From a3d2936a8e9e1c263e5d18b6832c238e7aa6700e Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 21 Apr 2020 16:08:07 -0400 Subject: [PATCH] panfrost: The texture descriptor has a pointer to a trampoline Not to the texture itself, and can have a stride right after for linear textures. Signed-off-by: Alyssa Rosenzweig Signed-off-by: Tomeu Vizoso Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_context.c | 23 ++++- src/gallium/drivers/panfrost/pan_context.h | 1 + src/panfrost/encoder/pan_texture.c | 108 +++++++++++++------ src/panfrost/encoder/pan_texture.h | 6 +- src/panfrost/pandecode/decode.c | 115 ++++++++++++--------- 5 files changed, 168 insertions(+), 85 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index d8bcdd28fa5..1a87a7bf014 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -930,6 +930,20 @@ panfrost_create_sampler_view( panfrost_translate_texture_type(template->target); if (device->quirks & IS_BIFROST) { + const struct util_format_description *desc = + util_format_description(template->format); + unsigned char composed_swizzle[4]; + util_format_compose_swizzles(desc->swizzle, user_swizzle, composed_swizzle); + + unsigned size = panfrost_estimate_texture_payload_size( + template->u.tex.first_level, + template->u.tex.last_level, + template->u.tex.first_layer, + template->u.tex.last_layer, + type, prsrc->layout); + + so->bifrost_bo = pan_bo_create(device, size, 0); + so->bifrost_descriptor = rzalloc(pctx, struct bifrost_texture_descriptor); panfrost_new_texture_bifrost( so->bifrost_descriptor, @@ -942,16 +956,18 @@ panfrost_create_sampler_view( template->u.tex.first_layer, template->u.tex.last_layer, prsrc->cubemap_stride, - panfrost_translate_swizzle_4(user_swizzle), + panfrost_translate_swizzle_4(composed_swizzle), prsrc->bo->gpu, - prsrc->slices); + prsrc->slices, + so->bifrost_bo); } else { - unsigned size = panfrost_estimate_texture_size( + unsigned size = panfrost_estimate_texture_payload_size( template->u.tex.first_level, template->u.tex.last_level, template->u.tex.first_layer, template->u.tex.last_layer, type, prsrc->layout); + size += sizeof(struct mali_texture_descriptor); so->midgard_bo = pan_bo_create(device, size, 0); @@ -1010,6 +1026,7 @@ panfrost_sampler_view_destroy( pipe_resource_reference(&pview->texture, NULL); panfrost_bo_unreference(view->midgard_bo); + panfrost_bo_unreference(view->bifrost_bo); if (view->bifrost_descriptor) ralloc_free(view->bifrost_descriptor); ralloc_free(view); diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 7a4315036f9..d43c202a855 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -257,6 +257,7 @@ struct panfrost_sampler_state { struct panfrost_sampler_view { struct pipe_sampler_view base; struct panfrost_bo *midgard_bo; + struct panfrost_bo *bifrost_bo; struct bifrost_texture_descriptor *bifrost_descriptor; }; diff --git a/src/panfrost/encoder/pan_texture.c b/src/panfrost/encoder/pan_texture.c index 147cf41c948..fe13a03eec4 100644 --- a/src/panfrost/encoder/pan_texture.c +++ b/src/panfrost/encoder/pan_texture.c @@ -143,14 +143,14 @@ panfrost_texture_num_elements( return num_elements; } -/* Conservative estimate of the size of the texture descriptor a priori. +/* Conservative estimate of the size of the texture payload a priori. * Average case, size equal to the actual size. Worst case, off by 2x (if * a manual stride is not needed on a linear texture). Returned value * must be greater than or equal to the actual size, so it's safe to use * as an allocation amount */ unsigned -panfrost_estimate_texture_size( +panfrost_estimate_texture_payload_size( unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, enum mali_texture_type type, enum mali_texture_layout layout) @@ -163,8 +163,49 @@ panfrost_estimate_texture_size( first_layer, last_layer, type == MALI_TEX_CUBE, manual_stride); - return sizeof(struct mali_texture_descriptor) + - sizeof(mali_ptr) * elements; + return sizeof(mali_ptr) * elements; +} + +static void +panfrost_emit_texture_payload( + mali_ptr *payload, + const struct util_format_description *desc, + enum mali_format mali_format, + enum mali_texture_type type, + enum mali_texture_layout layout, + unsigned first_level, unsigned last_level, + unsigned first_layer, unsigned last_layer, + unsigned cube_stride, + bool manual_stride, + mali_ptr base, + struct panfrost_slice *slices) +{ + base |= panfrost_compression_tag(desc, mali_format, layout); + + /* Inject the addresses in, interleaving array indices, mip levels, + * cube faces, and strides in that order */ + + unsigned first_face = 0, last_face = 0, face_mult = 1; + + if (type == MALI_TEX_CUBE) { + face_mult = 6; + panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer); + } + + unsigned idx = 0; + + for (unsigned w = first_layer; w <= last_layer; ++w) { + for (unsigned l = first_level; l <= last_level; ++l) { + for (unsigned f = first_face; f <= last_face; ++f) { + payload[idx++] = base + panfrost_texture_offset( + slices, type == MALI_TEX_3D, + cube_stride, l, w * face_mult + f); + + if (manual_stride) + payload[idx++] = slices[l].stride; + } + } + } } void @@ -213,33 +254,19 @@ panfrost_new_texture( memcpy(out, &descriptor, sizeof(descriptor)); - base |= panfrost_compression_tag(desc, mali_format, layout); - - /* Inject the addresses in, interleaving array indices, mip levels, - * cube faces, and strides in that order */ - - unsigned first_face = 0, last_face = 0, face_mult = 1; - - if (type == MALI_TEX_CUBE) { - face_mult = 6; - panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer); - } - mali_ptr *payload = (mali_ptr *) (out + sizeof(struct mali_texture_descriptor)); - unsigned idx = 0; - - for (unsigned w = first_layer; w <= last_layer; ++w) { - for (unsigned l = first_level; l <= last_level; ++l) { - for (unsigned f = first_face; f <= last_face; ++f) { - payload[idx++] = base + panfrost_texture_offset( - slices, type == MALI_TEX_3D, - cube_stride, l, w * face_mult + f); - - if (manual_stride) - payload[idx++] = slices[l].stride; - } - } - } + panfrost_emit_texture_payload( + payload, + desc, + mali_format, + type, + layout, + first_level, last_level, + first_layer, last_layer, + cube_stride, + manual_stride, + base, + slices); } void @@ -255,13 +282,30 @@ panfrost_new_texture_bifrost( unsigned cube_stride, unsigned swizzle, mali_ptr base, - struct panfrost_slice *slices) + struct panfrost_slice *slices, + struct panfrost_bo *payload) { const struct util_format_description *desc = util_format_description(format); enum mali_format mali_format = panfrost_find_format(desc); + /* Apparently it's always needed in Bifrost? */ + bool manual_stride = true; + + panfrost_emit_texture_payload( + (mali_ptr *) payload->cpu, + desc, + mali_format, + type, + layout, + first_level, last_level, + first_layer, last_layer, + cube_stride, + manual_stride, + base, + slices); + descriptor->format_unk = 0x2; descriptor->type = type; descriptor->format_unk2 = 0x100; @@ -276,7 +320,7 @@ panfrost_new_texture_bifrost( descriptor->unk1 = 0x0; descriptor->levels_unk = 0; descriptor->level_2 = 0; - descriptor->payload = base; + descriptor->payload = payload->gpu; descriptor->array_size = MALI_POSITIVE(array_size); descriptor->unk4 = 0x0; descriptor->depth = MALI_POSITIVE(u_minify(depth, first_level)); diff --git a/src/panfrost/encoder/pan_texture.h b/src/panfrost/encoder/pan_texture.h index 77c0eaaf049..d049ada9fdc 100644 --- a/src/panfrost/encoder/pan_texture.h +++ b/src/panfrost/encoder/pan_texture.h @@ -31,6 +31,7 @@ #include #include "util/format/u_format.h" #include "panfrost-job.h" +#include "pan_bo.h" struct panfrost_slice { unsigned offset; @@ -67,7 +68,7 @@ panfrost_afbc_header_size(unsigned width, unsigned height); /* mali_texture_descriptor */ unsigned -panfrost_estimate_texture_size( +panfrost_estimate_texture_payload_size( unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, enum mali_texture_type type, enum mali_texture_layout layout); @@ -100,7 +101,8 @@ panfrost_new_texture_bifrost( unsigned cube_stride, unsigned swizzle, mali_ptr base, - struct panfrost_slice *slices); + struct panfrost_slice *slices, + struct panfrost_bo *payload); unsigned diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c index 73a5324951b..79ab9d953f8 100644 --- a/src/panfrost/pandecode/decode.c +++ b/src/panfrost/pandecode/decode.c @@ -1972,6 +1972,63 @@ pandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type, return stats; } +static void +pandecode_texture_payload(mali_ptr payload, + enum mali_texture_type type, + enum mali_texture_layout layout, + bool manual_stride, + uint8_t levels, + uint16_t depth, + uint16_t array_size, + struct pandecode_mapped_memory *tmem) +{ + pandecode_log(".payload = {\n"); + pandecode_indent++; + + /* A bunch of bitmap pointers follow. + * We work out the correct number, + * based on the mipmap/cubemap + * properties, but dump extra + * possibilities to futureproof */ + + int bitmap_count = levels + 1; + + /* Miptree for each face */ + if (type == MALI_TEX_CUBE) + bitmap_count *= 6; + else if (type == MALI_TEX_3D && layout == MALI_TEXTURE_LINEAR) + bitmap_count *= (depth + 1); + + /* Array of textures */ + bitmap_count *= (array_size + 1); + + /* Stride for each element */ + if (manual_stride) + bitmap_count *= 2; + + mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem, + payload, sizeof(mali_ptr) * bitmap_count); + for (int i = 0; i < bitmap_count; ++i) { + /* How we dump depends if this is a stride or a pointer */ + + if (manual_stride && (i & 1)) { + /* signed 32-bit snuck in as a 64-bit pointer */ + uint64_t stride_set = pointers_and_strides[i]; + uint32_t clamped_stride = stride_set; + int32_t stride = clamped_stride; + assert(stride_set == clamped_stride); + pandecode_log("(mali_ptr) %d /* stride */, \n", stride); + } else { + char *a = pointer_as_memory_reference(pointers_and_strides[i]); + pandecode_log("%s, \n", a); + free(a); + } + } + + pandecode_indent--; + pandecode_log("},\n"); +} + static void pandecode_texture(mali_ptr u, struct pandecode_mapped_memory *tmem, @@ -2096,58 +2153,17 @@ pandecode_texture(mali_ptr u, pandecode_prop("unknown7 = 0x%" PRIx32, t->unknown7); } - pandecode_log(".payload = {\n"); - pandecode_indent++; - - /* A bunch of bitmap pointers follow. - * We work out the correct number, - * based on the mipmap/cubemap - * properties, but dump extra - * possibilities to futureproof */ - - int bitmap_count = t->levels + 1; - - /* Miptree for each face */ - if (f.type == MALI_TEX_CUBE) - bitmap_count *= 6; - else if (f.type == MALI_TEX_3D && f.layout == MALI_TEXTURE_LINEAR) - bitmap_count *= (t->depth + 1); - - /* Array of textures */ - bitmap_count *= (t->array_size + 1); - - /* Stride for each element */ - if (f.manual_stride) - bitmap_count *= 2; - - mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem, - u + sizeof(*t), sizeof(mali_ptr) * bitmap_count); - for (int i = 0; i < bitmap_count; ++i) { - /* How we dump depends if this is a stride or a pointer */ - - if (f.manual_stride && (i & 1)) { - /* signed 32-bit snuck in as a 64-bit pointer */ - uint64_t stride_set = pointers_and_strides[i]; - uint32_t clamped_stride = stride_set; - int32_t stride = clamped_stride; - assert(stride_set == clamped_stride); - pandecode_log("(mali_ptr) %d /* stride */, \n", stride); - } else { - char *a = pointer_as_memory_reference(pointers_and_strides[i]); - pandecode_log("%s, \n", a); - free(a); - } - } - - pandecode_indent--; - pandecode_log("},\n"); + pandecode_texture_payload(u + sizeof(*t), f.type, f.layout, f.manual_stride, t->levels, t->depth, t->array_size, tmem); pandecode_indent--; pandecode_log("};\n"); } static void -pandecode_bifrost_texture(const struct bifrost_texture_descriptor *t, unsigned job_no, unsigned tex) +pandecode_bifrost_texture( + const struct bifrost_texture_descriptor *t, + unsigned job_no, + unsigned tex) { pandecode_log("struct bifrost_texture_descriptor texture_descriptor_%d_%d = {\n", job_no, tex); pandecode_indent++; @@ -2228,7 +2244,10 @@ pandecode_bifrost_texture(const struct bifrost_texture_descriptor *t, unsigned j pandecode_log_cont("\n"); - pandecode_prop("payload = 0x%" PRIx64, t->payload); + struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(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"); @@ -2360,7 +2379,7 @@ pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool i pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t)); pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r)); - if (s->unk1 != 8) { + if (s->unk1 != 0x8) { pandecode_msg("XXX: unk8 tripped\n"); pandecode_prop("unk8 = 0x%x", s->unk8); } -- 2.30.2