#include "pan_bo.h"
#include "pan_context.h"
#include "pan_util.h"
-#include "pan_format.h"
#include "util/format/u_format.h"
case PIPE_FORMAT_A4B4G4R4_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_R4G4B4A4_UNORM:
fmt.unk1 = 0x4;
fmt.nr_channels = MALI_POSITIVE(1);
fmt.unk2 = 0x5;
assert(surf->u.tex.last_layer == first_layer);
signed stride = rsrc->slices[level].stride;
- mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer);
+ mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
fb->format = panfrost_sfbd_format(surf);
fb->framebuffer = base;
fb->stride = stride;
- if (rsrc->layout == PAN_LINEAR)
- fb->format.block = MALI_BLOCK_LINEAR;
- else if (rsrc->layout == PAN_TILED) {
- fb->format.block = MALI_BLOCK_TILED;
+ if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
+ fb->format.block = MALI_BLOCK_FORMAT_LINEAR;
+ else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+ fb->format.block = MALI_BLOCK_FORMAT_TILED;
fb->stride *= 16;
} else {
- fprintf(stderr, "Invalid render layout\n");
+ fprintf(stderr, "Invalid render modifier\n");
assert(0);
}
}
struct pipe_surface *surf)
{
struct panfrost_resource *rsrc = pan_resource(surf->texture);
+ struct panfrost_context *ctx = pan_context(surf->context);
unsigned level = surf->u.tex.level;
assert(surf->u.tex.first_layer == 0);
- if (rsrc->layout == PAN_LINEAR) {
- if (panfrost_is_z24s8_variant(surf->format)) {
-
- fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
- fb->depth_stride = rsrc->slices[level].stride;
-
- fb->stencil_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
- fb->stencil_stride = rsrc->slices[level].stride;
-
- } else if (surf->format == PIPE_FORMAT_Z32_UNORM ||
- surf->format == PIPE_FORMAT_Z32_FLOAT) {
+ 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;
+
+ /* No stencil? Job done. */
+ if (!ctx->depth_stencil || !ctx->depth_stencil->base.stencil[0].enabled)
+ return;
+
+ if (panfrost_is_z24s8_variant(surf->format)) {
+ /* Stencil data is interleaved with depth */
+ fb->stencil_buffer = fb->depth_buffer;
+ fb->stencil_stride = fb->depth_stride;
+ } else if (surf->format == PIPE_FORMAT_Z32_FLOAT) {
+ /* No stencil, nothing to do */
+ } else if (surf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+ /* Stencil data in separate buffer */
+ struct panfrost_resource *stencil = rsrc->separate_stencil;
+ struct panfrost_slice stencil_slice = stencil->slices[level];
+
+ fb->stencil_buffer = stencil->bo->gpu + stencil_slice.offset;
+ fb->stencil_stride = stencil_slice.stride;
+ } else
+ unreachable("Unsupported depth/stencil format.");
+}
- fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
- fb->depth_stride = rsrc->slices[level].stride;
- } else if (surf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+static struct mali_single_framebuffer
+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_device *dev = pan_device(gallium->screen);
+
+ unsigned width = batch->key.width;
+ unsigned height = batch->key.height;
+
+ /* TODO: Why do we need to make the stack bigger than other platforms? */
+ unsigned shift = panfrost_get_stack_shift(MAX2(batch->stack_size, 512));
+
+ struct mali_single_framebuffer framebuffer = {
+ .width = MALI_POSITIVE(width),
+ .height = MALI_POSITIVE(height),
+ .shared_memory = {
+ .stack_shift = shift,
+ .shared_workgroup_count = ~0,
+ .scratchpad = panfrost_batch_get_scratchpad(batch, shift, dev->thread_tls_alloc, dev->core_count)->gpu,
+ },
+ .format = {
+ .unk3 = 0x3,
+ },
+ .clear_flags = 0x1000,
+ .tiler = panfrost_emit_midg_tiler(batch, vertex_count),
+ };
- fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
- fb->depth_stride = rsrc->slices[level].stride;
+ return framebuffer;
+}
- struct panfrost_resource *stencil = rsrc->separate_stencil;
- struct panfrost_slice stencil_slice = stencil->slices[level];
+void
+panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
+{
+ struct mali_single_framebuffer sfbd =
+ panfrost_emit_sfbd(batch, vertex_count);
- fb->stencil_buffer = stencil->bo->gpu + stencil_slice.offset;
- fb->stencil_stride = stencil_slice.stride;
- } else {
- fprintf(stderr, "Unsupported depth/stencil format\n");
- assert(0);
- }
- } else {
- fprintf(stderr, "Invalid render layout\n");
- assert(0);
- }
+ memcpy(batch->framebuffer.cpu, &sfbd, sizeof(sfbd));
}
/* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
panfrost_sfbd_clear(batch, &fb);
/* SFBD does not support MRT natively; sanity check */
- assert(batch->key.nr_cbufs == 1);
- panfrost_sfbd_set_cbuf(&fb, batch->key.cbufs[0]);
+ assert(batch->key.nr_cbufs <= 1);
+ if (batch->key.nr_cbufs) {
+ struct pipe_surface *surf = batch->key.cbufs[0];
+ struct panfrost_resource *rsrc = pan_resource(surf->texture);
+ struct panfrost_bo *bo = rsrc->bo;
+
+ panfrost_sfbd_set_cbuf(&fb, surf);
+
+ if (rsrc->checksummed) {
+ unsigned level = surf->u.tex.level;
+ struct panfrost_slice *slice = &rsrc->slices[level];
+
+ fb.checksum_stride = slice->checksum_stride;
+ fb.checksum = bo->gpu + slice->checksum_offset;
+ }
+ }
if (batch->key.zsbuf)
panfrost_sfbd_set_zsbuf(&fb, batch->key.zsbuf);
fb.format.unk2 |= MALI_SFBD_FORMAT_MSAA_B;
}
- struct pipe_surface *surf = batch->key.cbufs[0];
- struct panfrost_resource *rsrc = pan_resource(surf->texture);
- struct panfrost_bo *bo = rsrc->bo;
-
- if (rsrc->checksummed) {
- unsigned level = surf->u.tex.level;
- struct panfrost_slice *slice = &rsrc->slices[level];
-
- fb.checksum_stride = slice->checksum_stride;
- fb.checksum = bo->gpu + slice->checksum_offset;
- }
-
- return panfrost_upload_transient(batch, &fb, sizeof(fb)) | MALI_SFBD;
+ return panfrost_pool_upload_aligned(&batch->pool, &fb, sizeof(fb), 64);
}