allocate.c 2.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * © Copyright 2018 The Panfrost Community
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pandev.h"

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
20 21 22
/* TODO: What does this actually have to be? */
#define ALIGNMENT 128

23 24 25
// TODO: An actual allocator, perhaps
// TODO: Multiple stacks for multiple bases?

26
int stack_bottom = 4096; /* Don't interfere with constant offsets */
27
int last_offset = 0;
28

29 30
int
pandev_allocate_offset(int *stack, size_t sz)
31
{
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
32 33 34 35 36 37 38 39 40 41 42 43
	/* First, align the stack bottom to something nice; it's not critical
	 * at this point if we waste a little space to do so. */

	int excess = *stack & (ALIGNMENT - 1);

	/* Add the secret of my */
	if (excess)
		*stack += ALIGNMENT - excess;

	/* Finally, use the new bottom for the allocation and move down the
	 * stack */

44
	int ret = *stack;
45
	*stack += sz;
46 47 48
	return ret;
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
49
mali_ptr
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
50
pandev_upload(int cheating_offset, mali_ptr base, void *base_map, void *data, size_t sz, bool no_pad)
51
{
52
	int offset;
53

54
	/* We're not positive about the sizes of all objects, but we don't want
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
55 56
	 * them to crash against each other either. Let the caller disable
	 * padding if they so choose, though. */
57

58
	size_t padded_size = no_pad ? sz : sz * 2;
59

60 61 62
	/* Allocate space for the new GPU object, if required */

	if (cheating_offset == -1) {
63
		offset = pandev_allocate_offset(&stack_bottom, padded_size);
64 65 66
	} else {
		offset = cheating_offset;
	}
67

68 69 70
	/* Save last offset for sequential uploads (job descriptors) */
	last_offset = offset + padded_size;

71 72
	/* Upload it, with a canary for safety */
	if (cheating_offset == -1) memset(base_map + offset, 0, padded_size);
73
	memcpy(base_map + offset, data, sz);
74
	if (cheating_offset == -1) memset(base_map + offset + padded_size, 0xFFFFFFFF, 32);
75 76 77 78 79

	/* Return the GPU address */
	return base + offset;
}

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
80 81 82 83
/* Upload immediately after the last allocation */

mali_ptr
pandev_upload_sequential(mali_ptr base, void *base_map, void *data, size_t sz) {
84
	return pandev_upload(last_offset, base, base_map, data, sz, false);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
85
}