1 /*
2 * Copyright © 2016 Rob Clark <[email protected]>
3 * Copyright © 2018 Google, Inc.
4 * SPDX-License-Identifier: MIT
5 *
6 * Authors:
7 * Rob Clark <[email protected]>
8 */
9
10 #define FD_BO_NO_HARDPIN 1
11
12 #include "drm-uapi/drm_fourcc.h"
13 #include "pipe/p_screen.h"
14 #include "util/format/u_format.h"
15
16 #include "fd6_blitter.h"
17 #include "fd6_context.h"
18 #include "fd6_emit.h"
19 #include "fd6_resource.h"
20 #include "fd6_screen.h"
21
22 #include "ir3/ir3_compiler.h"
23
24 static bool
valid_sample_count(unsigned sample_count)25 valid_sample_count(unsigned sample_count)
26 {
27 switch (sample_count) {
28 case 0:
29 case 1:
30 case 2:
31 case 4:
32 // TODO seems 8x works, but increases lrz width or height.. but the
33 // blob I have doesn't seem to expose any egl configs w/ 8x, so
34 // just hide it for now and revisit later.
35 // case 8:
36 return true;
37 default:
38 return false;
39 }
40 }
41
42 static bool
fd6_screen_is_format_supported(struct pipe_screen * pscreen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned usage)43 fd6_screen_is_format_supported(struct pipe_screen *pscreen,
44 enum pipe_format format,
45 enum pipe_texture_target target,
46 unsigned sample_count,
47 unsigned storage_sample_count, unsigned usage)
48 {
49 unsigned retval = 0;
50
51 if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
52 !valid_sample_count(sample_count)) {
53 DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
54 util_format_name(format), target, sample_count, usage);
55 return false;
56 }
57
58 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
59 return false;
60
61 if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
62 (fd6_vertex_format(format) != FMT6_NONE)) {
63 retval |= PIPE_BIND_VERTEX_BUFFER;
64 }
65
66 bool has_color = fd6_color_format(format, TILE6_LINEAR) != FMT6_NONE;
67 bool has_tex = fd6_texture_format(format, TILE6_LINEAR) != FMT6_NONE;
68
69 if ((usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHADER_IMAGE)) &&
70 has_tex &&
71 (target == PIPE_BUFFER ||
72 util_is_power_of_two_or_zero(util_format_get_blocksize(format)))) {
73 retval |= usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHADER_IMAGE);
74 }
75
76 if (usage & PIPE_BIND_SHADER_IMAGE) {
77 if (sample_count > 1)
78 return false;
79
80 /* So, this only matters for image writes but 'usage' doesn't
81 * differentiate. See f1c1b96
82 */
83 const struct util_format_description *desc = util_format_description(format);
84 if ((desc->nr_channels > 2) && (desc->block.bits == 16))
85 return false;
86 }
87
88 if ((usage &
89 (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET |
90 PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_COMPUTE_RESOURCE)) &&
91 has_color && has_tex) {
92 retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET |
93 PIPE_BIND_SCANOUT | PIPE_BIND_SHARED |
94 PIPE_BIND_COMPUTE_RESOURCE);
95 }
96
97 /* For ARB_framebuffer_no_attachments: */
98 if ((usage & PIPE_BIND_RENDER_TARGET) && (format == PIPE_FORMAT_NONE)) {
99 retval |= usage & PIPE_BIND_RENDER_TARGET;
100 }
101
102 if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
103 (fd6_pipe2depth(format) != (enum a6xx_depth_format) ~0) && has_tex) {
104 retval |= PIPE_BIND_DEPTH_STENCIL;
105 }
106
107 if ((usage & PIPE_BIND_INDEX_BUFFER) &&
108 (fd_pipe2index(format) != (enum pc_di_index_size) ~0)) {
109 retval |= PIPE_BIND_INDEX_BUFFER;
110 }
111
112 if ((usage & PIPE_BIND_BLENDABLE) && has_color &&
113 !util_format_is_pure_integer(format)) {
114 retval |= PIPE_BIND_BLENDABLE;
115 }
116
117 if (retval != usage) {
118 DBG("not supported: format=%s, target=%d, sample_count=%d, "
119 "usage=%x, retval=%x",
120 util_format_name(format), target, sample_count, usage, retval);
121 }
122
123 return retval == usage;
124 }
125
126 /* clang-format off */
127 static const enum pc_di_primtype primtypes[] = {
128 [MESA_PRIM_POINTS] = DI_PT_POINTLIST,
129 [MESA_PRIM_LINES] = DI_PT_LINELIST,
130 [MESA_PRIM_LINE_LOOP] = DI_PT_LINELOOP,
131 [MESA_PRIM_LINE_STRIP] = DI_PT_LINESTRIP,
132 [MESA_PRIM_TRIANGLES] = DI_PT_TRILIST,
133 [MESA_PRIM_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
134 [MESA_PRIM_TRIANGLE_FAN] = DI_PT_TRIFAN,
135 [MESA_PRIM_QUADS] = DI_PT_NONE, /* unsupported */
136 [MESA_PRIM_QUAD_STRIP] = DI_PT_NONE, /* unsupported */
137 [MESA_PRIM_POLYGON] = DI_PT_NONE, /* unsupported */
138 [MESA_PRIM_LINES_ADJACENCY] = DI_PT_LINE_ADJ,
139 [MESA_PRIM_LINE_STRIP_ADJACENCY] = DI_PT_LINESTRIP_ADJ,
140 [MESA_PRIM_TRIANGLES_ADJACENCY] = DI_PT_TRI_ADJ,
141 [MESA_PRIM_TRIANGLE_STRIP_ADJACENCY] = DI_PT_TRISTRIP_ADJ,
142 [MESA_PRIM_PATCHES] = DI_PT_PATCHES0,
143 [MESA_PRIM_COUNT] = DI_PT_RECTLIST, /* internal clear blits */
144 };
145 /* clang-format on */
146
147 void
fd6_screen_init(struct pipe_screen * pscreen)148 fd6_screen_init(struct pipe_screen *pscreen)
149 {
150 struct fd_screen *screen = fd_screen(pscreen);
151
152 screen->max_rts = A6XX_MAX_RENDER_TARGETS;
153
154 uint32_t depth_cache_size =
155 screen->info->num_ccu * screen->info->a6xx.sysmem_per_ccu_depth_cache_size;
156 uint32_t color_cache_size =
157 (screen->info->num_ccu * screen->info->a6xx.sysmem_per_ccu_color_cache_size) /
158 (1 << screen->info->a6xx.gmem_ccu_color_cache_fraction);
159 uint32_t color_cache_size_gmem =
160 color_cache_size /
161 (1 << screen->info->a6xx.gmem_ccu_color_cache_fraction);
162
163 struct fd6_gmem_config *gmem = &screen->config_gmem;
164 struct fd6_gmem_config *sysmem = &screen->config_sysmem;
165
166 sysmem->depth_ccu_offset = 0;
167 sysmem->color_ccu_offset = sysmem->depth_ccu_offset + depth_cache_size;
168
169 if (screen->info->a7xx.has_gmem_vpc_attr_buf) {
170 sysmem->vpc_attr_buf_size = screen->info->a7xx.sysmem_vpc_attr_buf_size;
171 sysmem->vpc_attr_buf_offset = sysmem->color_ccu_offset + color_cache_size;
172
173 gmem->vpc_attr_buf_size = screen->info->a7xx.gmem_vpc_attr_buf_size;
174 gmem->vpc_attr_buf_offset = screen->gmemsize_bytes -
175 (gmem->vpc_attr_buf_size * screen->info->num_ccu);
176
177 gmem->color_ccu_offset = gmem->vpc_attr_buf_offset - color_cache_size_gmem;
178 screen->gmemsize_bytes = gmem->vpc_attr_buf_offset;
179 } else {
180 gmem->depth_ccu_offset = 0;
181 gmem->color_ccu_offset = screen->gmemsize_bytes - color_cache_size_gmem;
182 }
183
184 /* Currently only FB_READ forces GMEM path, mostly because we'd have to
185 * deal with cmdstream patching otherwise..
186 */
187 screen->gmem_reason_mask = (enum fd_gmem_reason)(
188 FD_GMEM_CLEARS_DEPTH_STENCIL |
189 FD_GMEM_DEPTH_ENABLED | FD_GMEM_STENCIL_ENABLED |
190 FD_GMEM_BLEND_ENABLED | FD_GMEM_LOGICOP_ENABLED);
191
192 pscreen->context_create = FD_CALLX(screen->info, fd6_context_create);
193 pscreen->is_format_supported = fd6_screen_is_format_supported;
194
195 screen->tile_mode = fd6_tile_mode;
196
197 FD_CALLX(screen->info, fd6_resource_screen_init)(pscreen);
198 fd6_emit_init_screen(pscreen);
199 ir3_screen_init(pscreen);
200
201 screen->primtypes = primtypes;
202 }
203