File: v3d_cl.h

package info (click to toggle)
intel-gpu-tools 2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 62,024 kB
  • sloc: xml: 769,439; ansic: 348,692; python: 8,307; yacc: 2,781; perl: 1,196; sh: 1,178; lex: 487; asm: 227; makefile: 27; lisp: 11
file content (139 lines) | stat: -rw-r--r-- 3,503 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2019 Raspberry Pi Ltd
 */

#ifndef V3D_CL_H
#define V3D_CL_H

#include "v3d_packet_helpers.h"
#include "igt_v3d.h"

/**
 * Undefined structure, used for typechecking that you're passing the pointers
 * to these functions correctly.
 */
struct v3d_cl_out;

/** A reference to a BO used in the CL packing functions */
struct v3d_cl_reloc {
	struct v3d_bo *bo;
	uint32_t offset;
};

#define __gen_user_data struct v3d_cl
#define __gen_address_type struct v3d_cl_reloc
#define __gen_address_offset(reloc) (((reloc)->bo ? (reloc)->bo->offset : 0) + \
				     (reloc)->offset)
#define __gen_emit_reloc cl_pack_emit_reloc
#define __gen_unpack_address(cl, s, e) __unpack_address(cl, s, e)

struct v3d_cl {
	void *base;
	struct v3d_cl_out *next;
	struct v3d_bo *bo;
	uint32_t size;
};

static inline struct v3d_cl_reloc
__unpack_address(const uint8_t *cl, uint32_t s, uint32_t e)
{
	struct v3d_cl_reloc reloc = {
		NULL, __gen_unpack_uint(cl, s, e) << (31 - (e - s)) };
	return reloc;
}

static inline uint32_t
v3d_cl_offset(struct v3d_cl *cl)
{
	return (char *)cl->next - (char *)cl->base;
}

static inline struct v3d_cl_reloc
v3d_cl_address(struct v3d_bo *bo, uint32_t offset)
{
	struct v3d_cl_reloc reloc = {
		.bo = bo,
		.offset = offset,
	};
	return reloc;
}

static inline struct v3d_cl_reloc
v3d_cl_get_address(struct v3d_cl *cl)
{
	return (struct v3d_cl_reloc){ .bo = cl->bo, .offset = v3d_cl_offset(cl) };
}

static inline struct v3d_cl_out *
cl_start(struct v3d_cl *cl)
{
	return cl->next;
}

static inline void
cl_end(struct v3d_cl *cl, struct v3d_cl_out *next)
{
	cl->next = next;
	assert(v3d_cl_offset(cl) <= cl->size);
}

static inline void
cl_advance(struct v3d_cl_out **cl, uint32_t n)
{
	(*cl) = (struct v3d_cl_out *)((char *)(*cl) + n);
}

#define V3DX(x) V3D42_##x
#define v3dX(x) V3D42_##x

#define cl_packet_header(packet) V3DX(packet ## _header)
#define cl_packet_length(packet) V3DX(packet ## _length)
#define cl_packet_pack(packet)   V3DX(packet ## _pack)
#define cl_packet_struct(packet) V3DX(packet)

/* Macro for setting up an emit of a CL struct.  A temporary unpacked struct
 * is created, which you get to set fields in of the form:
 *
 * cl_emit(bcl, FLAT_SHADE_FLAGS, flags) {
 *     .flags.flat_shade_flags = 1 << 2,
 * }
 *
 * or default values only can be emitted with just:
 *
 * cl_emit(bcl, FLAT_SHADE_FLAGS, flags);
 *
 * The trick here is that we make a for loop that will execute the body
 * (either the block or the ';' after the macro invocation) exactly once.
 */
#define cl_emit(cl, packet, name)					\
	for (struct cl_packet_struct(packet) name = {			\
		cl_packet_header(packet)				\
	},								\
	*_loop_terminate = &name;					\
	__builtin_expect(_loop_terminate != NULL, 1);			\
	({								\
		struct v3d_cl_out *cl_out = cl_start(cl);		\
		cl_packet_pack(packet)(cl, (uint8_t *)cl_out, &name);	\
		cl_advance(&cl_out, cl_packet_length(packet));		\
		cl_end(cl, cl_out);					\
		_loop_terminate = NULL;					\
	}))								\

/*
 * Helper function called by the XML-generated pack functions for filling in
 * an address field in shader records.
 *
 * Since we have a private address space as of V3D, our BOs can have lifelong
 * offsets, and all the kernel needs to know is which BOs need to be paged in
 * for this exec.
 */
static inline void
cl_pack_emit_reloc(struct v3d_cl *cl, const struct v3d_cl_reloc *reloc)
{
	/*
	 * Mock emit reloc, as it is not needed for IGT tests.
	 */
}

#endif /* V3D_CL_H */