From: Alyssa Rosenzweig Date: Mon, 23 Mar 2020 22:44:21 +0000 (-0400) Subject: panfrost: Split panfrost_device from panfrost_screen X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ca8c62592c71885df653ecb008f5c0bad71420d4;p=mesa.git panfrost: Split panfrost_device from panfrost_screen We would like to access properties of the device in a Gallium-independent way (for out-of-Gallium testing in the short-term, and would help a theoretical Vulkan implementation in the long run). Let's split up the struct. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c index 44e8c7af561..63f87dc26e1 100644 --- a/src/gallium/drivers/panfrost/pan_assemble.c +++ b/src/gallium/drivers/panfrost/pan_assemble.c @@ -44,7 +44,7 @@ panfrost_shader_compile(struct panfrost_context *ctx, struct panfrost_shader_state *state, uint64_t *outputs_written) { - struct panfrost_screen *screen = pan_screen(ctx->base.screen); + struct panfrost_device *dev = pan_device(ctx->base.screen); uint8_t *dst; nir_shader *s; @@ -64,7 +64,7 @@ panfrost_shader_compile(struct panfrost_context *ctx, .alpha_ref = state->alpha_state.ref_value }; - midgard_compile_shader_nir(s, &program, false, 0, screen->gpu_id, + midgard_compile_shader_nir(s, &program, false, 0, dev->gpu_id, pan_debug & PAN_DBG_PRECOMPILE); /* Prepare the compiled binary for upload */ @@ -76,7 +76,7 @@ panfrost_shader_compile(struct panfrost_context *ctx, * that's how I'd do it. */ if (size) { - state->bo = panfrost_bo_create(screen, size, PAN_BO_EXECUTE); + state->bo = panfrost_bo_create(dev, size, PAN_BO_EXECUTE); memcpy(state->bo->cpu, dst, size); state->first_tag = program.first_tag; } else { diff --git a/src/gallium/drivers/panfrost/pan_blend_shaders.c b/src/gallium/drivers/panfrost/pan_blend_shaders.c index 0a312f71e23..f6264f5c73b 100644 --- a/src/gallium/drivers/panfrost/pan_blend_shaders.c +++ b/src/gallium/drivers/panfrost/pan_blend_shaders.c @@ -138,7 +138,7 @@ panfrost_compile_blend_shader( enum pipe_format format, unsigned rt) { - struct panfrost_screen *screen = pan_screen(ctx->base.screen); + struct panfrost_device *dev = pan_device(ctx->base.screen); struct panfrost_blend_shader res; res.ctx = ctx; @@ -177,12 +177,12 @@ panfrost_compile_blend_shader( NIR_PASS_V(shader, nir_lower_blend, options); - NIR_PASS_V(shader, nir_lower_framebuffer, format, screen->gpu_id); + NIR_PASS_V(shader, nir_lower_framebuffer, format, dev->gpu_id); /* Compile the built shader */ panfrost_program program; - midgard_compile_shader_nir(shader, &program, true, rt, screen->gpu_id, false); + midgard_compile_shader_nir(shader, &program, true, rt, dev->gpu_id, false); /* Allow us to patch later */ res.patch_index = program.blend_patch_offset; diff --git a/src/gallium/drivers/panfrost/pan_bo.c b/src/gallium/drivers/panfrost/pan_bo.c index dfe04ed2ccc..d7bcae5b024 100644 --- a/src/gallium/drivers/panfrost/pan_bo.c +++ b/src/gallium/drivers/panfrost/pan_bo.c @@ -31,7 +31,6 @@ #include "drm-uapi/panfrost_drm.h" #include "pan_bo.h" -#include "pan_screen.h" #include "pan_util.h" #include "pandecode/decode.h" @@ -56,34 +55,34 @@ */ static struct panfrost_bo * -panfrost_bo_alloc(struct panfrost_screen *screen, size_t size, +panfrost_bo_alloc(struct panfrost_device *dev, size_t size, uint32_t flags) { struct drm_panfrost_create_bo create_bo = { .size = size }; struct panfrost_bo *bo; int ret; - if (screen->kernel_version->version_major > 1 || - screen->kernel_version->version_minor >= 1) { + if (dev->kernel_version->version_major > 1 || + dev->kernel_version->version_minor >= 1) { if (flags & PAN_BO_GROWABLE) create_bo.flags |= PANFROST_BO_HEAP; if (!(flags & PAN_BO_EXECUTE)) create_bo.flags |= PANFROST_BO_NOEXEC; } - ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_CREATE_BO, &create_bo); + ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_CREATE_BO, &create_bo); if (ret) { DBG("DRM_IOCTL_PANFROST_CREATE_BO failed: %m\n"); return NULL; } - bo = rzalloc(screen, struct panfrost_bo); + bo = rzalloc(dev->memctx, struct panfrost_bo); assert(bo); bo->size = create_bo.size; bo->gpu = create_bo.offset; bo->gem_handle = create_bo.handle; bo->flags = flags; - bo->screen = screen; + bo->dev = dev; return bo; } @@ -93,7 +92,7 @@ panfrost_bo_free(struct panfrost_bo *bo) struct drm_gem_close gem_close = { .handle = bo->gem_handle }; int ret; - ret = drmIoctl(bo->screen->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); if (ret) { fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed: %m\n"); assert(0); @@ -143,7 +142,7 @@ panfrost_bo_wait(struct panfrost_bo *bo, int64_t timeout_ns, /* The ioctl returns >= 0 value when the BO we are waiting for is ready * -1 otherwise. */ - ret = drmIoctl(bo->screen->fd, DRM_IOCTL_PANFROST_WAIT_BO, &req); + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PANFROST_WAIT_BO, &req); if (ret != -1) { /* Set gpu_access to 0 so that the next call to bo_wait() * doesn't have to call the WAIT_BO ioctl. @@ -184,9 +183,9 @@ pan_bucket_index(unsigned size) } static struct list_head * -pan_bucket(struct panfrost_screen *screen, unsigned size) +pan_bucket(struct panfrost_device *dev, unsigned size) { - return &screen->bo_cache.buckets[pan_bucket_index(size)]; + return &dev->bo_cache.buckets[pan_bucket_index(size)]; } /* Tries to fetch a BO of sufficient size with the appropriate flags from the @@ -195,11 +194,11 @@ pan_bucket(struct panfrost_screen *screen, unsigned size) * BO. */ static struct panfrost_bo * -panfrost_bo_cache_fetch(struct panfrost_screen *screen, +panfrost_bo_cache_fetch(struct panfrost_device *dev, size_t size, uint32_t flags, bool dontwait) { - pthread_mutex_lock(&screen->bo_cache.lock); - struct list_head *bucket = pan_bucket(screen, size); + pthread_mutex_lock(&dev->bo_cache.lock); + struct list_head *bucket = pan_bucket(dev, size); struct panfrost_bo *bo = NULL; /* Iterate the bucket looking for something suitable */ @@ -222,7 +221,7 @@ panfrost_bo_cache_fetch(struct panfrost_screen *screen, list_del(&entry->bucket_link); list_del(&entry->lru_link); - ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_MADVISE, &madv); + ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_MADVISE, &madv); if (!ret && !madv.retained) { panfrost_bo_free(entry); continue; @@ -231,19 +230,19 @@ panfrost_bo_cache_fetch(struct panfrost_screen *screen, bo = entry; break; } - pthread_mutex_unlock(&screen->bo_cache.lock); + pthread_mutex_unlock(&dev->bo_cache.lock); return bo; } static void -panfrost_bo_cache_evict_stale_bos(struct panfrost_screen *screen) +panfrost_bo_cache_evict_stale_bos(struct panfrost_device *dev) { struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); list_for_each_entry_safe(struct panfrost_bo, entry, - &screen->bo_cache.lru, lru_link) { + &dev->bo_cache.lru, lru_link) { /* We want all entries that have been used more than 1 sec * ago to be dropped, others can be kept. * Note the <= 2 check and not <= 1. It's here to account for @@ -267,13 +266,13 @@ panfrost_bo_cache_evict_stale_bos(struct panfrost_screen *screen) static bool panfrost_bo_cache_put(struct panfrost_bo *bo) { - struct panfrost_screen *screen = bo->screen; + struct panfrost_device *dev = bo->dev; if (bo->flags & PAN_BO_DONT_REUSE) return false; - pthread_mutex_lock(&screen->bo_cache.lock); - struct list_head *bucket = pan_bucket(screen, bo->size); + pthread_mutex_lock(&dev->bo_cache.lock); + struct list_head *bucket = pan_bucket(dev, bo->size); struct drm_panfrost_madvise madv; struct timespec time; @@ -281,21 +280,21 @@ panfrost_bo_cache_put(struct panfrost_bo *bo) madv.madv = PANFROST_MADV_DONTNEED; madv.retained = 0; - drmIoctl(screen->fd, DRM_IOCTL_PANFROST_MADVISE, &madv); + drmIoctl(dev->fd, DRM_IOCTL_PANFROST_MADVISE, &madv); /* Add us to the bucket */ list_addtail(&bo->bucket_link, bucket); /* Add us to the LRU list and update the last_used field. */ - list_addtail(&bo->lru_link, &screen->bo_cache.lru); + list_addtail(&bo->lru_link, &dev->bo_cache.lru); clock_gettime(CLOCK_MONOTONIC, &time); bo->last_used = time.tv_sec; /* Let's do some cleanup in the BO cache while we hold the * lock. */ - panfrost_bo_cache_evict_stale_bos(screen); - pthread_mutex_unlock(&screen->bo_cache.lock); + panfrost_bo_cache_evict_stale_bos(dev); + pthread_mutex_unlock(&dev->bo_cache.lock); return true; } @@ -308,11 +307,11 @@ panfrost_bo_cache_put(struct panfrost_bo *bo) void panfrost_bo_cache_evict_all( - struct panfrost_screen *screen) + struct panfrost_device *dev) { - pthread_mutex_lock(&screen->bo_cache.lock); - for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache.buckets); ++i) { - struct list_head *bucket = &screen->bo_cache.buckets[i]; + pthread_mutex_lock(&dev->bo_cache.lock); + for (unsigned i = 0; i < ARRAY_SIZE(dev->bo_cache.buckets); ++i) { + struct list_head *bucket = &dev->bo_cache.buckets[i]; list_for_each_entry_safe(struct panfrost_bo, entry, bucket, bucket_link) { @@ -321,7 +320,7 @@ panfrost_bo_cache_evict_all( panfrost_bo_free(entry); } } - pthread_mutex_unlock(&screen->bo_cache.lock); + pthread_mutex_unlock(&dev->bo_cache.lock); } void @@ -333,14 +332,14 @@ panfrost_bo_mmap(struct panfrost_bo *bo) if (bo->cpu) return; - ret = drmIoctl(bo->screen->fd, DRM_IOCTL_PANFROST_MMAP_BO, &mmap_bo); + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PANFROST_MMAP_BO, &mmap_bo); if (ret) { fprintf(stderr, "DRM_IOCTL_PANFROST_MMAP_BO failed: %m\n"); assert(0); } bo->cpu = os_mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->screen->fd, mmap_bo.offset); + bo->dev->fd, mmap_bo.offset); if (bo->cpu == MAP_FAILED) { fprintf(stderr, "mmap failed: %p %m\n", bo->cpu); assert(0); @@ -366,7 +365,7 @@ panfrost_bo_munmap(struct panfrost_bo *bo) } struct panfrost_bo * -panfrost_bo_create(struct panfrost_screen *screen, size_t size, +panfrost_bo_create(struct panfrost_device *dev, size_t size, uint32_t flags) { struct panfrost_bo *bo; @@ -388,11 +387,11 @@ panfrost_bo_create(struct panfrost_screen *screen, size_t size, * and if that fails too, we try one more time to allocate from the * cache, but this time we accept to wait. */ - bo = panfrost_bo_cache_fetch(screen, size, flags, true); + bo = panfrost_bo_cache_fetch(dev, size, flags, true); if (!bo) - bo = panfrost_bo_alloc(screen, size, flags); + bo = panfrost_bo_alloc(dev, size, flags); if (!bo) - bo = panfrost_bo_cache_fetch(screen, size, flags, false); + bo = panfrost_bo_cache_fetch(dev, size, flags, false); if (!bo) fprintf(stderr, "BO creation failed\n"); @@ -412,9 +411,9 @@ panfrost_bo_create(struct panfrost_screen *screen, size_t size, pipe_reference_init(&bo->reference, 1); - pthread_mutex_lock(&screen->active_bos_lock); - _mesa_set_add(bo->screen->active_bos, bo); - pthread_mutex_unlock(&screen->active_bos_lock); + pthread_mutex_lock(&dev->active_bos_lock); + _mesa_set_add(bo->dev->active_bos, bo); + pthread_mutex_unlock(&dev->active_bos_lock); return bo; } @@ -435,14 +434,14 @@ panfrost_bo_unreference(struct panfrost_bo *bo) if (!pipe_reference(&bo->reference, NULL)) return; - struct panfrost_screen *screen = bo->screen; + struct panfrost_device *dev = bo->dev; - pthread_mutex_lock(&screen->active_bos_lock); + pthread_mutex_lock(&dev->active_bos_lock); /* Someone might have imported this BO while we were waiting for the * lock, let's make sure it's still not referenced before freeing it. */ if (!pipe_is_referenced(&bo->reference)) { - _mesa_set_remove_key(bo->screen->active_bos, bo); + _mesa_set_remove_key(bo->dev->active_bos, bo); /* When the reference count goes to zero, we need to cleanup */ panfrost_bo_munmap(bo); @@ -453,32 +452,32 @@ panfrost_bo_unreference(struct panfrost_bo *bo) if (!panfrost_bo_cache_put(bo)) panfrost_bo_free(bo); } - pthread_mutex_unlock(&screen->active_bos_lock); + pthread_mutex_unlock(&dev->active_bos_lock); } struct panfrost_bo * -panfrost_bo_import(struct panfrost_screen *screen, int fd) +panfrost_bo_import(struct panfrost_device *dev, int fd) { - struct panfrost_bo *bo, *newbo = rzalloc(screen, struct panfrost_bo); + struct panfrost_bo *bo, *newbo = rzalloc(dev->memctx, struct panfrost_bo); struct drm_panfrost_get_bo_offset get_bo_offset = {0,}; struct set_entry *entry; ASSERTED int ret; unsigned gem_handle; - newbo->screen = screen; + newbo->dev = dev; - ret = drmPrimeFDToHandle(screen->fd, fd, &gem_handle); + ret = drmPrimeFDToHandle(dev->fd, fd, &gem_handle); assert(!ret); newbo->gem_handle = gem_handle; - pthread_mutex_lock(&screen->active_bos_lock); - entry = _mesa_set_search_or_add(screen->active_bos, newbo); + pthread_mutex_lock(&dev->active_bos_lock); + entry = _mesa_set_search_or_add(dev->active_bos, newbo); assert(entry); bo = (struct panfrost_bo *)entry->key; if (newbo == bo) { get_bo_offset.handle = gem_handle; - ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_GET_BO_OFFSET, &get_bo_offset); + ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_GET_BO_OFFSET, &get_bo_offset); assert(!ret); newbo->gpu = (mali_ptr) get_bo_offset.offset; @@ -506,7 +505,7 @@ panfrost_bo_import(struct panfrost_screen *screen, int fd) panfrost_bo_reference(bo); assert(bo->cpu); } - pthread_mutex_unlock(&screen->active_bos_lock); + pthread_mutex_unlock(&dev->active_bos_lock); return bo; } @@ -519,7 +518,7 @@ panfrost_bo_export(struct panfrost_bo *bo) .flags = DRM_CLOEXEC, }; - int ret = drmIoctl(bo->screen->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); + int ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); if (ret == -1) return -1; diff --git a/src/gallium/drivers/panfrost/pan_bo.h b/src/gallium/drivers/panfrost/pan_bo.h index 414c356b95c..ba7bc23341d 100644 --- a/src/gallium/drivers/panfrost/pan_bo.h +++ b/src/gallium/drivers/panfrost/pan_bo.h @@ -29,8 +29,7 @@ #include #include "pipe/p_state.h" #include "util/list.h" - -struct panfrost_screen; +#include "pan_device.h" /* Flags for allocated memory */ @@ -94,7 +93,7 @@ struct panfrost_bo { struct pipe_reference reference; - struct panfrost_screen *screen; + struct panfrost_device *dev; /* Mapping for the entire object (all levels) */ uint8_t *cpu; @@ -141,15 +140,15 @@ panfrost_bo_reference(struct panfrost_bo *bo); void panfrost_bo_unreference(struct panfrost_bo *bo); struct panfrost_bo * -panfrost_bo_create(struct panfrost_screen *screen, size_t size, +panfrost_bo_create(struct panfrost_device *dev, size_t size, uint32_t flags); void panfrost_bo_mmap(struct panfrost_bo *bo); struct panfrost_bo * -panfrost_bo_import(struct panfrost_screen *screen, int fd); +panfrost_bo_import(struct panfrost_device *dev, int fd); int panfrost_bo_export(struct panfrost_bo *bo); void -panfrost_bo_cache_evict_all(struct panfrost_screen *screen); +panfrost_bo_cache_evict_all(struct panfrost_device *dev); #endif /* __PAN_BO_H__ */ diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 7d61b2ff7cd..8c2bcd25e2b 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -41,20 +41,20 @@ void panfrost_vt_attach_framebuffer(struct panfrost_context *ctx, struct midgard_payload_vertex_tiler *vt) { - struct panfrost_screen *screen = pan_screen(ctx->base.screen); + struct panfrost_device *dev = pan_device(ctx->base.screen); struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx); /* If we haven't, reserve space for the framebuffer */ if (!batch->framebuffer.gpu) { - unsigned size = (screen->quirks & MIDGARD_SFBD) ? + unsigned size = (dev->quirks & MIDGARD_SFBD) ? sizeof(struct mali_single_framebuffer) : sizeof(struct mali_framebuffer); batch->framebuffer = panfrost_allocate_transient(batch, size); /* Tag the pointer */ - if (!(screen->quirks & MIDGARD_SFBD)) + if (!(dev->quirks & MIDGARD_SFBD)) batch->framebuffer.gpu |= MALI_MFBD; } @@ -530,10 +530,10 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx, struct mali_shader_meta *fragmeta, struct midgard_blend_rt *rts) { - const struct panfrost_screen *screen = pan_screen(ctx->base.screen); + const struct panfrost_device *dev = pan_device(ctx->base.screen); SET_BIT(fragmeta->unknown2_4, MALI_NO_DITHER, - (screen->quirks & MIDGARD_SFBD) && ctx->blend && + (dev->quirks & MIDGARD_SFBD) && ctx->blend && !ctx->blend->base.dither); /* Get blending setup */ @@ -570,7 +570,7 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx, break; } - if (screen->quirks & MIDGARD_SFBD) { + if (dev->quirks & MIDGARD_SFBD) { /* When only a single render target platform is used, the blend * information is inside the shader meta itself. We additionally * need to signal CAN_DISCARD for nontrivial blend modes (so @@ -617,7 +617,7 @@ panfrost_frag_shader_meta_init(struct panfrost_context *ctx, struct mali_shader_meta *fragmeta, struct midgard_blend_rt *rts) { - const struct panfrost_screen *screen = pan_screen(ctx->base.screen); + const struct panfrost_device *dev = pan_device(ctx->base.screen); struct panfrost_shader_state *fs; fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT); @@ -632,7 +632,7 @@ panfrost_frag_shader_meta_init(struct panfrost_context *ctx, * these earlier chips (perhaps this is a chicken bit of some kind). * More investigation is needed. */ - SET_BIT(fragmeta->unknown2_4, 0x10, screen->quirks & MIDGARD_SFBD); + SET_BIT(fragmeta->unknown2_4, 0x10, dev->quirks & MIDGARD_SFBD); /* Depending on whether it's legal to in the given shader, we try to * enable early-z testing (or forward-pixel kill?) */ @@ -689,7 +689,7 @@ panfrost_emit_shader_meta(struct panfrost_batch *batch, mali_ptr shader_ptr; if (st == PIPE_SHADER_FRAGMENT) { - struct panfrost_screen *screen = pan_screen(ctx->base.screen); + struct panfrost_device *dev = pan_device(ctx->base.screen); unsigned rt_count = MAX2(ctx->pipe_framebuffer.nr_cbufs, 1); size_t desc_size = sizeof(meta); struct midgard_blend_rt rts[4]; @@ -699,7 +699,7 @@ panfrost_emit_shader_meta(struct panfrost_batch *batch, panfrost_frag_shader_meta_init(ctx, &meta, rts); - if (!(screen->quirks & MIDGARD_SFBD)) + if (!(dev->quirks & MIDGARD_SFBD)) desc_size += sizeof(*rts) * rt_count; xfer = panfrost_allocate_transient(batch, desc_size); diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 0daa26fb34b..a0111a6ca06 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -58,8 +58,8 @@ struct midgard_tiler_descriptor panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count) { - struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen); - bool hierarchy = !(screen->quirks & MIDGARD_NO_HIER_TILING); + struct panfrost_device *device = pan_device(batch->ctx->base.screen); + bool hierarchy = !(device->quirks & MIDGARD_NO_HIER_TILING); struct midgard_tiler_descriptor t = {0}; unsigned height = batch->key.height; unsigned width = batch->key.width; @@ -881,7 +881,7 @@ panfrost_create_sampler_view( struct pipe_resource *texture, const struct pipe_sampler_view *template) { - struct panfrost_screen *screen = pan_screen(pctx->screen); + struct panfrost_device *device = pan_device(pctx->screen); struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view); pipe_reference(NULL, &texture->reference); @@ -922,7 +922,7 @@ panfrost_create_sampler_view( template->u.tex.last_layer, type, prsrc->layout); - so->bo = panfrost_bo_create(screen, size, 0); + so->bo = panfrost_bo_create(device, size, 0); panfrost_new_texture( so->bo->cpu, @@ -999,7 +999,7 @@ panfrost_set_shader_buffers( static void panfrost_hint_afbc( - struct panfrost_screen *screen, + struct panfrost_device *device, const struct pipe_framebuffer_state *fb) { /* AFBC implemenation incomplete; hide it */ @@ -1010,14 +1010,14 @@ panfrost_hint_afbc( for (unsigned i = 0; i < fb->nr_cbufs; ++i) { struct pipe_surface *surf = fb->cbufs[i]; struct panfrost_resource *rsrc = pan_resource(surf->texture); - panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1); + panfrost_resource_hint_layout(device, rsrc, MALI_TEXTURE_AFBC, 1); } /* Also hint it to the depth buffer */ if (fb->zsbuf) { struct panfrost_resource *rsrc = pan_resource(fb->zsbuf->texture); - panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1); + panfrost_resource_hint_layout(device, rsrc, MALI_TEXTURE_AFBC, 1); } } @@ -1027,7 +1027,7 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx, { struct panfrost_context *ctx = pan_context(pctx); - panfrost_hint_afbc(pan_screen(pctx->screen), fb); + panfrost_hint_afbc(pan_device(pctx->screen), fb); util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb); ctx->batch = NULL; panfrost_invalidate_frame(ctx); @@ -1181,7 +1181,7 @@ panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q) /* Allocate a bo for the query results to be stored */ if (!query->bo) { query->bo = panfrost_bo_create( - pan_screen(ctx->base.screen), + pan_device(ctx->base.screen), sizeof(unsigned), 0); } diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c index 80b25a3893c..94a64d7a4bd 100644 --- a/src/gallium/drivers/panfrost/pan_fragment.c +++ b/src/gallium/drivers/panfrost/pan_fragment.c @@ -50,9 +50,9 @@ panfrost_initialize_surface( mali_ptr panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws) { - struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen); + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); - mali_ptr framebuffer = (screen->quirks & MIDGARD_SFBD) ? + mali_ptr framebuffer = (dev->quirks & MIDGARD_SFBD) ? panfrost_sfbd_fragment(batch, has_draws) : panfrost_mfbd_fragment(batch, has_draws); diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 359cfef3615..eca2944bff0 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -71,7 +71,7 @@ panfrost_create_batch_fence(struct panfrost_batch *batch) pipe_reference_init(&fence->reference, 1); fence->ctx = batch->ctx; fence->batch = batch; - ret = drmSyncobjCreate(pan_screen(batch->ctx->base.screen)->fd, 0, + ret = drmSyncobjCreate(pan_device(batch->ctx->base.screen)->fd, 0, &fence->syncobj); assert(!ret); @@ -81,7 +81,7 @@ panfrost_create_batch_fence(struct panfrost_batch *batch) static void panfrost_free_batch_fence(struct panfrost_batch_fence *fence) { - drmSyncobjDestroy(pan_screen(fence->ctx->base.screen)->fd, + drmSyncobjDestroy(pan_device(fence->ctx->base.screen)->fd, fence->syncobj); ralloc_free(fence); } @@ -322,7 +322,7 @@ panfrost_batch_fence_is_signaled(struct panfrost_batch_fence *fence) if (fence->batch) return false; - int ret = drmSyncobjWait(pan_screen(fence->ctx->base.screen)->fd, + int ret = drmSyncobjWait(pan_device(fence->ctx->base.screen)->fd, &fence->syncobj, 1, 0, 0, NULL); /* Cache whether the fence was signaled */ @@ -603,7 +603,7 @@ panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size, { struct panfrost_bo *bo; - bo = panfrost_bo_create(pan_screen(batch->ctx->base.screen), size, + bo = panfrost_bo_create(pan_device(batch->ctx->base.screen), size, create_flags); panfrost_batch_add_bo(batch, bo, access_flags); @@ -702,14 +702,14 @@ panfrost_batch_get_tiler_heap(struct panfrost_batch *batch) struct panfrost_bo * panfrost_batch_get_tiler_dummy(struct panfrost_batch *batch) { - struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen); + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); uint32_t create_flags = 0; if (batch->tiler_dummy) return batch->tiler_dummy; - if (!(screen->quirks & MIDGARD_NO_HIER_TILING)) + if (!(dev->quirks & MIDGARD_NO_HIER_TILING)) create_flags = PAN_BO_INVISIBLE; batch->tiler_dummy = panfrost_batch_create_bo(batch, 4096, @@ -844,7 +844,7 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch, { struct panfrost_context *ctx = batch->ctx; struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_screen *screen = pan_screen(gallium->screen); + struct panfrost_device *dev = pan_device(gallium->screen); struct drm_panfrost_submit submit = {0,}; uint32_t *bo_handles, *in_syncs = NULL; bool is_fragment_shader; @@ -901,7 +901,7 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch, } submit.bo_handles = (u64) (uintptr_t) bo_handles; - ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit); + ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit); free(bo_handles); free(in_syncs); @@ -913,12 +913,12 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch, /* Trace the job if we're doing that */ if (pan_debug & (PAN_DBG_TRACE | PAN_DBG_SYNC)) { /* Wait so we can get errors reported back */ - drmSyncobjWait(screen->fd, &batch->out_sync->syncobj, 1, + drmSyncobjWait(dev->fd, &batch->out_sync->syncobj, 1, INT64_MAX, 0, NULL); /* Trace gets priority over sync */ bool minimal = !(pan_debug & PAN_DBG_TRACE); - pandecode_jc(submit.jc, FALSE, screen->gpu_id, minimal); + pandecode_jc(submit.jc, FALSE, dev->gpu_id, minimal); } return 0; @@ -975,9 +975,9 @@ panfrost_batch_submit(struct panfrost_batch *batch) if (batch->framebuffer.gpu && batch->first_job) { struct panfrost_context *ctx = batch->ctx; struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_screen *screen = pan_screen(gallium->screen); + struct panfrost_device *dev = pan_device(gallium->screen); - if (screen->quirks & MIDGARD_SFBD) + if (dev->quirks & MIDGARD_SFBD) panfrost_attach_sfbd(batch, ~0); else panfrost_attach_mfbd(batch, ~0); @@ -1048,7 +1048,7 @@ panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait) if (!wait) return; - drmSyncobjWait(pan_screen(ctx->base.screen)->fd, + drmSyncobjWait(pan_device(ctx->base.screen)->fd, util_dynarray_begin(&syncobjs), util_dynarray_num_elements(&syncobjs, uint32_t), INT64_MAX, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, NULL); @@ -1313,7 +1313,7 @@ panfrost_batch_intersection_scissor(struct panfrost_batch *batch, batch->maxy = MIN2(batch->maxy, maxy); } -/* Are we currently rendering to the screen (rather than an FBO)? */ +/* Are we currently rendering to the dev (rather than an FBO)? */ bool panfrost_batch_is_scanout(struct panfrost_batch *batch) diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index f150278bd7b..04646e5eda8 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -359,7 +359,7 @@ panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count) { struct panfrost_context *ctx = batch->ctx; struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_screen *screen = pan_screen(gallium->screen); + struct panfrost_device *dev = pan_device(gallium->screen); unsigned width = batch->key.width; unsigned height = batch->key.height; @@ -381,7 +381,7 @@ panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count) .shared_memory = { .stack_shift = shift, - .scratchpad = panfrost_batch_get_scratchpad(batch, shift, screen->thread_tls_alloc, screen->core_count)->gpu, + .scratchpad = panfrost_batch_get_scratchpad(batch, shift, dev->thread_tls_alloc, dev->core_count)->gpu, .shared_workgroup_count = ~0, } }; diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index ac3e288a0b6..3929ff176cd 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -66,7 +66,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle, unsigned usage) { - struct panfrost_screen *screen = pan_screen(pscreen); + struct panfrost_device *dev = pan_device(pscreen); struct panfrost_resource *rsc; struct pipe_resource *prsc; @@ -83,7 +83,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, pipe_reference_init(&prsc->reference, 1); prsc->screen = pscreen; - rsc->bo = panfrost_bo_import(screen, whandle->handle); + rsc->bo = panfrost_bo_import(dev, whandle->handle); rsc->internal_format = templat->format; rsc->layout = MALI_TEXTURE_LINEAR; rsc->slices[0].stride = whandle->stride; @@ -91,9 +91,9 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, rsc->slices[0].initialized = true; panfrost_resource_reset_damage(rsc); - if (screen->ro) { + if (dev->ro) { rsc->scanout = - renderonly_create_gpu_import_for_resource(prsc, screen->ro, NULL); + renderonly_create_gpu_import_for_resource(prsc, dev->ro, NULL); /* failure is expected in some cases.. */ } @@ -107,7 +107,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, struct winsys_handle *handle, unsigned usage) { - struct panfrost_screen *screen = pan_screen(pscreen); + struct panfrost_device *dev = pan_device(pscreen); struct panfrost_resource *rsrc = (struct panfrost_resource *) pt; struct renderonly_scanout *scanout = rsrc->scanout; @@ -130,7 +130,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, .flags = DRM_CLOEXEC, }; - int ret = drmIoctl(screen->ro->kms_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); + int ret = drmIoctl(dev->ro->kms_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); if (ret == -1) return false; @@ -209,14 +209,14 @@ static struct pipe_resource * panfrost_create_scanout_res(struct pipe_screen *screen, const struct pipe_resource *template) { - struct panfrost_screen *pscreen = pan_screen(screen); + struct panfrost_device *dev = pan_device(screen); struct pipe_resource scanout_templat = *template; struct renderonly_scanout *scanout; struct winsys_handle handle; struct pipe_resource *res; scanout = renderonly_scanout_for_resource(&scanout_templat, - pscreen->ro, &handle); + dev->ro, &handle); if (!scanout) return NULL; @@ -354,7 +354,7 @@ panfrost_setup_slices(struct panfrost_resource *pres, size_t *bo_size) } static void -panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_resource *pres) +panfrost_resource_create_bo(struct panfrost_device *dev, struct panfrost_resource *pres) { struct pipe_resource *res = &pres->base; @@ -387,7 +387,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso bool is_2d = (res->target == PIPE_TEXTURE_2D); bool is_sane_bpp = bpp == 8 || bpp == 16 || bpp == 32 || bpp == 64 || bpp == 128; bool should_tile = (res->usage != PIPE_USAGE_STREAM); - bool must_tile = (res->bind & PIPE_BIND_DEPTH_STENCIL) && (screen->quirks & MIDGARD_SFBD); + bool must_tile = (res->bind & PIPE_BIND_DEPTH_STENCIL) && (dev->quirks & MIDGARD_SFBD); bool can_tile = is_2d && is_sane_bpp && ((res->bind & ~valid_binding) == 0); /* FBOs we would like to checksum, if at all possible */ @@ -406,7 +406,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso /* We create a BO immediately but don't bother mapping, since we don't * care to map e.g. FBOs which the CPU probably won't touch */ - pres->bo = panfrost_bo_create(screen, bo_size, PAN_BO_DELAY_MMAP); + pres->bo = panfrost_bo_create(dev, bo_size, PAN_BO_DELAY_MMAP); } void @@ -500,7 +500,7 @@ panfrost_resource_create(struct pipe_screen *screen, return panfrost_create_scanout_res(screen, template); struct panfrost_resource *so = rzalloc(screen, struct panfrost_resource); - struct panfrost_screen *pscreen = (struct panfrost_screen *) screen; + struct panfrost_device *dev = pan_device(screen); so->base = *template; so->base.screen = screen; @@ -510,7 +510,7 @@ panfrost_resource_create(struct pipe_screen *screen, util_range_init(&so->valid_buffer_range); - panfrost_resource_create_bo(pscreen, so); + panfrost_resource_create_bo(dev, so); panfrost_resource_reset_damage(so); if (template->bind & PIPE_BIND_INDEX_BUFFER) @@ -523,11 +523,11 @@ static void panfrost_resource_destroy(struct pipe_screen *screen, struct pipe_resource *pt) { - struct panfrost_screen *pscreen = pan_screen(screen); + struct panfrost_device *dev = pan_device(screen); struct panfrost_resource *rsrc = (struct panfrost_resource *) pt; if (rsrc->scanout) - renderonly_scanout_destroy(rsrc->scanout, pscreen->ro); + renderonly_scanout_destroy(rsrc->scanout, dev->ro); if (rsrc->bo) panfrost_bo_unreference(rsrc->bo); @@ -569,7 +569,7 @@ panfrost_transfer_map(struct pipe_context *pctx, */ if (panfrost_pending_batches_access_bo(ctx, bo) || !panfrost_bo_wait(bo, 0, PAN_BO_ACCESS_RW)) { - struct panfrost_screen *screen = pan_screen(pctx->screen); + struct panfrost_device *dev = pan_device(pctx->screen); /* We want the BO to be MMAPed. */ uint32_t flags = bo->flags & ~PAN_BO_DELAY_MMAP; struct panfrost_bo *newbo = NULL; @@ -580,7 +580,7 @@ panfrost_transfer_map(struct pipe_context *pctx, * doing to it. */ if (!(bo->flags & (PAN_BO_IMPORTED | PAN_BO_EXPORTED))) - newbo = panfrost_bo_create(screen, bo->size, + newbo = panfrost_bo_create(dev, bo->size, flags); if (newbo) { @@ -812,7 +812,7 @@ panfrost_get_texture_address( void panfrost_resource_hint_layout( - struct panfrost_screen *screen, + struct panfrost_device *dev, struct panfrost_resource *rsrc, enum mali_texture_layout layout, signed weight) @@ -862,7 +862,7 @@ panfrost_resource_hint_layout( /* If we grew in size, reallocate the BO */ if (new_size > rsrc->bo->size) { panfrost_bo_unreference(rsrc->bo); - rsrc->bo = panfrost_bo_create(screen, new_size, PAN_BO_DELAY_MMAP); + rsrc->bo = panfrost_bo_create(dev, new_size, PAN_BO_DELAY_MMAP); } /* TODO: If there are textures bound, regenerate their descriptors */ @@ -893,15 +893,15 @@ static const struct u_transfer_vtbl transfer_vtbl = { }; void -panfrost_resource_screen_init(struct panfrost_screen *pscreen) +panfrost_resource_screen_init(struct pipe_screen *pscreen) { //pscreen->base.resource_create_with_modifiers = // panfrost_resource_create_with_modifiers; - pscreen->base.resource_create = u_transfer_helper_resource_create; - pscreen->base.resource_destroy = u_transfer_helper_resource_destroy; - pscreen->base.resource_from_handle = panfrost_resource_from_handle; - pscreen->base.resource_get_handle = panfrost_resource_get_handle; - pscreen->base.transfer_helper = u_transfer_helper_create(&transfer_vtbl, + pscreen->resource_create = u_transfer_helper_resource_create; + pscreen->resource_destroy = u_transfer_helper_resource_destroy; + pscreen->resource_from_handle = panfrost_resource_from_handle; + pscreen->resource_get_handle = panfrost_resource_get_handle; + pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, true, false, true, true); } diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 9f8c2890b32..a3d78e940e5 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -88,13 +88,13 @@ panfrost_get_texture_address( struct panfrost_resource *rsrc, unsigned level, unsigned face); -void panfrost_resource_screen_init(struct panfrost_screen *screen); +void panfrost_resource_screen_init(struct pipe_screen *screen); void panfrost_resource_context_init(struct pipe_context *pctx); void panfrost_resource_hint_layout( - struct panfrost_screen *screen, + struct panfrost_device *dev, struct panfrost_resource *rsrc, enum mali_texture_layout layout, signed weight); diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index b6f8c646602..e2e8d4847a5 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -72,7 +72,7 @@ int pan_debug = 0; static const char * panfrost_get_name(struct pipe_screen *screen) { - return panfrost_model_name(pan_screen(screen)->gpu_id); + return panfrost_model_name(pan_device(screen)->gpu_id); } static const char * @@ -591,12 +591,12 @@ panfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_t static void panfrost_destroy_screen(struct pipe_screen *pscreen) { - struct panfrost_screen *screen = pan_screen(pscreen); - panfrost_bo_cache_evict_all(screen); - pthread_mutex_destroy(&screen->bo_cache.lock); - pthread_mutex_destroy(&screen->active_bos_lock); - drmFreeVersion(screen->kernel_version); - ralloc_free(screen); + struct panfrost_device *dev = pan_device(pscreen); + panfrost_bo_cache_evict_all(dev); + pthread_mutex_destroy(&dev->bo_cache.lock); + pthread_mutex_destroy(&dev->active_bos_lock); + drmFreeVersion(dev->kernel_version); + ralloc_free(pscreen); } static uint64_t @@ -629,7 +629,7 @@ panfrost_fence_finish(struct pipe_screen *pscreen, struct pipe_fence_handle *fence, uint64_t timeout) { - struct panfrost_screen *screen = pan_screen(pscreen); + struct panfrost_device *dev = pan_device(pscreen); struct panfrost_fence *f = (struct panfrost_fence *)fence; struct util_dynarray syncobjs; int ret; @@ -642,10 +642,10 @@ panfrost_fence_finish(struct pipe_screen *pscreen, util_dynarray_foreach(&f->syncfds, int, fd) { uint32_t syncobj; - ret = drmSyncobjCreate(screen->fd, 0, &syncobj); + ret = drmSyncobjCreate(dev->fd, 0, &syncobj); assert(!ret); - ret = drmSyncobjImportSyncFile(screen->fd, syncobj, *fd); + ret = drmSyncobjImportSyncFile(dev->fd, syncobj, *fd); assert(!ret); util_dynarray_append(&syncobjs, uint32_t, syncobj); } @@ -654,13 +654,13 @@ panfrost_fence_finish(struct pipe_screen *pscreen, if (abs_timeout == OS_TIMEOUT_INFINITE) abs_timeout = INT64_MAX; - ret = drmSyncobjWait(screen->fd, util_dynarray_begin(&syncobjs), + ret = drmSyncobjWait(dev->fd, util_dynarray_begin(&syncobjs), util_dynarray_num_elements(&syncobjs, uint32_t), abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, NULL); util_dynarray_foreach(&syncobjs, uint32_t, syncobj) - drmSyncobjDestroy(screen->fd, *syncobj); + drmSyncobjDestroy(dev->fd, *syncobj); return ret >= 0; } @@ -669,7 +669,7 @@ struct panfrost_fence * panfrost_fence_create(struct panfrost_context *ctx, struct util_dynarray *fences) { - struct panfrost_screen *screen = pan_screen(ctx->base.screen); + struct panfrost_device *device = pan_device(ctx->base.screen); struct panfrost_fence *f = calloc(1, sizeof(*f)); if (!f) return NULL; @@ -684,7 +684,7 @@ panfrost_fence_create(struct panfrost_context *ctx, if ((*fence)->signaled) continue; - drmSyncobjExportSyncFile(screen->fd, (*fence)->syncobj, &fd); + drmSyncobjExportSyncFile(device->fd, (*fence)->syncobj, &fd); if (fd == -1) fprintf(stderr, "export failed: %m\n"); @@ -744,26 +744,29 @@ panfrost_create_screen(int fd, struct renderonly *ro) if (!screen) return NULL; + struct panfrost_device *dev = pan_device(&screen->base); + if (ro) { - screen->ro = renderonly_dup(ro); - if (!screen->ro) { + dev->ro = renderonly_dup(ro); + if (!dev->ro) { DBG("Failed to dup renderonly object\n"); free(screen); return NULL; } } - screen->fd = fd; + dev->fd = fd; + dev->memctx = screen; - screen->gpu_id = panfrost_query_gpu_version(screen->fd); - screen->core_count = panfrost_query_core_count(screen->fd); - screen->thread_tls_alloc = panfrost_query_thread_tls_alloc(screen->fd); - screen->quirks = panfrost_get_quirks(screen->gpu_id); - screen->kernel_version = drmGetVersion(fd); + dev->gpu_id = panfrost_query_gpu_version(dev->fd); + dev->core_count = panfrost_query_core_count(dev->fd); + dev->thread_tls_alloc = panfrost_query_thread_tls_alloc(dev->fd); + dev->quirks = panfrost_get_quirks(dev->gpu_id); + dev->kernel_version = drmGetVersion(fd); /* Check if we're loading against a supported GPU model. */ - switch (screen->gpu_id) { + switch (dev->gpu_id) { case 0x720: /* T720 */ case 0x750: /* T760 */ case 0x820: /* T820 */ @@ -771,18 +774,18 @@ panfrost_create_screen(int fd, struct renderonly *ro) break; default: /* Fail to load against untested models */ - debug_printf("panfrost: Unsupported model %X", screen->gpu_id); + debug_printf("panfrost: Unsupported model %X", dev->gpu_id); return NULL; } - pthread_mutex_init(&screen->active_bos_lock, NULL); - screen->active_bos = _mesa_set_create(screen, panfrost_active_bos_hash, + pthread_mutex_init(&dev->active_bos_lock, NULL); + dev->active_bos = _mesa_set_create(screen, panfrost_active_bos_hash, panfrost_active_bos_cmp); - pthread_mutex_init(&screen->bo_cache.lock, NULL); - list_inithead(&screen->bo_cache.lru); - for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache.buckets); ++i) - list_inithead(&screen->bo_cache.buckets[i]); + pthread_mutex_init(&dev->bo_cache.lock, NULL); + list_inithead(&dev->bo_cache.lru); + for (unsigned i = 0; i < ARRAY_SIZE(dev->bo_cache.buckets); ++i) + list_inithead(&dev->bo_cache.buckets[i]); if (pan_debug & (PAN_DBG_TRACE | PAN_DBG_SYNC)) pandecode_initialize(!(pan_debug & PAN_DBG_TRACE)); @@ -804,7 +807,7 @@ panfrost_create_screen(int fd, struct renderonly *ro) screen->base.fence_finish = panfrost_fence_finish; screen->base.set_damage_region = panfrost_resource_set_damage_region; - panfrost_resource_screen_init(screen); + panfrost_resource_screen_init(&screen->base); return &screen->base; } diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h index 348b8e759c6..f67856949e2 100644 --- a/src/gallium/drivers/panfrost/pan_screen.h +++ b/src/gallium/drivers/panfrost/pan_screen.h @@ -38,75 +38,16 @@ #include "util/set.h" #include +#include "pan_device.h" #include "pan_allocate.h" struct panfrost_batch; struct panfrost_context; struct panfrost_resource; -struct panfrost_screen; - -/* Driver limits */ -#define PAN_MAX_CONST_BUFFERS 16 - -/* Transient slab size. This is a balance between fragmentation against cache - * locality and ease of bookkeeping */ - -#define TRANSIENT_SLAB_PAGES (32) /* 128kb */ -#define TRANSIENT_SLAB_SIZE (4096 * TRANSIENT_SLAB_PAGES) - -/* Maximum number of transient slabs so we don't need dynamic arrays. Most - * interesting Mali boards are 4GB RAM max, so if the entire RAM was filled - * with transient slabs, you could never exceed (4GB / TRANSIENT_SLAB_SIZE) - * allocations anyway. By capping, we can use a fixed-size bitset for tracking - * free slabs, eliminating quite a bit of complexity. We can pack the free - * state of 8 slabs into a single byte, so for 128kb transient slabs the bitset - * occupies a cheap 4kb of memory */ - -#define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES) - -/* How many power-of-two levels in the BO cache do we want? 2^12 - * minimum chosen as it is the page size that all allocations are - * rounded to */ - -#define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */ -#define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */ - -/* Fencepost problem, hence the off-by-one */ -#define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1) struct panfrost_screen { struct pipe_screen base; - int fd; - - /* Properties of the GPU in use */ - unsigned gpu_id; - unsigned core_count; - unsigned thread_tls_alloc; - unsigned quirks; - - drmVersionPtr kernel_version; - - struct renderonly *ro; - - pthread_mutex_t active_bos_lock; - struct set *active_bos; - - struct { - pthread_mutex_t lock; - - /* List containing all cached BOs sorted in LRU (Least - * Recently Used) order. This allows us to quickly evict BOs - * that are more than 1 second old. - */ - struct list_head lru; - - /* The BO cache is a set of buckets with power-of-two sizes - * ranging from 2^12 (4096, the page size) to - * 2^(12 + MAX_BO_CACHE_BUCKETS). - * Each bucket is a linked list of free panfrost_bo objects. */ - - struct list_head buckets[NR_BO_CACHE_BUCKETS]; - } bo_cache; + struct panfrost_device dev; }; static inline struct panfrost_screen * @@ -115,6 +56,12 @@ pan_screen(struct pipe_screen *p) return (struct panfrost_screen *)p; } +static inline struct panfrost_device * +pan_device(struct pipe_screen *p) +{ + return &(pan_screen(p)->dev); +} + struct panfrost_fence * panfrost_fence_create(struct panfrost_context *ctx, struct util_dynarray *fences); diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index fa62916a104..9cbcbcaba4e 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -199,7 +199,7 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count) { struct panfrost_context *ctx = batch->ctx; struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_screen *screen = pan_screen(gallium->screen); + struct panfrost_device *dev = pan_device(gallium->screen); unsigned width = batch->key.width; unsigned height = batch->key.height; @@ -214,7 +214,7 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count) .height = MALI_POSITIVE(height), .shared_memory = { .shared_workgroup_count = ~0, - .scratchpad = panfrost_batch_get_scratchpad(batch, shift, screen->thread_tls_alloc, screen->core_count)->gpu, + .scratchpad = panfrost_batch_get_scratchpad(batch, shift, dev->thread_tls_alloc, dev->core_count)->gpu, }, .format = { .unk3 = 0x3, diff --git a/src/panfrost/Makefile.sources b/src/panfrost/Makefile.sources index 25c221bf697..ad9a230567e 100644 --- a/src/panfrost/Makefile.sources +++ b/src/panfrost/Makefile.sources @@ -17,6 +17,7 @@ bifrost_FILES := \ encoder_FILES := \ encoder/pan_afbc.c \ encoder/pan_attributes.c \ + encoder/pan_device.h \ encoder/pan_encoder.h \ encoder/pan_format.c \ encoder/pan_invocation.c \ diff --git a/src/panfrost/encoder/pan_device.h b/src/panfrost/encoder/pan_device.h new file mode 100644 index 00000000000..07158b92007 --- /dev/null +++ b/src/panfrost/encoder/pan_device.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2018-2019 Alyssa Rosenzweig + * Copyright 2018-2019 Collabora, Ltd. + * All Rights Reserved. + * + * 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 VMWARE AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +#ifndef PAN_DEVICE_H +#define PAN_DEVICE_H + +#include +#include "renderonly/renderonly.h" +#include "util/u_dynarray.h" +#include "util/bitset.h" +#include "util/set.h" + +#include +#include "pan_allocate.h" + +/* Driver limits */ +#define PAN_MAX_CONST_BUFFERS 16 + +/* Transient slab size. This is a balance between fragmentation against cache + * locality and ease of bookkeeping */ + +#define TRANSIENT_SLAB_PAGES (32) /* 128kb */ +#define TRANSIENT_SLAB_SIZE (4096 * TRANSIENT_SLAB_PAGES) + +/* Maximum number of transient slabs so we don't need dynamic arrays. Most + * interesting Mali boards are 4GB RAM max, so if the entire RAM was filled + * with transient slabs, you could never exceed (4GB / TRANSIENT_SLAB_SIZE) + * allocations anyway. By capping, we can use a fixed-size bitset for tracking + * free slabs, eliminating quite a bit of complexity. We can pack the free + * state of 8 slabs into a single byte, so for 128kb transient slabs the bitset + * occupies a cheap 4kb of memory */ + +#define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES) + +/* How many power-of-two levels in the BO cache do we want? 2^12 + * minimum chosen as it is the page size that all allocations are + * rounded to */ + +#define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */ +#define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */ + +/* Fencepost problem, hence the off-by-one */ +#define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1) + +struct panfrost_device { + /* For ralloc */ + void *memctx; + + int fd; + + /* Properties of the GPU in use */ + unsigned gpu_id; + unsigned core_count; + unsigned thread_tls_alloc; + unsigned quirks; + + drmVersionPtr kernel_version; + + struct renderonly *ro; + + pthread_mutex_t active_bos_lock; + struct set *active_bos; + + struct { + pthread_mutex_t lock; + + /* List containing all cached BOs sorted in LRU (Least + * Recently Used) order. This allows us to quickly evict BOs + * that are more than 1 second old. + */ + struct list_head lru; + + /* The BO cache is a set of buckets with power-of-two sizes + * ranging from 2^12 (4096, the page size) to + * 2^(12 + MAX_BO_CACHE_BUCKETS). + * Each bucket is a linked list of free panfrost_bo objects. */ + + struct list_head buckets[NR_BO_CACHE_BUCKETS]; + } bo_cache; +}; + +#endif