1 /*
2 * Copyright 2022 Alyssa Rosenzweig
3 * SPDX-License-Identifier: MIT
4 */
5
6 #pragma once
7
8 #include <assert.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include "util/format/u_formats.h"
12 #include "agx_pack.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /* Maximum render targets per framebuffer. This is NOT architectural, but it
19 * is the ~universal API limit so there's no point in allowing more.
20 */
21 #define AGX_MAX_RENDER_TARGETS (8)
22
23 /* Forward declarations to keep the header lean */
24 struct nir_shader;
25 struct nir_def;
26 struct nir_builder;
27
28 struct agx_tile_size {
29 uint8_t width;
30 uint8_t height;
31 };
32
33 struct agx_tilebuffer_layout {
34 /* Logical format of each render target. Use agx_tilebuffer_physical_format
35 * to get the physical format.
36 */
37 enum pipe_format logical_format[AGX_MAX_RENDER_TARGETS];
38
39 /* Which render targets are spilled. */
40 bool spilled[AGX_MAX_RENDER_TARGETS];
41
42 /* Offset into the sample of each render target. If a render target is
43 * spilled, its offset is UNDEFINED. Use agx_tilebuffer_offset_B to access.
44 */
45 uint8_t _offset_B[AGX_MAX_RENDER_TARGETS];
46
47 /* Total bytes per sample, rounded up as needed. Spilled render targets do
48 * not count against this.
49 */
50 uint8_t sample_size_B;
51
52 /* Number of samples per pixel */
53 uint8_t nr_samples;
54
55 /* If layered rendering is used */
56 bool layered;
57
58 /* Selected tile size */
59 struct agx_tile_size tile_size;
60
61 /* USC word corresponding to this configuration of the tilebuffer */
62 struct agx_usc_shared_packed usc;
63 };
64
65 /*
66 * _offset_B is undefined for non-spilled render targets. This safe accessor
67 * asserts that render targets are not spilled rather than returning garbage.
68 */
69 static inline uint8_t
agx_tilebuffer_offset_B(struct agx_tilebuffer_layout * layout,unsigned rt)70 agx_tilebuffer_offset_B(struct agx_tilebuffer_layout *layout, unsigned rt)
71 {
72 assert(rt < AGX_MAX_RENDER_TARGETS);
73 assert(!layout->spilled[rt] && "precondition");
74
75 return layout->_offset_B[rt];
76 }
77
78 static inline bool
agx_tilebuffer_spills(struct agx_tilebuffer_layout * layout)79 agx_tilebuffer_spills(struct agx_tilebuffer_layout *layout)
80 {
81 for (unsigned rt = 0; rt < AGX_MAX_RENDER_TARGETS; ++rt) {
82 if (layout->spilled[rt])
83 return true;
84 }
85
86 return false;
87 }
88
89 struct agx_tilebuffer_layout
90 agx_build_tilebuffer_layout(const enum pipe_format *formats, uint8_t nr_cbufs,
91 uint8_t nr_samples, bool layered);
92
93 bool agx_nir_lower_tilebuffer(struct nir_shader *shader,
94 struct agx_tilebuffer_layout *tib,
95 uint8_t *colormasks, unsigned *bindless_base,
96 struct nir_def *write_samples, bool *translucent);
97
98 bool agx_nir_lower_to_per_sample(struct nir_shader *shader);
99
100 bool agx_nir_lower_monolithic_msaa(struct nir_shader *shader,
101 uint8_t nr_samples);
102
103 bool agx_nir_lower_sample_intrinsics(struct nir_shader *shader,
104 bool ignore_sample_mask_without_msaa);
105
106 bool agx_nir_lower_alpha_to_coverage(struct nir_shader *shader,
107 uint8_t nr_samples);
108
109 bool agx_nir_lower_alpha_to_one(struct nir_shader *shader);
110
111 uint32_t agx_tilebuffer_total_size(struct agx_tilebuffer_layout *tib);
112
113 enum pipe_format
114 agx_tilebuffer_physical_format(struct agx_tilebuffer_layout *tib, unsigned rt);
115
116 bool agx_tilebuffer_supports_mask(struct agx_tilebuffer_layout *tib,
117 unsigned rt);
118
119 void agx_tilebuffer_pack_usc(struct agx_tilebuffer_layout *tib);
120
121 #ifdef __cplusplus
122 } /* extern C */
123 #endif
124