panfrost: Blit with the FullScreenJob descriptor (v9)

A vertex array is pre-allocated in order to interpolate varyings.

The GPU (tiler) only writes the VertexArrayDescriptor fields
"pointer", "vertex_packet_stride" and "vertex_attribute_stride" in
MallocVertexShaderJob mode. These fields can also be programmed with
IndexedVertexShaderJob and FullScreenJob modes. Update the XML spec
file comment accordingly.

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Reviewed-by: Ashley Smith <ashley.smith@collabora.com>
Acked-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40124>
This commit is contained in:
Loïc Molinari 2026-03-31 13:02:23 +02:00 committed by Marge Bot
parent 82306a6bd7
commit ed05834caf
6 changed files with 128 additions and 10 deletions

View file

@ -25,8 +25,8 @@ panfrost_blitter_draw_rectangle(struct blitter_context *blitter,
struct panfrost_context *pctx = pan_context(ctx);
struct panfrost_screen *scr = pan_screen(ctx->screen);
/* Always fallback for now. */
goto fallback;
if (scr->dev.arch != 9 || depth != 0.0f || num_instances > 1)
goto fallback;
/* Map viewport to the dest rect of the framebuffer. The tiler will then be
* configured to use it as scissor box in order to clip fullscreen

View file

@ -435,6 +435,27 @@ struct panfrost_shader_binary {
struct util_dynarray binary;
};
struct panfrost_run_fullscreen_attrib {
float x, y, z, w;
};
/* The tiler always allocates packets that can hold 64 vertices in RUN_IDVS
* malloc mode. For RUN_FULLSCREEN, the vertex array is preallocated but must
* match the tiler allocation strategy. */
#define PAN_RUN_FULLSCREEN_NUM_VERTICES 64
#define PAN_RUN_FULLSCREEN_ATTRIB_STRIDE \
sizeof(struct panfrost_run_fullscreen_attrib)
/* A RUN_FULLSCREEN packet is made of a position and a texcoord attrib. */
#define PAN_RUN_FULLSCREEN_PACKET_STRIDE \
(2 * sizeof(struct panfrost_run_fullscreen_attrib))
#define PAN_RUN_FULLSCREEN_ARRAY_SIZE \
(PAN_RUN_FULLSCREEN_NUM_VERTICES * PAN_RUN_FULLSCREEN_PACKET_STRIDE)
#define PAN_RUN_FULLSCREEN_ARRAY_ALIGN 64
void
panfrost_disk_cache_store(struct disk_cache *cache,
const struct panfrost_uncompiled_shader *uncompiled,
@ -472,6 +493,10 @@ unsigned pan_assign_vertex_buffer(struct pan_vertex_buffer *buffers,
unsigned *nr_bufs, unsigned vbi,
unsigned divisor);
struct pan_ptr panfrost_emit_fullscreen_vertex_array(struct panfrost_batch *batch,
enum blitter_attrib_type type,
const struct blitter_attrib *attrib);
struct panfrost_zsa_state;
struct panfrost_sampler_state;
struct panfrost_sampler_view;

View file

@ -172,6 +172,41 @@ pan_assign_vertex_buffer(struct pan_vertex_buffer *buffers, unsigned *nr_bufs,
return idx;
}
struct pan_ptr
panfrost_emit_fullscreen_vertex_array(struct panfrost_batch *batch,
enum blitter_attrib_type type,
const struct blitter_attrib *attrib)
{
struct pan_ptr array = { .cpu = NULL, .gpu = 0 };
struct panfrost_run_fullscreen_attrib *texcoords;
if (type != UTIL_BLITTER_ATTRIB_TEXCOORD_XY &&
type != UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW)
return array;
array = pan_pool_alloc_aligned(&batch->pool.base,
PAN_RUN_FULLSCREEN_ARRAY_SIZE,
PAN_RUN_FULLSCREEN_ARRAY_ALIGN);
texcoords = (struct panfrost_run_fullscreen_attrib *)
((uint8_t *)array.cpu + (PAN_RUN_FULLSCREEN_NUM_VERTICES *
PAN_RUN_FULLSCREEN_ATTRIB_STRIDE));
texcoords[0].x = attrib->texcoord.x1;
texcoords[0].y = attrib->texcoord.y1;
texcoords[0].z = attrib->texcoord.z;
texcoords[0].w = attrib->texcoord.w;
texcoords[1].x = attrib->texcoord.x2;
texcoords[1].y = attrib->texcoord.y1;
texcoords[1].z = attrib->texcoord.z;
texcoords[1].w = attrib->texcoord.w;
texcoords[2].x = attrib->texcoord.x1;
texcoords[2].y = attrib->texcoord.y2;
texcoords[2].z = attrib->texcoord.z;
texcoords[2].w = attrib->texcoord.w;
return array;
}
/*
* Helper to add a PIPE_CLEAR_* to batch->draws and batch->resolve together,
* meaning that we draw to a given target. Adding to only one mask does not

View file

@ -497,7 +497,8 @@ jm_emit_vertex_job(struct panfrost_batch *batch,
static void
jm_emit_tiler_draw(struct mali_draw_packed *out, struct panfrost_batch *batch,
bool fs_required, enum mesa_prim prim)
bool fs_required, enum mesa_prim prim,
struct pan_ptr *vertex_array)
{
struct panfrost_context *ctx = batch->ctx;
struct pipe_rasterizer_state *rast = &ctx->rasterizer->base;
@ -559,6 +560,13 @@ jm_emit_tiler_draw(struct mali_draw_packed *out, struct panfrost_batch *batch,
cfg.flags_0.aligned_line_ends = !rast->line_rectangular;
cfg.vertex_array.packet = true;
if (vertex_array) {
cfg.vertex_array.pointer = vertex_array->gpu;
cfg.vertex_array.vertex_packet_stride =
PAN_RUN_FULLSCREEN_PACKET_STRIDE;
cfg.vertex_array.vertex_attribute_stride =
PAN_RUN_FULLSCREEN_ATTRIB_STRIDE;
}
cfg.minimum_z = batch->minimum_z;
cfg.maximum_z = batch->maximum_z;
@ -804,7 +812,7 @@ jm_emit_malloc_vertex_job(struct panfrost_batch *batch,
}
jm_emit_tiler_draw(pan_section_ptr(job, MALLOC_VERTEX_JOB, DRAW), batch,
fs_required, u_reduced_prim(info->mode));
fs_required, u_reduced_prim(info->mode), NULL);
pan_section_pack(job, MALLOC_VERTEX_JOB, POSITION, cfg) {
jm_emit_shader_env(batch, &cfg, MESA_SHADER_VERTEX,
@ -852,7 +860,8 @@ jm_emit_tiler_job(struct panfrost_batch *batch,
;
#endif
jm_emit_tiler_draw(pan_section_ptr(job, TILER_JOB, DRAW), batch, true, prim);
jm_emit_tiler_draw(pan_section_ptr(job, TILER_JOB, DRAW), batch, true,
prim, NULL);
panfrost_emit_primitive_size(ctx, prim == MESA_PRIM_POINTS,
batch->varyings.psiz, prim_size);
@ -1025,7 +1034,44 @@ GENX(jm_launch_draw_fullscreen)(struct panfrost_batch *batch,
enum blitter_attrib_type type,
const struct blitter_attrib *attrib)
{
UNREACHABLE("draw fullscreen not implemented for jm");
#if PAN_ARCH == 9
PAN_TRACE_FUNC(PAN_TRACE_GL_JM);
struct pan_ptr job, dcd, vertex_array;
job = pan_pool_alloc_desc(&batch->pool.base, FULLSCREEN_JOB);
if (!job.cpu) {
mesa_loge("jm_launch_draw failed");
return;
}
dcd = pan_pool_alloc_desc(&batch->pool.base, DRAW);
if (!dcd.cpu) {
mesa_loge("jm_launch_draw failed");
return;
}
vertex_array = panfrost_emit_fullscreen_vertex_array(batch, type, attrib);
jm_emit_tiler_draw(dcd.cpu, batch, true, u_reduced_prim(MESA_PRIM_QUADS),
&vertex_array);
pan_section_pack(job.cpu, FULLSCREEN_JOB, PRIMITIVE, cfg) {
cfg.scissor_array_enable = false;
}
pan_section_pack(job.cpu, FULLSCREEN_JOB, DCD, cfg) {
cfg.address = dcd.gpu;
}
pan_section_pack(job.cpu, FULLSCREEN_JOB, TILER, cfg) {
cfg.address = jm_emit_tiler_desc(batch);
}
memcpy(pan_section_ptr(job.cpu, FULLSCREEN_JOB, SCISSOR), &batch->scissor,
pan_size(SCISSOR));
pan_jc_add_job(&batch->jm.jobs.vtc_jc, MALI_JOB_TYPE_FULLSCREEN, false,
false, 0, 0, &job, false);
#else
UNREACHABLE("draw fullscreen not available for arch < 9");
#endif
}
void

View file

@ -43,6 +43,7 @@
<value name="Fragment" value="9"/>
<value name="Indexed vertex" value="10"/>
<value name="Malloc vertex" value="11"/>
<value name="Fullscreen" value="12"/>
</enum>
<enum name="Shader stage">
@ -1558,10 +1559,8 @@
<struct name="Vertex Array" size="3">
<field name="Packet" size="1" start="0:0" type="bool"/>
<!-- Written by hardware in packet mode -->
<!-- Written by hardware in MallocVertexShader job mode -->
<field name="Pointer" size="58" start="0:6" type="address" modifier="shr(6)"/>
<!-- Written by hardware, leave zero -->
<field name="Vertex packet stride" size="16" start="2:0" type="uint"/>
<field name="Vertex attribute stride" size="16" start="2:16" type="uint"/>
</struct>
@ -1616,6 +1615,10 @@
<field name="Vertex attribute stride" start="0:16" size="16" type="uint"/>
</struct>
<struct name="DCD Pointer" size="2">
<field name="Address" size="64" start="0:0" type="address"/>
</struct>
<struct name="Tiler Pointer" size="2">
<field name="Address" size="64" start="0:0" type="address"/>
</struct>
@ -1643,6 +1646,14 @@
<section name="Varying" offset="320" type="Shader Environment"/>
</aggregate>
<aggregate name="Fullscreen Job" size="128" align="128">
<section name="Header" offset="0" type="Job Header"/>
<section name="Primitive" offset="32" type="Primitive"/>
<section name="DCD" offset="48" type="DCD Pointer"/>
<section name="Tiler" offset="56" type="Tiler Pointer"/>
<section name="Scissor" offset="104" type="Scissor"/>
</aggregate>
<aggregate name="Tiler Job" size="256" align="128">
<section name="Header" offset="0" type="Job Header"/>
<section name="Primitive" offset="32" type="Primitive"/>

View file

@ -114,7 +114,8 @@ static inline bool
job_uses_tiling(enum mali_job_type type)
{
#if PAN_ARCH >= 9
if (type == MALI_JOB_TYPE_MALLOC_VERTEX)
if (type == MALI_JOB_TYPE_MALLOC_VERTEX ||
type == MALI_JOB_TYPE_FULLSCREEN)
return true;
#endif