{
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);
}
}
so->texture_bo = prsrc->bo->gpu;
- so->layout = prsrc->layout;
+ so->modifier = prsrc->modifier;
unsigned char user_swizzle[4] = {
so->base.swizzle_r,
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);
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,
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);
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,
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 *
.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,
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 {
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 {
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;
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");
}
}
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));
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;
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;
fbx->ds_linear.stencil_stride = stencil_slice.stride;
fbx->ds_linear.stencil_layer_stride = stencil_layer_stride;
}
-
- } else {
- assert(0);
}
}
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;
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)
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 */
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;
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;
}
}
- 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)
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,
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,
/* 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;
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);
}
}
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;
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,
* 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
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);
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,
*/
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");
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,
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 */
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));
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,
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);
.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,
},
desc,
mali_format,
type,
- layout,
+ modifier,
width, height,
first_level, last_level,
first_layer, last_layer,
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,
desc,
mali_format,
type,
- layout,
+ modifier,
width, height,
first_level, last_level,
first_layer, last_layer,
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;
#define __PAN_TEXTURE_H
#include <stdbool.h>
+#include "drm-uapi/drm_fourcc.h"
#include "util/format/u_format.h"
#include "compiler/shader_enums.h"
#include "panfrost-job.h"
struct panfrost_bo *bo;
struct panfrost_slice *slices;
unsigned cubemap_stride;
- enum mali_texture_layout layout;
+ uint64_t modifier;
};
unsigned
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(
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,
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,
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