diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index cec1c715632..756520c5ffe 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -1419,7 +1419,7 @@ panfrost_update_sampler_view(struct panfrost_sampler_view *view, { struct panfrost_resource *rsrc = pan_resource(view->base.texture); if (view->texture_bo != rsrc->bo->gpu || - view->layout != rsrc->layout) { + view->modifier != rsrc->modifier) { panfrost_bo_unreference(view->bo); panfrost_create_sampler_view_bo(view, pctx, &rsrc->base); } diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 347111625f3..78fa9628668 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -944,7 +944,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, } so->texture_bo = prsrc->bo->gpu; - so->layout = prsrc->layout; + so->modifier = prsrc->modifier; unsigned char user_swizzle[4] = { so->base.swizzle_r, @@ -989,7 +989,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, so->base.u.tex.first_layer, so->base.u.tex.last_layer, texture->nr_samples, - type, prsrc->layout); + type, prsrc->modifier); so->bo = panfrost_bo_create(device, size, 0); @@ -999,7 +999,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, texture->width0, texture->height0, depth, array_size, format, - type, prsrc->layout, + type, prsrc->modifier, so->base.u.tex.first_level, so->base.u.tex.last_level, so->base.u.tex.first_layer, @@ -1017,7 +1017,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, so->base.u.tex.first_layer, so->base.u.tex.last_layer, texture->nr_samples, - type, prsrc->layout); + type, prsrc->modifier); size += sizeof(struct mali_texture_descriptor); so->bo = panfrost_bo_create(device, size, 0); @@ -1027,7 +1027,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, texture->width0, texture->height0, depth, array_size, format, - type, prsrc->layout, + type, prsrc->modifier, so->base.u.tex.first_level, so->base.u.tex.last_level, so->base.u.tex.first_layer, diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index dfe98373e1a..f0791626ca4 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -274,7 +274,7 @@ struct panfrost_sampler_view { struct panfrost_bo *bo; struct bifrost_texture_descriptor *bifrost_descriptor; mali_ptr texture_bo; - enum mali_texture_layout layout; + uint64_t modifier; }; static inline struct panfrost_context * diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 10bca05b26a..13075e63774 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -845,7 +845,7 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u .depth0 = rsrc->base.depth0, .format = format, .type = type, - .layout = rsrc->layout, + .modifier = rsrc->modifier, .array_size = rsrc->base.array_size, .first_level = level, .last_level = level, diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 522dd8f6dfb..759b8d9936b 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -227,9 +227,9 @@ panfrost_mfbd_set_cbuf( else rt->format.msaa = MALI_MSAA_SINGLE; - /* Now, we set the layout specific pieces */ + /* Now, we set the modifier specific pieces */ - if (rsrc->layout == MALI_TEXTURE_LINEAR) { + if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { if (is_bifrost) { rt->format.unk4 = 0x1; } else { @@ -239,7 +239,7 @@ panfrost_mfbd_set_cbuf( rt->framebuffer = base; rt->framebuffer_stride = stride / 16; rt->layer_stride = layer_stride; - } else if (rsrc->layout == MALI_TEXTURE_TILED) { + } else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { if (is_bifrost) { rt->format.unk3 |= 0x8; } else { @@ -249,7 +249,7 @@ panfrost_mfbd_set_cbuf( rt->framebuffer = base; rt->framebuffer_stride = stride; rt->layer_stride = layer_stride; - } else if (rsrc->layout == MALI_TEXTURE_AFBC) { + } else if (drm_is_afbc(rsrc->modifier)) { rt->format.block = MALI_BLOCK_AFBC; unsigned header_size = rsrc->slices[level].header_size; @@ -260,18 +260,14 @@ panfrost_mfbd_set_cbuf( rt->afbc.stride = 0; rt->afbc.flags = MALI_AFBC_FLAGS; - unsigned components = util_format_get_nr_components(surf->format); - - /* The "lossless colorspace transform" is lossy for R and RG formats */ - if (components >= 3) - rt->afbc.flags |= MALI_AFBC_YTR; + if (rsrc->modifier & AFBC_FORMAT_MOD_YTR) + rt->afbc.flags |= MALI_AFBC_YTR; /* TODO: The blob sets this to something nonzero, but it's not * clear what/how to calculate/if it matters */ rt->framebuffer_stride = 0; } else { - fprintf(stderr, "Invalid render layout (cbuf)"); - assert(0); + unreachable("Invalid mod"); } } @@ -296,7 +292,7 @@ panfrost_mfbd_set_zsbuf( mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); - if (rsrc->layout == MALI_TEXTURE_AFBC) { + if (drm_is_afbc(rsrc->modifier)) { /* The only Z/S format we can compress is Z24S8 or variants * thereof (handled by the gallium frontend) */ assert(panfrost_is_z24s8_variant(surf->format)); @@ -315,7 +311,9 @@ panfrost_mfbd_set_zsbuf( fbx->ds_afbc.flags = MALI_AFBC_FLAGS; fbx->ds_afbc.padding = 0x1000; - } else if (rsrc->layout == MALI_TEXTURE_LINEAR || rsrc->layout == MALI_TEXTURE_TILED) { + } else { + assert(rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || rsrc->modifier == DRM_FORMAT_MOD_LINEAR); + /* TODO: Z32F(S8) support, which is always linear */ int stride = rsrc->slices[level].stride; @@ -328,7 +326,7 @@ panfrost_mfbd_set_zsbuf( fbx->ds_linear.depth = base; - if (rsrc->layout == MALI_TEXTURE_LINEAR) { + if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { fbx->zs_block = MALI_BLOCK_LINEAR; fbx->ds_linear.depth_stride = stride / 16; fbx->ds_linear.depth_layer_stride = layer_stride; @@ -365,9 +363,6 @@ panfrost_mfbd_set_zsbuf( fbx->ds_linear.stencil_stride = stencil_slice.stride; fbx->ds_linear.stencil_layer_stride = stencil_layer_stride; } - - } else { - assert(0); } } diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 5dd6d36b9f2..8be9c43811b 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -75,7 +75,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, rsc->bo = panfrost_bo_import(dev, whandle->handle); rsc->internal_format = templat->format; - rsc->layout = MALI_TEXTURE_LINEAR; + rsc->modifier = DRM_FORMAT_MOD_LINEAR; rsc->slices[0].stride = whandle->stride; rsc->slices[0].offset = whandle->offset; rsc->slices[0].initialized = true; @@ -234,7 +234,7 @@ panfrost_create_scanout_res(struct pipe_screen *screen, return res; } -/* Setup the mip tree given a particular layout, possibly with checksumming */ +/* Setup the mip tree given a particular modifier, possibly with checksumming */ static void panfrost_setup_slices(struct panfrost_resource *pres, size_t *bo_size) @@ -265,8 +265,9 @@ panfrost_setup_slices(struct panfrost_resource *pres, size_t *bo_size) bool renderable = res->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL) && res->target != PIPE_BUFFER; - bool afbc = pres->layout == MALI_TEXTURE_AFBC; - bool tiled = pres->layout == MALI_TEXTURE_TILED; + bool afbc = drm_is_afbc(pres->modifier); + bool tiled = pres->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; + bool linear = pres->modifier == DRM_FORMAT_MOD_LINEAR; bool should_align = renderable || tiled; /* We don't know how to specify a 2D stride for 3D textures */ @@ -307,7 +308,7 @@ panfrost_setup_slices(struct panfrost_resource *pres, size_t *bo_size) stride /= 4; /* ..but cache-line align it for performance */ - if (can_align_stride && pres->layout == MALI_TEXTURE_LINEAR) + if (can_align_stride && linear) stride = ALIGN_POT(stride, 64); slice->stride = stride; @@ -410,10 +411,12 @@ panfrost_resource_create_bo(struct panfrost_device *dev, struct panfrost_resourc pres->checksummed = can_checksum && should_checksum; - /* Set the layout appropriately */ + /* Set the modifier appropriately */ assert(!(must_tile && !can_tile)); /* must_tile => can_tile */ - pres->layout = ((can_tile && should_tile) || must_tile) ? MALI_TEXTURE_TILED : MALI_TEXTURE_LINEAR; - pres->layout_constant = must_tile || !can_tile; + pres->modifier = ((can_tile && should_tile) || must_tile) ? + DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED : + DRM_FORMAT_MOD_LINEAR; + pres->modifier_constant = must_tile || !can_tile; size_t bo_size; @@ -647,7 +650,7 @@ panfrost_transfer_map(struct pipe_context *pctx, } } - if (rsrc->layout != MALI_TEXTURE_LINEAR) { + if (rsrc->modifier != DRM_FORMAT_MOD_LINEAR) { /* Non-linear resources need to be indirectly mapped */ if (usage & PIPE_TRANSFER_MAP_DIRECTLY) @@ -659,9 +662,9 @@ panfrost_transfer_map(struct pipe_context *pctx, assert(box->depth == 1); if ((usage & PIPE_TRANSFER_READ) && rsrc->slices[level].initialized) { - if (rsrc->layout == MALI_TEXTURE_AFBC) { + if (drm_is_afbc(rsrc->modifier)) { unreachable("Unimplemented: reads from AFBC"); - } else if (rsrc->layout == MALI_TEXTURE_TILED) { + } else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { panfrost_load_tiled_image( transfer->map, bo->cpu + rsrc->slices[level].offset, @@ -721,32 +724,32 @@ panfrost_transfer_unmap(struct pipe_context *pctx, struct panfrost_bo *bo = prsrc->bo; if (transfer->usage & PIPE_TRANSFER_WRITE) { - if (prsrc->layout == MALI_TEXTURE_AFBC) { + if (drm_is_afbc(prsrc->modifier)) { unreachable("Unimplemented: writes to AFBC\n"); - } else if (prsrc->layout == MALI_TEXTURE_TILED) { + } else if (prsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { assert(transfer->box.depth == 1); /* Do we overwrite the entire resource? If so, * we don't need an intermediate blit so it's a - * good time to switch the layout. */ + * good time to switch the modifier. */ bool discards_content = prsrc->base.last_level == 0 && transfer->box.width == prsrc->base.width0 && transfer->box.height == prsrc->base.height0 && transfer->box.x == 0 && transfer->box.y == 0 - && !prsrc->layout_constant; + && !prsrc->modifier_constant; /* It also serves as a good heuristic for * streaming textures (e.g. in video players), * but we could do better */ if (discards_content) - ++prsrc->layout_updates; + ++prsrc->modifier_updates; - if (prsrc->layout_updates >= LAYOUT_CONVERT_THRESHOLD) + if (prsrc->modifier_updates >= LAYOUT_CONVERT_THRESHOLD) { - prsrc->layout = MALI_TEXTURE_LINEAR; + prsrc->modifier = DRM_FORMAT_MOD_LINEAR; util_copy_rect( bo->cpu + prsrc->slices[0].offset, diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 31936d77d65..ccf3af45082 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -58,17 +58,17 @@ struct panfrost_resource { /* Distance from tree to tree */ unsigned cubemap_stride; - /* Internal layout (tiled?) */ - enum mali_texture_layout layout; + /* DRM fourcc code: linear, 16x16 u-interleaved, AFBC */ + uint64_t modifier; - /* Whether the layout can be changed */ - bool layout_constant; + /* Whether the modifier can be changed */ + bool modifier_constant; /* Is transaciton elimination enabled? */ bool checksummed; - /* Used to decide when to convert to another layout */ - uint16_t layout_updates; + /* Used to decide when to convert to another modifier */ + uint16_t modifier_updates; enum pipe_format internal_format; diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index a08a6f3e8f7..6425dfa65bc 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -141,13 +141,13 @@ panfrost_sfbd_set_cbuf( fb->framebuffer = base; fb->stride = stride; - if (rsrc->layout == MALI_TEXTURE_LINEAR) + if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) fb->format.block = MALI_BLOCK_LINEAR; - else if (rsrc->layout == MALI_TEXTURE_TILED) { + else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { fb->format.block = MALI_BLOCK_TILED; fb->stride *= 16; } else { - fprintf(stderr, "Invalid render layout\n"); + fprintf(stderr, "Invalid render modifier\n"); assert(0); } } @@ -163,8 +163,8 @@ panfrost_sfbd_set_zsbuf( unsigned level = surf->u.tex.level; assert(surf->u.tex.first_layer == 0); - if (rsrc->layout != MALI_TEXTURE_TILED) - unreachable("Invalid render layout."); + if (rsrc->modifier != DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) + unreachable("Invalid render modifier."); fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset; fb->depth_stride = rsrc->slices[level].stride; diff --git a/src/panfrost/lib/pan_blit.c b/src/panfrost/lib/pan_blit.c index ece664bb5b9..e1cfb1e5b17 100644 --- a/src/panfrost/lib/pan_blit.c +++ b/src/panfrost/lib/pan_blit.c @@ -299,7 +299,7 @@ panfrost_load_midg( image->width0, image->height0, MAX2(image->nr_samples, 1), 1, image->format, MALI_TEX_2D, - image->layout, + image->modifier, image->first_level, image->last_level, 0, 0, image->nr_samples, diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index da436ea7318..84721ff734d 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -43,6 +43,21 @@ * to us here. */ +/* Map modifiers to mali_texture_layout for packing in a texture descriptor */ + +static enum mali_texture_layout +panfrost_modifier_to_layout(uint64_t modifier) +{ + if (drm_is_afbc(modifier)) + return MALI_TEXTURE_AFBC; + else if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) + return MALI_TEXTURE_TILED; + else if (modifier == DRM_FORMAT_MOD_LINEAR) + return MALI_TEXTURE_LINEAR; + else + unreachable("Invalid modifer"); +} + /* Check if we need to set a custom stride by computing the "expected" * stride and comparing it to what the user actually wants. Only applies * to linear textures, since tiled/compressed textures have strict @@ -90,10 +105,10 @@ panfrost_astc_stretch(unsigned dim) static unsigned panfrost_compression_tag( const struct util_format_description *desc, - enum mali_format format, enum mali_texture_layout layout) + enum mali_format format, uint64_t modifier) { - if (layout == MALI_TEXTURE_AFBC) - return desc->nr_channels >= 3; + if (drm_is_afbc(modifier)) + return (modifier & AFBC_FORMAT_MOD_YTR) ? 1 : 0; else if (format == MALI_ASTC_2D_LDR || format == MALI_ASTC_2D_HDR) return (panfrost_astc_stretch(desc->block.height) << 3) | panfrost_astc_stretch(desc->block.width); @@ -157,10 +172,10 @@ panfrost_estimate_texture_payload_size( unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, - enum mali_texture_type type, enum mali_texture_layout layout) + enum mali_texture_type type, uint64_t modifier) { /* Assume worst case */ - unsigned manual_stride = (layout == MALI_TEXTURE_LINEAR); + unsigned manual_stride = (modifier == DRM_FORMAT_MOD_LINEAR); unsigned elements = panfrost_texture_num_elements( first_level, last_level, @@ -178,12 +193,12 @@ panfrost_estimate_texture_payload_size( */ static unsigned -panfrost_nonlinear_stride(enum mali_texture_layout layout, +panfrost_nonlinear_stride(uint64_t modifier, unsigned bytes_per_pixel, unsigned width, unsigned height) { - if (layout == MALI_TEXTURE_TILED) { + if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { return (height <= 16) ? 0 : (16 * bytes_per_pixel * ALIGN_POT(width, 16)); } else { unreachable("TODO: AFBC on Bifrost"); @@ -196,7 +211,7 @@ panfrost_emit_texture_payload( const struct util_format_description *desc, enum mali_format mali_format, enum mali_texture_type type, - enum mali_texture_layout layout, + uint64_t modifier, unsigned width, unsigned height, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, @@ -206,7 +221,7 @@ panfrost_emit_texture_payload( mali_ptr base, struct panfrost_slice *slices) { - base |= panfrost_compression_tag(desc, mali_format, layout); + base |= panfrost_compression_tag(desc, mali_format, modifier); /* Inject the addresses in, interleaving array indices, mip levels, * cube faces, and strides in that order */ @@ -231,9 +246,9 @@ panfrost_emit_texture_payload( cube_stride, l, w * face_mult + f, s); if (manual_stride) { - payload[idx++] = (layout == MALI_TEXTURE_LINEAR) ? + payload[idx++] = (modifier == DRM_FORMAT_MOD_LINEAR) ? slices[l].stride : - panfrost_nonlinear_stride(layout, + panfrost_nonlinear_stride(modifier, MAX2(desc->block.bits / 8, 1), u_minify(width, l), u_minify(height, l)); @@ -264,7 +279,7 @@ panfrost_new_texture( uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_type type, - enum mali_texture_layout layout, + uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, @@ -281,7 +296,7 @@ panfrost_new_texture( enum mali_format mali_format = panfrost_pipe_format_table[desc->format].hw; assert(mali_format); - bool manual_stride = (layout == MALI_TEXTURE_LINEAR) + bool manual_stride = (modifier == DRM_FORMAT_MOD_LINEAR) && panfrost_needs_explicit_stride(slices, width, first_level, last_level, bytes_per_pixel); @@ -299,7 +314,7 @@ panfrost_new_texture( .format = mali_format, .srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB), .type = type, - .layout = layout, + .layout = panfrost_modifier_to_layout(modifier), .manual_stride = manual_stride, .unknown2 = 1, }, @@ -315,7 +330,7 @@ panfrost_new_texture( desc, mali_format, type, - layout, + modifier, width, height, first_level, last_level, first_layer, last_layer, @@ -333,7 +348,7 @@ panfrost_new_texture_bifrost( uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_type type, - enum mali_texture_layout layout, + uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, @@ -354,7 +369,7 @@ panfrost_new_texture_bifrost( desc, mali_format, type, - layout, + modifier, width, height, first_level, last_level, first_layer, last_layer, @@ -372,7 +387,7 @@ panfrost_new_texture_bifrost( descriptor->width = MALI_POSITIVE(u_minify(width, first_level)); descriptor->height = MALI_POSITIVE(u_minify(height, first_level)); descriptor->swizzle = swizzle; - descriptor->layout = layout; + descriptor->layout = panfrost_modifier_to_layout(modifier), descriptor->levels = last_level - first_level; descriptor->unk1 = 0x0; descriptor->levels_unk = 0; diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index c4a07d15ad2..55f5f796b28 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -29,6 +29,7 @@ #define __PAN_TEXTURE_H #include +#include "drm-uapi/drm_fourcc.h" #include "util/format/u_format.h" #include "compiler/shader_enums.h" #include "panfrost-job.h" @@ -64,7 +65,7 @@ struct pan_image { struct panfrost_bo *bo; struct panfrost_slice *slices; unsigned cubemap_stride; - enum mali_texture_layout layout; + uint64_t modifier; }; unsigned @@ -88,7 +89,7 @@ panfrost_estimate_texture_payload_size( unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, - enum mali_texture_type type, enum mali_texture_layout layout); + enum mali_texture_type type, uint64_t modifier); void panfrost_new_texture( @@ -97,7 +98,7 @@ panfrost_new_texture( uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_type type, - enum mali_texture_layout layout, + uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, @@ -113,7 +114,7 @@ panfrost_new_texture_bifrost( uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_type type, - enum mali_texture_layout layout, + uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, @@ -195,4 +196,10 @@ panfrost_load_midg( struct pan_image *image, unsigned loc); +/* DRM modifier helper */ + +#define drm_is_afbc(mod) \ + ((mod >> 52) == (DRM_FORMAT_MOD_ARM_TYPE_AFBC | \ + (DRM_FORMAT_MOD_VENDOR_ARM << 4))) + #endif