X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fpanfrost%2Fpan_resource.c;h=ac83f38b3279915bbde9d204a754e65343cab692;hb=debb85d1ecccaad237261906186a2612f951a9b8;hp=de20fc790998326d1fc82b6302419f02567cce1b;hpb=7da251fc721360fc28b984507959ebfa0c88c8b2;p=mesa.git diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index de20fc79099..ac83f38b327 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -1,35 +1,37 @@ -/************************************************************************** - * - * Copyright 2008 VMware, Inc. - * Copyright 2014 Broadcom - * Copyright 2018 Alyssa Rosenzweig - * All Rights Reserved. +/* + * Copyright (C) 2008 VMware, Inc. + * Copyright (C) 2014 Broadcom + * Copyright (C) 2018-2019 Alyssa Rosenzweig + * Copyright (C) 2019 Collabora * * 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: + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * - * 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. + * Authors (Collabora): + * Tomeu Vizoso + * Alyssa Rosenzweig * - **************************************************************************/ + */ #include #include -#include +#include "drm-uapi/drm_fourcc.h" #include "state_tracker/winsys_handle.h" #include "util/u_format.h" @@ -42,6 +44,7 @@ #include "pan_screen.h" #include "pan_resource.h" #include "pan_swizzle.h" +#include "pan_util.h" static struct pipe_resource * panfrost_resource_from_handle(struct pipe_screen *pscreen, @@ -67,6 +70,13 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, prsc->screen = pscreen; rsc->bo = screen->driver->import_bo(screen, whandle); + rsc->bo->slices[0].stride = whandle->stride; + + if (screen->ro) { + rsc->scanout = + renderonly_create_gpu_import_for_resource(prsc, screen->ro, NULL); + /* failure is expected in some cases.. */ + } return prsc; } @@ -81,23 +91,19 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, struct panfrost_screen *screen = pan_screen(pscreen); struct panfrost_resource *rsrc = (struct panfrost_resource *) pt; struct renderonly_scanout *scanout = rsrc->scanout; - int bytes_per_pixel = util_format_get_blocksize(rsrc->base.format); - int stride = bytes_per_pixel * rsrc->base.width0; /* TODO: Alignment? */ - handle->stride = stride; handle->modifier = DRM_FORMAT_MOD_INVALID; - if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { - printf("Missed shared handle\n"); - return FALSE; - } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) { - if (renderonly_get_handle(scanout, handle)) { - return TRUE; - } else { - printf("Missed nonrenderonly KMS handle for resource %p with scanout %p\n", pt, scanout); - return FALSE; - } - } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { + if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { + return FALSE; + } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) { + if (renderonly_get_handle(scanout, handle)) + return TRUE; + + handle->handle = rsrc->bo->gem_handle; + handle->stride = rsrc->bo->slices[0].stride; + return TRUE; + } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { if (scanout) { struct drm_prime_handle args = { .handle = scanout->handle, @@ -108,32 +114,21 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, if (ret == -1) return FALSE; + handle->stride = scanout->stride; handle->handle = args.fd; return TRUE; - } else { - printf("Missed nonscanout FD handle\n"); - assert(0); - return FALSE; - } - } + } else + return screen->driver->export_bo(screen, rsrc->bo->gem_handle, rsrc->bo->slices[0].stride, handle); + } - return FALSE; + return FALSE; } static void panfrost_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc) { - //fprintf(stderr, "TODO %s\n", __func__); -} - -static void -panfrost_blit(struct pipe_context *pipe, - const struct pipe_blit_info *info) -{ - /* STUB */ - printf("Skipping blit XXX\n"); - return; + //DBG("TODO %s\n", __func__); } static struct pipe_surface * @@ -181,9 +176,138 @@ panfrost_surface_destroy(struct pipe_context *pipe, free(surf); } -/* TODO: Proper resource tracking depends on, well, proper resources. This - * section will be woefully incomplete until we can sort out a proper DRM - * driver. */ +static void +panfrost_setup_slices(const struct pipe_resource *tmpl, struct panfrost_bo *bo) +{ + unsigned width = tmpl->width0; + unsigned height = tmpl->height0; + unsigned depth = tmpl->depth0; + unsigned bytes_per_pixel = util_format_get_blocksize(tmpl->format); + + assert(depth > 0); + + /* Tiled operates blockwise; linear is packed. Also, anything + * we render to has to be tile-aligned. Maybe not strictly + * necessary, but we're not *that* pressed for memory and it + * makes code a lot simpler */ + + bool renderable = tmpl->bind & + (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL); + bool tiled = bo->layout == PAN_TILED; + bool should_align = renderable || tiled; + + /* We don't know how to specify a 2D stride for 3D textures */ + + bool should_align_stride = + tmpl->target != PIPE_TEXTURE_3D; + + should_align &= should_align_stride; + + unsigned offset = 0; + unsigned size_2d = 0; + + for (unsigned l = 0; l <= tmpl->last_level; ++l) { + struct panfrost_slice *slice = &bo->slices[l]; + + unsigned effective_width = width; + unsigned effective_height = height; + unsigned effective_depth = depth; + + if (should_align) { + effective_width = ALIGN(effective_width, 16); + effective_height = ALIGN(effective_height, 16); + + /* We don't need to align depth */ + } + + slice->offset = offset; + + /* Compute the would-be stride */ + unsigned stride = bytes_per_pixel * effective_width; + + /* ..but cache-line align it for performance */ + if (should_align_stride) + stride = ALIGN(stride, 64); + + slice->stride = stride; + + unsigned slice_one_size = slice->stride * effective_height; + unsigned slice_full_size = slice_one_size * effective_depth; + + /* Report 2D size for 3D texturing */ + + if (l == 0) + size_2d = slice_one_size; + + offset += slice_full_size; + + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); + } + + assert(tmpl->array_size); + + if (tmpl->target != PIPE_TEXTURE_3D) { + /* Arrays and cubemaps have the entire miptree duplicated */ + + bo->cubemap_stride = ALIGN(offset, 64); + bo->size = ALIGN(bo->cubemap_stride * tmpl->array_size, 4096); + } else { + /* 3D strides across the 2D layers */ + assert(tmpl->array_size == 1); + + bo->cubemap_stride = size_2d; + bo->size = ALIGN(offset, 4096); + } +} + +static struct panfrost_bo * +panfrost_create_bo(struct panfrost_screen *screen, const struct pipe_resource *template) +{ + struct panfrost_bo *bo = CALLOC_STRUCT(panfrost_bo); + pipe_reference_init(&bo->reference, 1); + + /* Based on the usage, figure out what storing will be used. There are + * various tradeoffs: + * + * Linear: the basic format, bad for memory bandwidth, bad for cache + * use. Zero-copy, though. Renderable. + * + * Tiled: Not compressed, but cache-optimized. Expensive to write into + * (due to software tiling), but cheap to sample from. Ideal for most + * textures. + * + * AFBC: Compressed and renderable (so always desirable for non-scanout + * rendertargets). Cheap to sample from. The format is black box, so we + * can't read/write from software. + */ + + /* Tiling textures is almost always faster, unless we only use it once */ + + bool is_texture = (template->bind & PIPE_BIND_SAMPLER_VIEW); + bool is_2d = template->depth0 == 1 && template->array_size == 1; + bool is_streaming = (template->usage != PIPE_USAGE_STREAM); + + bool should_tile = is_streaming && is_texture && is_2d; + + /* Set the layout appropriately */ + bo->layout = should_tile ? PAN_TILED : PAN_LINEAR; + + panfrost_setup_slices(template, bo); + + if (bo->layout == PAN_TILED || bo->layout == PAN_LINEAR) { + struct panfrost_memory mem; + + screen->driver->allocate_slab(screen, &mem, bo->size / 4096, true, 0, 0, 0); + + bo->cpu = mem.cpu; + bo->gpu = mem.gpu; + bo->gem_handle = mem.gem_handle; + } + + return bo; +} static struct pipe_resource * panfrost_resource_create(struct pipe_screen *screen, @@ -203,64 +327,115 @@ panfrost_resource_create(struct pipe_screen *screen, case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: case PIPE_TEXTURE_3D: + case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_RECT: + case PIPE_TEXTURE_2D_ARRAY: break; default: - fprintf(stderr, "Unknown texture target %d\n", template->target); + DBG("Unknown texture target %d\n", template->target); assert(0); } - if ((template->bind & PIPE_BIND_RENDER_TARGET) || (template->bind & PIPE_BIND_DEPTH_STENCIL)) { - if (template->bind & PIPE_BIND_DISPLAY_TARGET || - template->bind & PIPE_BIND_SCANOUT || - template->bind & PIPE_BIND_SHARED) { - struct pipe_resource scanout_templat = *template; - struct renderonly_scanout *scanout; - struct winsys_handle handle; - - /* TODO: align width0 and height0? */ - - scanout = renderonly_scanout_for_resource(&scanout_templat, - pscreen->ro, &handle); - if (!scanout) - return NULL; - - assert(handle.type == WINSYS_HANDLE_TYPE_FD); - /* TODO: handle modifiers? */ - so = pan_resource(screen->resource_from_handle(screen, template, - &handle, - PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)); - close(handle.handle); - if (!so) - return NULL; - - so->scanout = scanout; - pscreen->display_target = so; - } else { - so->bo = pscreen->driver->create_bo(pscreen, template); - } + util_range_init(&so->valid_buffer_range); + + if (template->bind & PIPE_BIND_DISPLAY_TARGET || + template->bind & PIPE_BIND_SCANOUT || + template->bind & PIPE_BIND_SHARED) { + struct pipe_resource scanout_templat = *template; + struct renderonly_scanout *scanout; + struct winsys_handle handle; + + scanout = renderonly_scanout_for_resource(&scanout_templat, + pscreen->ro, &handle); + if (!scanout) + return NULL; + + assert(handle.type == WINSYS_HANDLE_TYPE_FD); + /* TODO: handle modifiers? */ + so = pan_resource(screen->resource_from_handle(screen, template, + &handle, + PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)); + close(handle.handle); + if (!so) + return NULL; + + so->scanout = scanout; + pscreen->display_target = so; } else { - so->bo = pscreen->driver->create_bo(pscreen, template); + so->bo = panfrost_create_bo(pscreen, template); } - printf("Created resource %p with scanout %p\n", so, so->scanout); - return (struct pipe_resource *)so; } +static void +panfrost_destroy_bo(struct panfrost_screen *screen, struct panfrost_bo *pbo) +{ + struct panfrost_bo *bo = (struct panfrost_bo *)pbo; + + if ((bo->layout == PAN_LINEAR || bo->layout == PAN_TILED) && + !bo->imported) { + struct panfrost_memory mem = { + .cpu = bo->cpu, + .gpu = bo->gpu, + .size = bo->size, + .gem_handle = bo->gem_handle, + }; + + screen->driver->free_slab(screen, &mem); + } + + if (bo->layout == PAN_AFBC) { + /* TODO */ + DBG("--leaking afbc (%d bytes)--\n", bo->afbc_metadata_size); + } + + if (bo->has_checksum) { + struct panfrost_memory mem = { + .cpu = bo->checksum_slab.cpu, + .gpu = bo->checksum_slab.gpu, + .size = bo->checksum_slab.size, + .gem_handle = bo->checksum_slab.gem_handle, + }; + + screen->driver->free_slab(screen, &mem); + } + + if (bo->imported) { + screen->driver->free_imported_bo(screen, bo); + } +} + +void +panfrost_bo_reference(struct panfrost_bo *bo) +{ + pipe_reference(NULL, &bo->reference); +} + +void +panfrost_bo_unreference(struct pipe_screen *screen, struct panfrost_bo *bo) +{ + /* When the reference count goes to zero, we need to cleanup */ + + if (pipe_reference(&bo->reference, NULL)) { + panfrost_destroy_bo(pan_screen(screen), bo); + } +} + static void panfrost_resource_destroy(struct pipe_screen *screen, struct pipe_resource *pt) { - struct panfrost_screen *pscreen = panfrost_screen(screen); + struct panfrost_screen *pscreen = pan_screen(screen); struct panfrost_resource *rsrc = (struct panfrost_resource *) pt; if (rsrc->scanout) renderonly_scanout_destroy(rsrc->scanout, pscreen->ro); if (rsrc->bo) - pscreen->driver->destroy_bo(pscreen, rsrc->bo); + panfrost_bo_unreference(screen, rsrc->bo); + util_range_destroy(&rsrc->valid_buffer_range); FREE(rsrc); } @@ -272,38 +447,101 @@ panfrost_transfer_map(struct pipe_context *pctx, const struct pipe_box *box, struct pipe_transfer **out_transfer) { - struct panfrost_context *ctx = pan_context(pctx); - struct panfrost_screen *screen = panfrost_screen(pctx->screen); int bytes_per_pixel = util_format_get_blocksize(resource->format); - int stride = bytes_per_pixel * resource->width0; /* TODO: Alignment? */ - uint8_t *cpu; + struct panfrost_resource *rsrc = pan_resource(resource); + struct panfrost_bo *bo = rsrc->bo; - struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer); - transfer->level = level; - transfer->usage = usage; - transfer->box = *box; - transfer->stride = stride; - assert(!transfer->box.z); + struct panfrost_gtransfer *transfer = CALLOC_STRUCT(panfrost_gtransfer); + transfer->base.level = level; + transfer->base.usage = usage; + transfer->base.box = *box; - pipe_resource_reference(&transfer->resource, resource); + pipe_resource_reference(&transfer->base.resource, resource); - *out_transfer = transfer; + *out_transfer = &transfer->base; - if (resource->bind & PIPE_BIND_DISPLAY_TARGET || - resource->bind & PIPE_BIND_SCANOUT || - resource->bind & PIPE_BIND_SHARED) { - /* Mipmapped readpixels?! */ - assert(level == 0); + /* Check if we're bound for rendering and this is a read pixels. If so, + * we need to flush */ + + struct panfrost_context *ctx = pan_context(pctx); + struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer; + + bool is_bound = false; + + for (unsigned c = 0; c < fb->nr_cbufs; ++c) { + is_bound |= fb->cbufs[c]->texture == resource; + } - /* Force a flush -- kill the pipeline */ + if (is_bound && (usage & PIPE_TRANSFER_READ)) { + assert(level == 0); panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME); } - cpu = screen->driver->map_bo(ctx, transfer); - if (cpu == NULL) - return NULL; + /* TODO: Respect usage flags */ + + if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { + /* TODO: reallocate */ + //printf("debug: Missed reallocate\n"); + } else if ((usage & PIPE_TRANSFER_WRITE) + && resource->target == PIPE_BUFFER + && !util_ranges_intersect(&rsrc->valid_buffer_range, box->x, box->x + box->width)) { + /* No flush for writes to uninitialized */ + } else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { + if (usage & PIPE_TRANSFER_WRITE) { + /* STUB: flush reading */ + //printf("debug: missed reading flush %d\n", resource->target); + } else if (usage & PIPE_TRANSFER_READ) { + /* STUB: flush writing */ + //printf("debug: missed writing flush %d (%d-%d)\n", resource->target, box->x, box->x + box->width); + } else { + /* Why are you even mapping?! */ + } + } + + if (bo->layout != PAN_LINEAR) { + /* Non-linear resources need to be indirectly mapped */ + + if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + return NULL; + + transfer->base.stride = box->width * bytes_per_pixel; + transfer->base.layer_stride = transfer->base.stride * box->height; + + /* TODO: Reads */ + transfer->map = malloc(transfer->base.layer_stride * box->depth); - return cpu + transfer->box.x * bytes_per_pixel + transfer->box.y * stride; + return transfer->map; + } else { + transfer->base.stride = bo->slices[level].stride; + transfer->base.layer_stride = bo->cubemap_stride; + + return bo->cpu + + bo->slices[level].offset + + transfer->base.box.z * bo->cubemap_stride + + transfer->base.box.y * bo->slices[level].stride + + transfer->base.box.x * bytes_per_pixel; + } +} + +static void +panfrost_tile_texture(struct panfrost_screen *screen, struct panfrost_resource *rsrc, struct panfrost_gtransfer *trans) +{ + struct panfrost_bo *bo = (struct panfrost_bo *)rsrc->bo; + + unsigned level = trans->base.level; + + panfrost_texture_swizzle( + trans->base.box.x, + trans->base.box.y, + trans->base.box.width, + trans->base.box.height, + util_format_get_blocksize(rsrc->base.format), + u_minify(rsrc->base.width0, level), + trans->map, + bo->cpu + + bo->slices[level].offset + + bo->cubemap_stride * trans->base.box.z + ); } static void @@ -311,9 +549,34 @@ panfrost_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer) { struct panfrost_context *ctx = pan_context(pctx); - struct panfrost_screen *screen = pan_screen(pctx->screen); - screen->driver->unmap_bo(ctx, transfer); + /* Gallium expects writeback here, so we tile */ + + struct panfrost_gtransfer *trans = pan_transfer(transfer); + struct panfrost_resource *prsrc = (struct panfrost_resource *) transfer->resource; + + if (trans->map) { + struct panfrost_bo *bo = prsrc->bo; + + if (transfer->usage & PIPE_TRANSFER_WRITE) { + + if (bo->layout == PAN_AFBC) { + DBG("Unimplemented: writes to AFBC\n"); + } else if (bo->layout == PAN_TILED) { + struct pipe_context *gallium = (struct pipe_context *) ctx; + struct panfrost_screen *screen = pan_screen(gallium->screen); + assert(transfer->box.depth == 1); + panfrost_tile_texture(screen, prsrc, trans); + } + } + + free(trans->map); + } + + + util_range_add(&prsrc->valid_buffer_range, + transfer->box.x, + transfer->box.x + transfer->box.width); /* Derefence the resource */ pipe_resource_reference(&transfer->resource, NULL); @@ -322,6 +585,19 @@ panfrost_transfer_unmap(struct pipe_context *pctx, free(transfer); } +static void +panfrost_transfer_flush_region(struct pipe_context *pctx, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct panfrost_resource *rsc = pan_resource(transfer->resource); + + if (transfer->resource->target == PIPE_BUFFER) { + util_range_add(&rsc->valid_buffer_range, + transfer->box.x + box->x, + transfer->box.x + box->x + box->width); + } +} static struct pb_slab * panfrost_slab_alloc(void *priv, unsigned heap, unsigned entry_size, unsigned group_index) @@ -364,15 +640,35 @@ panfrost_slab_can_reclaim(void *priv, struct pb_slab_entry *entry) static void panfrost_slab_free(void *priv, struct pb_slab *slab) { - /* STUB */ - //struct panfrost_memory *mem = (struct panfrost_memory *) slab; - printf("stub: Tried to free slab\n"); + struct panfrost_memory *mem = (struct panfrost_memory *) slab; + struct panfrost_screen *screen = (struct panfrost_screen *) priv; + + screen->driver->free_slab(screen, mem); } static void panfrost_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc) { - //fprintf(stderr, "TODO %s\n", __func__); + //DBG("TODO %s\n", __func__); +} + +static enum pipe_format +panfrost_resource_get_internal_format(struct pipe_resource *prsrc) +{ + return prsrc->format; +} + +static void +panfrost_resource_set_stencil(struct pipe_resource *prsrc, + struct pipe_resource *stencil) +{ + pan_resource(prsrc)->separate_stencil = pan_resource(stencil); +} + +static struct pipe_resource * +panfrost_resource_get_stencil(struct pipe_resource *prsrc) +{ + return &pan_resource(prsrc)->separate_stencil->base; } static const struct u_transfer_vtbl transfer_vtbl = { @@ -380,10 +676,10 @@ static const struct u_transfer_vtbl transfer_vtbl = { .resource_destroy = panfrost_resource_destroy, .transfer_map = panfrost_transfer_map, .transfer_unmap = panfrost_transfer_unmap, - .transfer_flush_region = u_default_transfer_flush_region, - //.get_internal_format = panfrost_resource_get_internal_format, - //.set_stencil = panfrost_resource_set_stencil, - //.get_stencil = panfrost_resource_get_stencil, + .transfer_flush_region = panfrost_transfer_flush_region, + .get_internal_format = panfrost_resource_get_internal_format, + .set_stencil = panfrost_resource_set_stencil, + .get_stencil = panfrost_resource_get_stencil, }; void @@ -396,7 +692,7 @@ panfrost_resource_screen_init(struct panfrost_screen *pscreen) 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, - true, true, + true, false, true, true); pb_slabs_init(&pscreen->slabs, @@ -423,7 +719,6 @@ panfrost_resource_context_init(struct pipe_context *pctx) pctx->surface_destroy = panfrost_surface_destroy; pctx->resource_copy_region = util_resource_copy_region; pctx->blit = panfrost_blit; - //pctx->generate_mipmap = panfrost_generate_mipmap; pctx->flush_resource = panfrost_flush_resource; pctx->invalidate_resource = panfrost_invalidate_resource; pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region;