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)
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
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
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;
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));