#include "util/u_transfer.h"
#include "util/u_transfer_helper.h"
#include "util/u_gen_mipmap.h"
+#include "util/u_drm.h"
#include "pan_bo.h"
#include "pan_context.h"
rsc->bo = panfrost_bo_import(dev, whandle->handle);
rsc->internal_format = templat->format;
- rsc->modifier = DRM_FORMAT_MOD_LINEAR;
+ rsc->modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ?
+ DRM_FORMAT_MOD_LINEAR : whandle->modifier;
rsc->slices[0].stride = whandle->stride;
rsc->slices[0].offset = whandle->offset;
rsc->slices[0].initialized = true;
rsc->checksummed = true;
}
+ if (drm_is_afbc(whandle->modifier)) {
+ rsc->slices[0].header_size =
+ panfrost_afbc_header_size(templat->width0, templat->height0);
+ }
+
if (dev->ro) {
rsc->scanout =
renderonly_create_gpu_import_for_resource(prsc, dev->ro, NULL);
struct panfrost_resource *rsrc = (struct panfrost_resource *) pt;
struct renderonly_scanout *scanout = rsrc->scanout;
- handle->modifier = DRM_FORMAT_MOD_INVALID;
+ handle->modifier = rsrc->modifier;
if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
return false;
static struct pipe_resource *
panfrost_create_scanout_res(struct pipe_screen *screen,
- const struct pipe_resource *template)
+ const struct pipe_resource *template,
+ uint64_t modifier)
{
struct panfrost_device *dev = pan_device(screen);
struct pipe_resource scanout_templat = *template;
return NULL;
assert(handle.type == WINSYS_HANDLE_TYPE_FD);
- /* TODO: handle modifiers? */
+ handle.modifier = modifier;
res = screen->resource_from_handle(screen, template, &handle,
PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
close(handle.handle);
if (dev->ro && (template->bind &
(PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)))
- return panfrost_create_scanout_res(screen, template);
+ return panfrost_create_scanout_res(screen, template, modifier);
struct panfrost_resource *so = rzalloc(screen, struct panfrost_resource);
so->base = *template;
DRM_FORMAT_MOD_INVALID);
}
+/* If no modifier is specified, we'll choose. Otherwise, the order of
+ * preference is compressed, tiled, linear. */
+
+static struct pipe_resource *
+panfrost_resource_create_with_modifiers(struct pipe_screen *screen,
+ const struct pipe_resource *template,
+ const uint64_t *modifiers, int count)
+{
+ for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
+ if (drm_find_modifier(pan_best_modifiers[i], modifiers, count)) {
+ return panfrost_resource_create_with_modifier(screen, template,
+ pan_best_modifiers[i]);
+ }
+ }
+
+ /* If we didn't find one, app specified invalid */
+ assert(count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID);
+ return panfrost_resource_create(screen, template);
+}
+
static void
panfrost_resource_destroy(struct pipe_screen *screen,
struct pipe_resource *pt)
bool fake_rgtc = !panfrost_supports_compressed_format(dev, MALI_BC4_UNORM);
- //pscreen->base.resource_create_with_modifiers =
- // panfrost_resource_create_with_modifiers;
+ pscreen->resource_create_with_modifiers =
+ panfrost_resource_create_with_modifiers;
pscreen->resource_create = u_transfer_helper_resource_create;
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
pscreen->resource_from_handle = panfrost_resource_from_handle;
* to us here.
*/
+/* List of supported modifiers, in descending order of preference. AFBC is
+ * faster than u-interleaved tiling which is faster than linear. Within AFBC,
+ * enabling the YUV-like transform is typically a win where possible. */
+
+uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
+ DRM_FORMAT_MOD_ARM_AFBC(
+ AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+ AFBC_FORMAT_MOD_SPARSE |
+ AFBC_FORMAT_MOD_YTR),
+
+ DRM_FORMAT_MOD_ARM_AFBC(
+ AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+ AFBC_FORMAT_MOD_SPARSE),
+
+ DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
+ DRM_FORMAT_MOD_LINEAR
+};
+
/* Map modifiers to mali_texture_layout for packing in a texture descriptor */
static enum mali_texture_layout