return;
if (device->quirks & IS_BIFROST) {
- struct bifrost_texture_descriptor *descriptors;
+ struct panfrost_transfer T = panfrost_pool_alloc(&batch->pool,
+ MALI_BIFROST_TEXTURE_LENGTH *
+ ctx->sampler_view_count[stage]);
- descriptors = malloc(sizeof(struct bifrost_texture_descriptor) *
- ctx->sampler_view_count[stage]);
+ struct mali_bifrost_texture_packed *out =
+ (struct mali_bifrost_texture_packed *) T.cpu;
for (int i = 0; i < ctx->sampler_view_count[stage]; ++i) {
struct panfrost_sampler_view *view = ctx->sampler_views[stage][i];
struct pipe_sampler_view *pview = &view->base;
struct panfrost_resource *rsrc = pan_resource(pview->texture);
+
panfrost_update_sampler_view(view, &ctx->base);
+ out[i] = view->bifrost_descriptor;
/* Add the BOs to the job so they are retained until the job is done. */
panfrost_batch_add_bo(batch, view->bo,
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ |
panfrost_bo_access_for_stage(stage));
-
- memcpy(&descriptors[i], view->bifrost_descriptor, sizeof(*view->bifrost_descriptor));
}
- postfix->textures = panfrost_pool_upload(&batch->pool,
- descriptors,
- sizeof(struct bifrost_texture_descriptor) *
- ctx->sampler_view_count[stage]);
-
- free(descriptors);
+ postfix->textures = T.gpu;
} else {
uint64_t trampolines[PIPE_MAX_SHADER_SAMPLER_VIEWS];
so->bo = panfrost_bo_create(device, size, 0);
- so->bifrost_descriptor = rzalloc(pctx, struct bifrost_texture_descriptor);
panfrost_new_texture_bifrost(
- so->bifrost_descriptor,
+ &so->bifrost_descriptor,
texture->width0, texture->height0,
depth, array_size,
format,
pipe_resource_reference(&pview->texture, NULL);
panfrost_bo_unreference(view->bo);
- if (view->bifrost_descriptor)
- ralloc_free(view->bifrost_descriptor);
ralloc_free(view);
}
struct panfrost_sampler_view {
struct pipe_sampler_view base;
struct panfrost_bo *bo;
- struct bifrost_texture_descriptor *bifrost_descriptor;
+ struct mali_bifrost_texture_packed bifrost_descriptor;
mali_ptr texture_bo;
uint64_t modifier;
};
/* For each pointer, there is an address and optionally also a stride */
#define MAX_ELEMENTS (2)
-/* While Midgard texture descriptors are variable length, Bifrost descriptors
- * are fixed like samplers with more pointers to expand if necessary */
-
-struct bifrost_texture_descriptor {
- unsigned format_unk : 4; /* 2 */
- enum mali_texture_dimension type : 2;
- unsigned zero : 4;
- unsigned format_swizzle : 12;
- enum mali_format format : 8;
- unsigned srgb : 1;
- unsigned format_unk3 : 1; /* 0 */
-
- uint16_t width; /* MALI_POSITIVE */
- uint16_t height; /* MALI_POSITIVE */
-
- /* OpenGL swizzle */
- unsigned swizzle : 12;
- enum mali_texture_layout layout : 4;
- uint8_t levels : 8; /* Number of levels-1 if mipmapped, 0 if not */
- unsigned unk1 : 8;
-
- unsigned levels_unk : 24; /* 0 */
- unsigned level_2 : 8; /* Number of levels, again? */
-
- mali_ptr payload;
-
- uint16_t array_size;
- uint16_t unk4;
-
- uint16_t depth;
- uint16_t unk5;
-} __attribute__((packed));
-
/* Used for lod encoding. Thanks @urjaman for pointing out these routines can
* be cleaned up a lot. */
static void
pandecode_bifrost_texture(
- const struct bifrost_texture_descriptor *t,
+ const void *cl,
unsigned job_no,
unsigned tex)
{
- pandecode_log("struct bifrost_texture_descriptor texture_descriptor_%d_%d = {\n", job_no, tex);
- pandecode_indent++;
-
- pandecode_prop("format_unk = 0x%" PRIx32, t->format_unk);
- pandecode_prop("type = %" PRId32, t->type);
-
- if (t->zero) {
- pandecode_msg("XXX: zero tripped\n");
- pandecode_prop("zero = 0x%" PRIx32, t->zero);
- }
-
- pandecode_prop("format_swizzle = 0x%" PRIx32, t->format_swizzle);
- pandecode_prop("format = 0x%" PRIx32, t->format);
- pandecode_prop("srgb = 0x%" PRIx32, t->srgb);
- pandecode_prop("format_unk3 = 0x%" PRIx32, t->format_unk3);
- pandecode_prop("width = %" PRId32, t->width);
- pandecode_prop("height = %" PRId32, t->height);
- pandecode_prop("swizzle = 0x%" PRIx32, t->swizzle);
- pandecode_prop("levels = %" PRId32, t->levels);
- pandecode_prop("unk1 = 0x%" PRIx32, t->unk1);
- pandecode_prop("levels_unk = %" PRId32, t->levels_unk);
- pandecode_prop("level_2 = %" PRId32, t->level_2);
- pandecode_prop("payload = 0x%" PRIx64, t->payload);
- pandecode_prop("array_size = %" PRId32, t->array_size);
- pandecode_prop("unk4 = 0x%" PRIx32, t->unk4);
- pandecode_prop("depth = %" PRId32, t->depth);
- pandecode_prop("unk5 = 0x%" PRIx32, t->unk5);
- pandecode_log("\n");
-
- bool is_cube = t->type == MALI_TEXTURE_DIMENSION_CUBE;
- unsigned dimension = is_cube ? 2 : t->type;
-
- /* Print the layout. Default is linear; a modifier can denote AFBC or
- * u-interleaved/tiled modes */
-
- if (t->layout == MALI_TEXTURE_LAYOUT_AFBC)
- pandecode_log_cont("afbc");
- else if (t->layout == MALI_TEXTURE_LAYOUT_TILED)
- pandecode_log_cont("tiled");
- else if (t->layout == MALI_TEXTURE_LAYOUT_LINEAR)
- pandecode_log_cont("linear");
- else
- pandecode_msg("XXX: invalid texture layout 0x%X\n", t->layout);
-
- pandecode_swizzle(t->swizzle, t->format);
- pandecode_log_cont(" ");
-
- /* Distinguish cube/2D with modifier */
-
- if (is_cube)
- pandecode_log_cont("cube ");
-
- pandecode_format_short(t->format, t->srgb);
-
- /* All four width/height/depth/array_size dimensions are present
- * regardless of the type of texture, but it is an error to have
- * non-zero dimensions for unused dimensions. Verify this. array_size
- * can always be set, as can width. */
-
- if (t->height && dimension < 2)
- pandecode_msg("XXX: nonzero height for <2D texture\n");
-
- if (t->depth && dimension < 3)
- pandecode_msg("XXX: nonzero depth for <2D texture\n");
-
- /* Print only the dimensions that are actually there */
-
- pandecode_log_cont(": %d", t->width + 1);
-
- if (dimension >= 2)
- pandecode_log_cont("x%u", t->height + 1);
-
- if (dimension >= 3)
- pandecode_log_cont("x%u", t->depth + 1);
-
- if (t->array_size)
- pandecode_log_cont("[%u]", t->array_size + 1);
+ struct MALI_BIFROST_TEXTURE temp;
+ MALI_BIFROST_TEXTURE_unpack(cl, &temp);
+ MALI_BIFROST_TEXTURE_print(pandecode_dump_stream, &temp, 2);
- if (t->levels)
- pandecode_log_cont(" mip %u", t->levels);
-
- pandecode_log_cont("\n");
-
- struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(t->payload);
- if (t->payload) {
- pandecode_texture_payload(t->payload, t->type, t->layout,
- true, t->levels, t->depth,
- t->array_size, tmem);
- }
-
- pandecode_indent--;
- pandecode_log("};\n");
+ struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(temp.surfaces);
+ pandecode_texture_payload(temp.surfaces, temp.dimension, temp.texel_ordering,
+ true, temp.levels, 1, 1, tmem);
}
/* For shader properties like texture_count, we have a claimed property in the shader_meta, and the actual Truth from static analysis (this may just be an upper limit). We validate accordingly */
if (!mmem)
return;
- if (is_bifrost) {
- const struct bifrost_texture_descriptor *PANDECODE_PTR_VAR(t, mmem, textures);
+ pandecode_log("Textures (%"PRIx64"):\n", textures);
- pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no);
- pandecode_indent++;
-
- for (unsigned tex = 0; tex < texture_count; ++tex)
- pandecode_bifrost_texture(&t[tex], job_no, tex);
+ if (is_bifrost) {
+ const void *cl = pandecode_fetch_gpu_mem(mmem,
+ textures, MALI_BIFROST_TEXTURE_LENGTH *
+ texture_count);
- pandecode_indent--;
- pandecode_log("};\n");
+ for (unsigned tex = 0; tex < texture_count; ++tex) {
+ pandecode_bifrost_texture(cl +
+ MALI_BIFROST_TEXTURE_LENGTH * tex,
+ job_no, tex);
+ }
} else {
mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures);
- pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no);
- pandecode_indent++;
-
for (int tex = 0; tex < texture_count; ++tex) {
mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
char *a = pointer_as_memory_reference(*u);
free(a);
}
- pandecode_indent--;
- pandecode_log("};\n");
-
/* Now, finally, descend down into the texture descriptor */
for (unsigned tex = 0; tex < texture_count; ++tex) {
mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
<field name="LOD bias" size="16" start="2:0" type="uint" default="0"/>
</struct>
+ <struct name="Bifrost Texture" size="8">
+ <field name="Type" size="4" start="0:0" type="uint" default="2"/>
+ <field name="Dimension" size="2" start="0:4" type="Texture Dimension"/>
+ <field name="Format" size="22" start="0:10" type="uint"/>
+ <field name="Width" size="16" start="1:0" type="uint" modifier="minus(1)"/>
+ <field name="Height" size="16" start="1:16" type="uint" modifier="minus(1)"/>
+ <field name="Swizzle" size="12" start="2:0" type="uint"/>
+ <field name="Texel ordering" size="4" start="2:12" type="Texture Layout"/>
+ <field name="Levels" size="5" start="2:16" type="uint"/>
+ <field name="Minimum LOD" size="13" start="3:0" type="uint" default="0"/>
+ <field name="Maximum LOD" size="13" start="3:16" type="uint" default="0"/>
+ <field name="Surfaces" size="64" start="4:0" type="address"/>
+ </struct>
+
<struct name="Stencil">
<field name="Reference Value" size="8" start="0" type="uint"/>
<field name="Mask" size="8" start="8" type="uint" default="0xFF"/>
void
panfrost_new_texture_bifrost(
- struct bifrost_texture_descriptor *descriptor,
+ struct mali_bifrost_texture_packed *out,
uint16_t width, uint16_t height,
uint16_t depth, uint16_t array_size,
enum pipe_format format,
base,
slices);
- descriptor->format_unk = 0x2;
- descriptor->type = dim;
- descriptor->format = mali_format;
- descriptor->srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
- descriptor->format_unk3 = 0x0;
- descriptor->width = MALI_POSITIVE(u_minify(width, first_level));
- descriptor->height = MALI_POSITIVE(u_minify(height, first_level));
- descriptor->swizzle = swizzle;
- descriptor->layout = panfrost_modifier_to_layout(modifier),
- descriptor->levels = last_level - first_level;
- descriptor->unk1 = 0x0;
- descriptor->levels_unk = 0;
- descriptor->level_2 = last_level - first_level;
- descriptor->payload = payload->gpu;
- descriptor->array_size = MALI_POSITIVE(array_size);
- descriptor->unk4 = 0x0;
- descriptor->depth = MALI_POSITIVE(u_minify(depth, first_level));
- descriptor->unk5 = 0x0;
+ bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
+
+ pan_pack(out, BIFROST_TEXTURE, cfg) {
+ cfg.dimension = dim;
+ cfg.format = (mali_format << 12) | (srgb << 20);
+ cfg.width = u_minify(width, first_level);
+ cfg.height = u_minify(height, first_level);
+ cfg.swizzle = swizzle;
+ cfg.texel_ordering = panfrost_modifier_to_layout(modifier);
+ cfg.levels = last_level - first_level;
+ cfg.surfaces = payload->gpu;
+
+ /* Use the sampler descriptor for LOD clamping */
+ cfg.minimum_lod = 0;
+ cfg.maximum_lod = last_level - first_level;
+ }
}
/* Computes sizes for checksumming, which is 8 bytes per 16x16 tile.
void
panfrost_new_texture_bifrost(
- struct bifrost_texture_descriptor *descriptor,
+ struct mali_bifrost_texture_packed *out,
uint16_t width, uint16_t height,
uint16_t depth, uint16_t array_size,
enum pipe_format format,