panfrost: The texture descriptor has a pointer to a trampoline
[mesa.git] / src / panfrost / encoder / pan_texture.c
index 147cf41c948acfb7e03fd1d3ed3a8156e9fd7c74..fe13a03eec4b38bf0e5860ce83c4dfbab4f90d18 100644 (file)
@@ -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));