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 <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4382>
This commit is contained in:
Alyssa Rosenzweig 2020-03-23 18:44:21 -04:00 committed by Marge Bot
parent 50e3b2e390
commit ca8c62592c
16 changed files with 278 additions and 222 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -29,8 +29,7 @@
#include <panfrost-misc.h>
#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__ */

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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,
}
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -38,75 +38,16 @@
#include "util/set.h"
#include <panfrost-misc.h>
#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);

View File

@ -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,

View File

@ -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 \

View File

@ -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 <xf86drm.h>
#include "renderonly/renderonly.h"
#include "util/u_dynarray.h"
#include "util/bitset.h"
#include "util/set.h"
#include <panfrost-misc.h>
#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