freedreno/a6xx: Add ARB_depth_clamp and separate clamp support.
[mesa.git] / src / gallium / drivers / freedreno / a6xx / fd6_pack.h
1 /*
2 * Copyright © 2019 Google, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #ifndef FD6_PACK_H
25 #define FD6_PACK_H
26
27 #include "a6xx.xml.h"
28
29 struct fd_reg_pair {
30 uint32_t reg;
31 uint64_t value;
32 struct fd_bo *bo;
33 bool is_address;
34 bool bo_write;
35 uint32_t bo_offset;
36 uint32_t bo_shift;
37 };
38
39 #define __bo_type struct fd_bo *
40
41 #include "a6xx-pack.xml.h"
42 #include "adreno-pm4-pack.xml.h"
43
44 #define __assert_eq(a, b) \
45 do { \
46 if ((a) != (b)) { \
47 fprintf(stderr, "assert failed: " #a " (0x%x) != " #b " (0x%x)\n", a, b); \
48 assert((a) == (b)); \
49 } \
50 } while (0)
51
52 #define __ONE_REG(i, ...) \
53 do { \
54 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
55 /* NOTE: allow regs[0].reg==0, this happens in OUT_PKT() */ \
56 if (i < ARRAY_SIZE(regs) && (i == 0 || regs[i].reg > 0)) { \
57 __assert_eq(regs[0].reg + i, regs[i].reg); \
58 if (regs[i].bo) { \
59 struct fd_reloc reloc = { \
60 .bo = regs[i].bo, \
61 .offset = regs[i].bo_offset, \
62 .or = regs[i].value, \
63 .shift = regs[i].bo_shift, \
64 .orhi = regs[i].value >> 32 \
65 }; \
66 ring->cur = p; \
67 p += 2; \
68 fd_ringbuffer_reloc(ring, &reloc); \
69 } else { \
70 *p++ = regs[i].value; \
71 if (regs[i].is_address) \
72 *p++ = regs[i].value >> 32; \
73 } \
74 } \
75 } while (0)
76
77 #define OUT_REG(ring, ...) \
78 do { \
79 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
80 unsigned count = ARRAY_SIZE(regs); \
81 \
82 STATIC_ASSERT(count > 0); \
83 STATIC_ASSERT(count <= 16); \
84 \
85 BEGIN_RING(ring, count + 1); \
86 uint32_t *p = ring->cur; \
87 *p++ = CP_TYPE4_PKT | count | \
88 (_odd_parity_bit(count) << 7) | \
89 ((regs[0].reg & 0x3ffff) << 8) | \
90 ((_odd_parity_bit(regs[0].reg) << 27)); \
91 \
92 __ONE_REG( 0, __VA_ARGS__); \
93 __ONE_REG( 1, __VA_ARGS__); \
94 __ONE_REG( 2, __VA_ARGS__); \
95 __ONE_REG( 3, __VA_ARGS__); \
96 __ONE_REG( 4, __VA_ARGS__); \
97 __ONE_REG( 5, __VA_ARGS__); \
98 __ONE_REG( 6, __VA_ARGS__); \
99 __ONE_REG( 7, __VA_ARGS__); \
100 __ONE_REG( 8, __VA_ARGS__); \
101 __ONE_REG( 9, __VA_ARGS__); \
102 __ONE_REG(10, __VA_ARGS__); \
103 __ONE_REG(11, __VA_ARGS__); \
104 __ONE_REG(12, __VA_ARGS__); \
105 __ONE_REG(13, __VA_ARGS__); \
106 __ONE_REG(14, __VA_ARGS__); \
107 __ONE_REG(15, __VA_ARGS__); \
108 ring->cur = p; \
109 } while (0)
110
111 #define OUT_PKT(ring, opcode, ...) \
112 do { \
113 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
114 unsigned count = ARRAY_SIZE(regs); \
115 \
116 STATIC_ASSERT(count <= 16); \
117 \
118 BEGIN_RING(ring, count + 1); \
119 uint32_t *p = ring->cur; \
120 *p++ = CP_TYPE7_PKT | count | \
121 (_odd_parity_bit(count) << 15) | \
122 ((opcode & 0x7f) << 16) | \
123 ((_odd_parity_bit(opcode) << 23)); \
124 \
125 __ONE_REG( 0, __VA_ARGS__); \
126 __ONE_REG( 1, __VA_ARGS__); \
127 __ONE_REG( 2, __VA_ARGS__); \
128 __ONE_REG( 3, __VA_ARGS__); \
129 __ONE_REG( 4, __VA_ARGS__); \
130 __ONE_REG( 5, __VA_ARGS__); \
131 __ONE_REG( 6, __VA_ARGS__); \
132 __ONE_REG( 7, __VA_ARGS__); \
133 __ONE_REG( 8, __VA_ARGS__); \
134 __ONE_REG( 9, __VA_ARGS__); \
135 __ONE_REG(10, __VA_ARGS__); \
136 __ONE_REG(11, __VA_ARGS__); \
137 __ONE_REG(12, __VA_ARGS__); \
138 __ONE_REG(13, __VA_ARGS__); \
139 __ONE_REG(14, __VA_ARGS__); \
140 __ONE_REG(15, __VA_ARGS__); \
141 ring->cur = p; \
142 } while (0)
143
144 /* similar to OUT_PKT() but appends specified # of dwords
145 * copied for buf to the end of the packet (ie. for use-
146 * cases like CP_LOAD_STATE)
147 */
148 #define OUT_PKTBUF(ring, opcode, dwords, sizedwords, ...) \
149 do { \
150 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
151 unsigned count = ARRAY_SIZE(regs); \
152 \
153 STATIC_ASSERT(count <= 16); \
154 count += sizedwords; \
155 \
156 BEGIN_RING(ring, count + 1); \
157 uint32_t *p = ring->cur; \
158 *p++ = CP_TYPE7_PKT | count | \
159 (_odd_parity_bit(count) << 15) | \
160 ((opcode & 0x7f) << 16) | \
161 ((_odd_parity_bit(opcode) << 23)); \
162 \
163 __ONE_REG( 0, __VA_ARGS__); \
164 __ONE_REG( 1, __VA_ARGS__); \
165 __ONE_REG( 2, __VA_ARGS__); \
166 __ONE_REG( 3, __VA_ARGS__); \
167 __ONE_REG( 4, __VA_ARGS__); \
168 __ONE_REG( 5, __VA_ARGS__); \
169 __ONE_REG( 6, __VA_ARGS__); \
170 __ONE_REG( 7, __VA_ARGS__); \
171 __ONE_REG( 8, __VA_ARGS__); \
172 __ONE_REG( 9, __VA_ARGS__); \
173 __ONE_REG(10, __VA_ARGS__); \
174 __ONE_REG(11, __VA_ARGS__); \
175 __ONE_REG(12, __VA_ARGS__); \
176 __ONE_REG(13, __VA_ARGS__); \
177 __ONE_REG(14, __VA_ARGS__); \
178 __ONE_REG(15, __VA_ARGS__); \
179 memcpy(p, dwords, 4 * sizedwords); \
180 p += sizedwords; \
181 ring->cur = p; \
182 } while (0)
183
184 #endif /* FD6_PACK_H */