84b232e74a2d8a4e038ef5148945293f7a16a0d4
[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 bo_write;
34 uint32_t bo_offset;
35 uint32_t bo_shift;
36 };
37
38 #define __bo_type struct fd_bo *
39
40 #include "a6xx-pack.xml.h"
41
42 #define __assert_eq(a, b) \
43 do { \
44 if ((a) != (b)) { \
45 fprintf(stderr, "assert failed: " #a " (0x%x) != " #b " (0x%x)\n", a, b); \
46 assert((a) == (b)); \
47 } \
48 } while (0)
49
50 #define __ONE_REG(i, ...) \
51 do { \
52 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
53 if (i < ARRAY_SIZE(regs) && regs[i].reg > 0) { \
54 __assert_eq(regs[0].reg + i, regs[i].reg); \
55 if (regs[i].bo) { \
56 struct fd_reloc reloc = { \
57 .bo = regs[i].bo, \
58 .flags = FD_RELOC_READ | \
59 (regs[i].bo_write ? FD_RELOC_WRITE : 0), \
60 \
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 } \
72 } \
73 } while (0)
74
75 #define OUT_REG(ring, ...) \
76 do { \
77 const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
78 unsigned count = ARRAY_SIZE(regs); \
79 uint32_t *p = ring->cur; \
80 \
81 STATIC_ASSERT(count > 0); \
82 STATIC_ASSERT(count <= 16); \
83 \
84 BEGIN_RING(ring, count + 1); \
85 *p++ = CP_TYPE4_PKT | count | \
86 (_odd_parity_bit(count) << 7) | \
87 ((regs[0].reg & 0x3ffff) << 8) | \
88 ((_odd_parity_bit(regs[0].reg) << 27)); \
89 \
90 __ONE_REG( 0, __VA_ARGS__); \
91 __ONE_REG( 1, __VA_ARGS__); \
92 __ONE_REG( 2, __VA_ARGS__); \
93 __ONE_REG( 3, __VA_ARGS__); \
94 __ONE_REG( 4, __VA_ARGS__); \
95 __ONE_REG( 5, __VA_ARGS__); \
96 __ONE_REG( 6, __VA_ARGS__); \
97 __ONE_REG( 7, __VA_ARGS__); \
98 __ONE_REG( 8, __VA_ARGS__); \
99 __ONE_REG( 9, __VA_ARGS__); \
100 __ONE_REG(10, __VA_ARGS__); \
101 __ONE_REG(11, __VA_ARGS__); \
102 __ONE_REG(12, __VA_ARGS__); \
103 __ONE_REG(13, __VA_ARGS__); \
104 __ONE_REG(14, __VA_ARGS__); \
105 __ONE_REG(15, __VA_ARGS__); \
106 ring->cur = p; \
107 } while (0)
108
109 #endif /* FD6_PACK_H */