diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index a837aaeb282..0d181945c9f 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -170,12 +170,14 @@ panfrost_shader_compile(struct panfrost_context *ctx,
}
/* Prepare the compiled binary for upload */
+ mali_ptr shader = 0;
+ unsigned attribute_count = 0, varying_count = 0;
int size = program.compiled.size;
if (size) {
state->bo = panfrost_bo_create(dev, size, PAN_BO_EXECUTE);
memcpy(state->bo->cpu, program.compiled.data, size);
- state->shader = state->bo->gpu;
+ shader = state->bo->gpu;
}
/* Midgard needs the first tag on the bottom nibble */
@@ -184,9 +186,9 @@ panfrost_shader_compile(struct panfrost_context *ctx,
/* If size = 0, we tag as "end-of-shader" */
if (size)
- state->shader |= program.first_tag;
+ shader |= program.first_tag;
else
- state->shader = 0x1;
+ shader = 0x1;
}
util_dynarray_fini(&program.compiled);
@@ -201,23 +203,21 @@ panfrost_shader_compile(struct panfrost_context *ctx,
state->reads_frag_coord = s->info.system_values_read & (1 << SYSTEM_VALUE_FRAG_COORD);
state->writes_global = s->info.writes_memory;
- state->texture_count = s->info.num_textures;
switch (stage) {
case MESA_SHADER_VERTEX:
- state->attribute_count = util_bitcount64(s->info.inputs_read);
- state->varying_count = util_bitcount64(s->info.outputs_written);
+ attribute_count = util_bitcount64(s->info.inputs_read);
+ varying_count = util_bitcount64(s->info.outputs_written);
if (vertex_id)
- state->attribute_count = MAX2(state->attribute_count, PAN_VERTEX_ID + 1);
+ attribute_count = MAX2(attribute_count, PAN_VERTEX_ID + 1);
if (instance_id)
- state->attribute_count = MAX2(state->attribute_count, PAN_INSTANCE_ID + 1);
+ attribute_count = MAX2(attribute_count, PAN_INSTANCE_ID + 1);
break;
case MESA_SHADER_FRAGMENT:
- state->attribute_count = 0;
- state->varying_count = util_bitcount64(s->info.inputs_read);
+ varying_count = util_bitcount64(s->info.inputs_read);
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
state->writes_depth = true;
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
@@ -239,8 +239,6 @@ panfrost_shader_compile(struct panfrost_context *ctx,
break;
case MESA_SHADER_COMPUTE:
/* TODO: images */
- state->attribute_count = 0;
- state->varying_count = 0;
state->shared_size = s->info.cs.shared_size;
break;
default:
@@ -284,6 +282,19 @@ panfrost_shader_compile(struct panfrost_context *ctx,
}
}
+ /* Prepare the descriptors at compile-time */
+ pan_pack(&state->shader, SHADER, cfg) {
+ cfg.shader = shader;
+ cfg.attribute_count = attribute_count;
+ cfg.varying_count = varying_count;
+ cfg.texture_count = s->info.num_textures;
+ cfg.sampler_count = cfg.texture_count;
+ }
+
+ /* Needed for linkage */
+ state->attribute_count = attribute_count;
+ state->varying_count = varying_count;
+
/* In both clone and tgsi_to_nir paths, the shader is ralloc'd against
* a NULL context */
ralloc_free(s);
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 34a3e8055e1..9a79846d5a0 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -315,11 +315,7 @@ panfrost_emit_compute_shader(struct panfrost_context *ctx,
struct panfrost_shader_state *ss = panfrost_get_shader_state(ctx, st);
memset(meta, 0, sizeof(*meta));
- meta->shader = ss->shader;
- meta->attribute_count = ss->attribute_count;
- meta->varying_count = ss->varying_count;
- meta->texture_count = ss->texture_count;
- meta->sampler_count = ss->texture_count; /* Combined on mesa/st */
+ memcpy(&meta->shader, &ss->shader, sizeof(ss->shader));
if (dev->quirks & IS_BIFROST) {
struct mali_bifrost_properties_packed prop;
@@ -554,6 +550,18 @@ panfrost_emit_blend(struct panfrost_batch *batch, void *rts,
}
}
+static struct mali_shader_packed
+panfrost_pack_shaderless(bool midgard)
+{
+ struct mali_shader_packed pack;
+
+ pan_pack(&pack, SHADER, cfg) {
+ cfg.shader = midgard ? 0x1 : 0x0;
+ }
+
+ return pack;
+}
+
static void
panfrost_emit_frag_shader(struct panfrost_context *ctx,
struct mali_shader_meta *fragmeta,
@@ -569,12 +577,7 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
memset(fragmeta, 0, sizeof(*fragmeta));
-
- fragmeta->shader = fs->shader;
- fragmeta->attribute_count = fs->attribute_count;
- fragmeta->varying_count = fs->varying_count;
- fragmeta->texture_count = fs->texture_count;
- fragmeta->sampler_count = fs->texture_count; /* Combined on mesa/st */
+ memcpy(&fragmeta->shader, &fs->shader, sizeof(fs->shader));
if (dev->quirks & IS_BIFROST) {
struct mali_bifrost_properties_packed prop;
@@ -698,23 +701,19 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
/* Disable shader execution if we can */
if (!panfrost_fs_required(fs, blend, rt_count)) {
- fragmeta->attribute_count = 0;
- fragmeta->varying_count = 0;
- fragmeta->texture_count = 0;
- fragmeta->sampler_count = 0;
+ struct mali_shader_packed shader =
+ panfrost_pack_shaderless(!(dev->quirks & IS_BIFROST));
+
+ memcpy(&fragmeta->shader, &shader, sizeof(shader));
struct mali_midgard_properties_packed prop;
if (dev->quirks & IS_BIFROST) {
- fragmeta->shader = 0x0;
-
pan_pack(&prop, BIFROST_PROPERTIES, cfg) {
cfg.unknown = 0x950020; /* XXX */
cfg.early_z_enable = true;
}
} else {
- fragmeta->shader = 0x1;
-
pan_pack(&prop, MIDGARD_PROPERTIES, cfg) {
cfg.work_register_count = 1;
cfg.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 8fb6c3a3ad1..794978c8181 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -183,12 +183,11 @@ struct panfrost_rasterizer {
struct panfrost_shader_state {
/* Compiled, mapped descriptor, ready for the hardware */
bool compiled;
+ struct mali_shader_packed shader;
/* Non-descript information */
unsigned uniform_count;
unsigned work_reg_count;
- unsigned attribute_count;
- unsigned texture_count;
bool can_discard;
bool writes_point_size;
bool writes_depth;
@@ -207,7 +206,7 @@ struct panfrost_shader_state {
/* For Bifrost - output type for each RT */
enum bifrost_shader_type blend_types[BIFROST_MAX_RENDER_TARGET_COUNT];
- unsigned int varying_count;
+ unsigned attribute_count, varying_count;
enum mali_format varyings[PIPE_MAX_ATTRIBS];
gl_varying_slot varyings_loc[PIPE_MAX_ATTRIBS];
struct pipe_stream_output_info stream_output;
@@ -222,9 +221,7 @@ struct panfrost_shader_state {
/* Should we enable helper invocations */
bool helper_invocations;
- /* Pointer to GPU-executable memory formatted for the hardware. bo->gpu
- * on Bifrost, bo->gpu | initial_tag on Midgard */
- mali_ptr shader;
+ /* GPU-executable memory */
struct panfrost_bo *bo;
BITSET_WORD outputs_read;
diff --git a/src/panfrost/bifrost/test/bi_submit.c b/src/panfrost/bifrost/test/bi_submit.c
index 542ed72c16c..2bccbb578ec 100644
--- a/src/panfrost/bifrost/test/bi_submit.c
+++ b/src/panfrost/bifrost/test/bi_submit.c
@@ -172,9 +172,12 @@ bit_vertex(struct panfrost_device *dev, panfrost_program prog,
memcpy(shmem->cpu, &shmemp, sizeof(shmemp));
struct mali_shader_meta meta = {
- .shader = shader->gpu,
- .attribute_count = 1,
- .varying_count = 1,
+ .shader = { .opaque = {
+ (uint32_t) shader->gpu & 0xFFFFFFFF, /* PC lo */
+ (uint32_t) (shader->gpu >> 32ull), /* PC hi */
+ (uint32_t) (1 << 16) | 1, /* attr/vary */
+ (uint32_t) 0, /* tex/sampl */
+ } },
.bifrost_props = { .opaque = { 0x80020001 } },
.bifrost_preload = { .opaque = { (sz_ubo / 16) << 15 } },
};
diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h
index 18dbb95ed96..c99743bfa25 100644
--- a/src/panfrost/include/panfrost-job.h
+++ b/src/panfrost/include/panfrost-job.h
@@ -296,11 +296,7 @@ struct bifrost_blend_rt {
* descriptors for each active render target */
struct mali_shader_meta {
- mali_ptr shader;
- u16 sampler_count;
- u16 texture_count;
- u16 attribute_count;
- u16 varying_count;
+ struct mali_shader_packed shader;
union {
struct mali_bifrost_properties_packed bifrost_props;
diff --git a/src/panfrost/lib/decode.c b/src/panfrost/lib/decode.c
index 6a235504622..9f4a5f2529f 100644
--- a/src/panfrost/lib/decode.c
+++ b/src/panfrost/lib/decode.c
@@ -1726,21 +1726,26 @@ pandecode_vertex_tiler_postfix_pre(
.uniform_buffer_count = 0
};
- if (s->shader & ~0xF)
- info = pandecode_shader_disassemble(s->shader & ~0xF, job_no, job_type, is_bifrost, gpu_id);
-
+ struct MALI_SHADER shader;
struct MALI_MIDGARD_PROPERTIES midg_props;
struct MALI_BIFROST_PROPERTIES bi_props;
struct MALI_PRELOAD bi_preload;
+ struct mali_shader_packed shader_packed = s->shader;
+ MALI_SHADER_unpack((const uint8_t *) &shader_packed, &shader);
+
+ if (shader.shader & ~0xF)
+ info = pandecode_shader_disassemble(shader.shader & ~0xF, job_no, job_type, is_bifrost, gpu_id);
+
+
pandecode_log("struct mali_shader_meta shader_meta_%"PRIx64"_%d%s = {\n", p->shader, job_no, suffix);
pandecode_indent++;
/* Save for dumps */
- attribute_count = s->attribute_count;
- varying_count = s->varying_count;
- texture_count = s->texture_count;
- sampler_count = s->sampler_count;
+ attribute_count = shader.attribute_count;
+ varying_count = shader.varying_count;
+ texture_count = shader.texture_count;
+ sampler_count = shader.sampler_count;
if (is_bifrost) {
uint32_t opaque = s->bifrost_props.opaque[0];
@@ -1759,12 +1764,12 @@ pandecode_vertex_tiler_postfix_pre(
uniform_buffer_count = midg_props.uniform_buffer_count;
}
- pandecode_shader_address("shader", s->shader);
+ pandecode_shader_address("shader", shader.shader);
- pandecode_shader_prop("texture_count", s->texture_count, info.texture_count, false);
- pandecode_shader_prop("sampler_count", s->sampler_count, info.sampler_count, false);
- pandecode_shader_prop("attribute_count", s->attribute_count, info.attribute_count, false);
- pandecode_shader_prop("varying_count", s->varying_count, info.varying_count, false);
+ pandecode_shader_prop("texture_count", texture_count, info.texture_count, false);
+ pandecode_shader_prop("sampler_count", sampler_count, info.sampler_count, false);
+ pandecode_shader_prop("attribute_count", attribute_count, info.attribute_count, false);
+ pandecode_shader_prop("varying_count", varying_count, info.varying_count, false);
if (is_bifrost)
MALI_BIFROST_PROPERTIES_print(pandecode_dump_stream, &bi_props, 2);
diff --git a/src/panfrost/lib/midgard.xml b/src/panfrost/lib/midgard.xml
index d6fa7e4a134..08615b15f97 100644
--- a/src/panfrost/lib/midgard.xml
+++ b/src/panfrost/lib/midgard.xml
@@ -395,6 +395,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/panfrost/lib/pan_blit.c b/src/panfrost/lib/pan_blit.c
index d7c178949c9..59a026850ba 100644
--- a/src/panfrost/lib/pan_blit.c
+++ b/src/panfrost/lib/pan_blit.c
@@ -244,11 +244,19 @@ panfrost_load_midg(
bool ms = image->nr_samples > 1;
+ struct mali_shader_packed shader;
+
+ pan_pack(&shader, SHADER, cfg) {
+ cfg.shader = pool->dev->blit_shaders.loads[loc][T][ms];
+ cfg.varying_count = 1;
+ cfg.texture_count = 1;
+ cfg.sampler_count = 1;
+
+ assert(cfg.shader);
+ }
+
struct mali_shader_meta shader_meta = {
- .shader = pool->dev->blit_shaders.loads[loc][T][ms],
- .sampler_count = 1,
- .texture_count = 1,
- .varying_count = 1,
+ .shader = shader,
.coverage_mask = ~0,
.unknown2_3 = MALI_DEPTH_FUNC(MALI_FUNC_ALWAYS) | 0x10,
.unknown2_4 = 0x4e0,
@@ -279,8 +287,6 @@ panfrost_load_midg(
else
shader_meta.unknown2_4 |= MALI_NO_MSAA;
- assert(shader_meta.shader);
-
if (pool->dev->quirks & MIDGARD_SFBD) {
shader_meta.unknown2_4 |= (0x10 | MALI_NO_DITHER);
shader_meta.blend = replace;