etnaviv: remove dead code
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_texture_desc.c
1 /*
2 * Copyright (c) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Wladimir J. van der Laan <laanwj@gmail.com>
26 */
27
28 #include "etnaviv_texture_desc.h"
29
30 #include "hw/common.xml.h"
31 #include "hw/texdesc_3d.xml.h"
32
33 #include "etnaviv_clear_blit.h"
34 #include "etnaviv_context.h"
35 #include "etnaviv_emit.h"
36 #include "etnaviv_format.h"
37 #include "etnaviv_translate.h"
38 #include "etnaviv_texture.h"
39 #include "util/u_inlines.h"
40 #include "util/u_memory.h"
41
42 #include <drm_fourcc.h>
43
44 static void *
45 etna_create_sampler_state_desc(struct pipe_context *pipe,
46 const struct pipe_sampler_state *ss)
47 {
48 struct etna_sampler_state_desc *cs = CALLOC_STRUCT(etna_sampler_state_desc);
49
50 if (!cs)
51 return NULL;
52
53 cs->SAMP_CTRL0 =
54 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_UWRAP(translate_texture_wrapmode(ss->wrap_s)) |
55 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_VWRAP(translate_texture_wrapmode(ss->wrap_t)) |
56 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_WWRAP(translate_texture_wrapmode(ss->wrap_r)) |
57 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_MIN(translate_texture_filter(ss->min_img_filter)) |
58 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_MIP(translate_texture_mipfilter(ss->min_mip_filter)) |
59 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_MAG(translate_texture_filter(ss->mag_img_filter)) |
60 VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_UNK21;
61 /* no ROUND_UV bit? */
62 cs->SAMP_CTRL1 = VIVS_NTE_DESCRIPTOR_SAMP_CTRL1_UNK1;
63 uint32_t min_lod_fp8 = MIN2(etna_float_to_fixp88(ss->min_lod), 0xfff);
64 uint32_t max_lod_fp8 = MIN2(etna_float_to_fixp88(ss->max_lod), 0xfff);
65 uint32_t max_lod_min = ss->min_img_filter != ss->mag_img_filter ? 4 : 0;
66
67 if (ss->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
68 cs->SAMP_LOD_MINMAX =
69 VIVS_NTE_DESCRIPTOR_SAMP_LOD_MINMAX_MAX(MAX2(max_lod_fp8, max_lod_min)) |
70 VIVS_NTE_DESCRIPTOR_SAMP_LOD_MINMAX_MIN(min_lod_fp8);
71 } else {
72 cs->SAMP_LOD_MINMAX =
73 VIVS_NTE_DESCRIPTOR_SAMP_LOD_MINMAX_MAX(MAX2(max_lod_fp8, max_lod_min)) |
74 VIVS_NTE_DESCRIPTOR_SAMP_LOD_MINMAX_MIN(min_lod_fp8);
75 }
76 cs->SAMP_LOD_BIAS =
77 VIVS_NTE_DESCRIPTOR_SAMP_LOD_BIAS_BIAS(etna_float_to_fixp88(ss->lod_bias)) |
78 COND(ss->lod_bias != 0.0, VIVS_NTE_DESCRIPTOR_SAMP_LOD_BIAS_ENABLE);
79
80 return cs;
81 }
82
83 static void
84 etna_delete_sampler_state_desc(struct pipe_context *pctx, void *ss)
85 {
86 FREE(ss);
87 }
88
89 static struct pipe_sampler_view *
90 etna_create_sampler_view_desc(struct pipe_context *pctx, struct pipe_resource *prsc,
91 const struct pipe_sampler_view *so)
92 {
93 const struct util_format_description *desc = util_format_description(so->format);
94 struct etna_sampler_view_desc *sv = CALLOC_STRUCT(etna_sampler_view_desc);
95 struct etna_context *ctx = etna_context(pctx);
96 const uint32_t format = translate_texture_format(so->format);
97 const bool ext = !!(format & EXT_FORMAT);
98 const bool astc = !!(format & ASTC_FORMAT);
99 const uint32_t swiz = get_texture_swiz(so->format, so->swizzle_r,
100 so->swizzle_g, so->swizzle_b,
101 so->swizzle_a);
102
103 if (!sv)
104 return NULL;
105
106 struct etna_resource *res = etna_texture_handle_incompatible(pctx, prsc);
107 if (!res) {
108 free(sv);
109 return NULL;
110 }
111
112 sv->base = *so;
113 pipe_reference_init(&sv->base.reference, 1);
114 sv->base.texture = NULL;
115 pipe_resource_reference(&sv->base.texture, prsc);
116 sv->base.context = pctx;
117
118 /* Determine whether target supported */
119 uint32_t target_hw = translate_texture_target(sv->base.target);
120 if (target_hw == ETNA_NO_MATCH) {
121 BUG("Unhandled texture target");
122 free(sv);
123 return NULL;
124 }
125
126 /* Texture descriptor sampler bits */
127 if (util_format_is_srgb(so->format))
128 sv->SAMP_CTRL1 |= VIVS_NTE_DESCRIPTOR_SAMP_CTRL1_SRGB;
129
130 if (!util_format_is_float(so->format) && so->target != PIPE_TEXTURE_3D)
131 sv->SAMP_CTRL0 |= VIVS_NTE_DESCRIPTOR_SAMP_CTRL0_INT_FILTER;
132
133 /* Create texture descriptor */
134 sv->bo = etna_bo_new(ctx->screen->dev, 0x100, DRM_ETNA_GEM_CACHE_WC);
135 if (!sv->bo)
136 goto error;
137
138 uint32_t *buf = etna_bo_map(sv->bo);
139 etna_bo_cpu_prep(sv->bo, DRM_ETNA_PREP_WRITE);
140 memset(buf, 0, 0x100);
141
142 /** GC7000 needs the size of the BASELOD level */
143 uint32_t base_width = u_minify(res->base.width0, sv->base.u.tex.first_level);
144 uint32_t base_height = u_minify(res->base.height0, sv->base.u.tex.first_level);
145 uint32_t base_depth = u_minify(res->base.depth0, sv->base.u.tex.first_level);
146 bool is_array = false;
147 bool sint = util_format_is_pure_sint(so->format);
148
149 if (sv->base.target == PIPE_TEXTURE_1D_ARRAY) {
150 is_array = true;
151 base_height = res->base.array_size;
152 } else if (sv->base.target == PIPE_TEXTURE_2D_ARRAY) {
153 is_array = true;
154 base_depth = res->base.array_size;
155 }
156
157 #define DESC_SET(x, y) buf[(TEXDESC_##x)>>2] = (y)
158 DESC_SET(CONFIG0, COND(!ext && !astc, VIVS_TE_SAMPLER_CONFIG0_FORMAT(format))
159 | VIVS_TE_SAMPLER_CONFIG0_TYPE(target_hw) |
160 COND(res->layout == ETNA_LAYOUT_LINEAR && !util_format_is_compressed(so->format),
161 VIVS_TE_SAMPLER_CONFIG0_ADDRESSING_MODE(TEXTURE_ADDRESSING_MODE_LINEAR)));
162 DESC_SET(CONFIG1, COND(ext, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(format)) |
163 COND(astc, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(TEXTURE_FORMAT_EXT_ASTC)) |
164 COND(is_array, VIVS_TE_SAMPLER_CONFIG1_TEXTURE_ARRAY) |
165 VIVS_TE_SAMPLER_CONFIG1_HALIGN(res->halign) | swiz);
166 DESC_SET(CONFIG2, 0x00030000 |
167 COND(sint && desc->channel[0].size == 8, TE_SAMPLER_CONFIG2_SIGNED_INT8) |
168 COND(sint && desc->channel[0].size == 16, TE_SAMPLER_CONFIG2_SIGNED_INT16));
169 DESC_SET(LINEAR_STRIDE, res->levels[0].stride);
170 DESC_SET(VOLUME, etna_log2_fixp88(base_depth));
171 DESC_SET(SLICE, res->levels[0].layer_stride);
172 DESC_SET(3D_CONFIG, VIVS_TE_SAMPLER_3D_CONFIG_DEPTH(base_depth));
173 DESC_SET(ASTC0, COND(astc, VIVS_NTE_SAMPLER_ASTC0_ASTC_FORMAT(format)) |
174 VIVS_NTE_SAMPLER_ASTC0_UNK8(0xc) |
175 VIVS_NTE_SAMPLER_ASTC0_UNK16(0xc) |
176 VIVS_NTE_SAMPLER_ASTC0_UNK24(0xc));
177 DESC_SET(BASELOD, TEXDESC_BASELOD_BASELOD(sv->base.u.tex.first_level) |
178 TEXDESC_BASELOD_MAXLOD(MIN2(sv->base.u.tex.last_level, res->base.last_level)));
179 DESC_SET(LOG_SIZE_EXT, TEXDESC_LOG_SIZE_EXT_WIDTH(etna_log2_fixp88(base_width)) |
180 TEXDESC_LOG_SIZE_EXT_HEIGHT(etna_log2_fixp88(base_height)));
181 DESC_SET(SIZE, VIVS_TE_SAMPLER_SIZE_WIDTH(base_width) |
182 VIVS_TE_SAMPLER_SIZE_HEIGHT(base_height));
183 for (int lod = 0; lod <= res->base.last_level; ++lod)
184 DESC_SET(LOD_ADDR(lod), etna_bo_gpu_va(res->bo) + res->levels[lod].offset);
185 #undef DESC_SET
186
187 etna_bo_cpu_fini(sv->bo);
188
189 sv->DESC_ADDR.bo = sv->bo;
190 sv->DESC_ADDR.offset = 0;
191 sv->DESC_ADDR.flags = ETNA_RELOC_READ;
192
193 return &sv->base;
194 error:
195 free(sv);
196 return NULL;
197 }
198
199 static void
200 etna_sampler_view_update_descriptor(struct etna_context *ctx,
201 struct etna_cmd_stream *stream,
202 struct etna_sampler_view_desc *sv)
203 {
204 /* TODO: this should instruct the kernel to update the descriptor when the
205 * bo is submitted. For now, just prevent the bo from being freed
206 * while it is in use indirectly.
207 */
208 struct etna_resource *res = etna_resource(sv->base.texture);
209 if (res->texture) {
210 res = etna_resource(res->texture);
211 }
212 /* No need to ref LOD levels individually as they'll always come from the same bo */
213 etna_cmd_stream_ref_bo(stream, res->bo, ETNA_RELOC_READ);
214 }
215
216 static void
217 etna_sampler_view_desc_destroy(struct pipe_context *pctx,
218 struct pipe_sampler_view *so)
219 {
220 struct etna_sampler_view_desc *sv = etna_sampler_view_desc(so);
221 pipe_resource_reference(&sv->base.texture, NULL);
222 etna_bo_del(sv->bo);
223 FREE(sv);
224 }
225
226 static void
227 etna_emit_texture_desc(struct etna_context *ctx)
228 {
229 struct etna_cmd_stream *stream = ctx->stream;
230 uint32_t active_samplers = active_samplers_bits(ctx);
231 uint32_t dirty = ctx->dirty;
232
233 if (unlikely(dirty & ETNA_DIRTY_SAMPLER_VIEWS)) {
234 for (int x = 0; x < VIVS_TS_SAMPLER__LEN; ++x) {
235 if ((1 << x) & active_samplers) {
236 struct etna_sampler_view_desc *sv = etna_sampler_view_desc(ctx->sampler_view[x]);
237 struct etna_resource *res = etna_resource(sv->base.texture);
238 struct etna_reloc LOD_ADDR_0;
239
240 if (!sv->ts.enable)
241 continue;
242
243 etna_set_state(stream, VIVS_TS_SAMPLER_CONFIG(x), sv->ts.TS_SAMPLER_CONFIG);
244 etna_set_state_reloc(stream, VIVS_TS_SAMPLER_STATUS_BASE(x), &sv->ts.TS_SAMPLER_STATUS_BASE);
245 etna_set_state(stream, VIVS_TS_SAMPLER_CLEAR_VALUE(x), sv->ts.TS_SAMPLER_CLEAR_VALUE);
246 etna_set_state(stream, VIVS_TS_SAMPLER_CLEAR_VALUE2(x), sv->ts.TS_SAMPLER_CLEAR_VALUE2);
247
248 LOD_ADDR_0.bo = res->bo;
249 LOD_ADDR_0.offset = res->levels[0].offset;
250 LOD_ADDR_0.flags = ETNA_RELOC_READ;
251
252 etna_set_state_reloc(stream, VIVS_TS_SAMPLER_SURFACE_BASE(x), &LOD_ADDR_0);
253 }
254 }
255 }
256
257 if (unlikely(dirty & (ETNA_DIRTY_SAMPLERS | ETNA_DIRTY_SAMPLER_VIEWS))) {
258 for (int x = 0; x < PIPE_MAX_SAMPLERS; ++x) {
259 if ((1 << x) & active_samplers) {
260 struct etna_sampler_state_desc *ss = etna_sampler_state_desc(ctx->sampler[x]);
261 struct etna_sampler_view_desc *sv = etna_sampler_view_desc(ctx->sampler_view[x]);
262 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_TX_CTRL(x),
263 COND(sv->ts.enable, VIVS_NTE_DESCRIPTOR_TX_CTRL_TS_ENABLE) |
264 VIVS_NTE_DESCRIPTOR_TX_CTRL_TS_MODE(sv->ts.mode) |
265 VIVS_NTE_DESCRIPTOR_TX_CTRL_TS_INDEX(x));
266 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_SAMP_CTRL0(x), ss->SAMP_CTRL0 | sv->SAMP_CTRL0);
267 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_SAMP_CTRL1(x), ss->SAMP_CTRL1 | sv->SAMP_CTRL1);
268 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_SAMP_LOD_MINMAX(x), ss->SAMP_LOD_MINMAX);
269 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_SAMP_LOD_BIAS(x), ss->SAMP_LOD_BIAS);
270 }
271 }
272 }
273
274 if (unlikely(dirty & ETNA_DIRTY_SAMPLER_VIEWS)) {
275 /* Set texture descriptors */
276 for (int x = 0; x < PIPE_MAX_SAMPLERS; ++x) {
277 if ((1 << x) & ctx->dirty_sampler_views) {
278 if ((1 << x) & active_samplers) {
279 struct etna_sampler_view_desc *sv = etna_sampler_view_desc(ctx->sampler_view[x]);
280 etna_sampler_view_update_descriptor(ctx, stream, sv);
281 etna_set_state_reloc(stream, VIVS_NTE_DESCRIPTOR_ADDR(x), &sv->DESC_ADDR);
282 } else {
283 /* dummy texture descriptors for unused samplers */
284 etna_set_state_reloc(stream, VIVS_NTE_DESCRIPTOR_ADDR(x), &ctx->DUMMY_DESC_ADDR);
285 }
286 }
287 }
288 }
289
290 if (unlikely(dirty & ETNA_DIRTY_SAMPLER_VIEWS)) {
291 /* Invalidate all dirty sampler views.
292 */
293 for (int x = 0; x < PIPE_MAX_SAMPLERS; ++x) {
294 if ((1 << x) & ctx->dirty_sampler_views) {
295 etna_set_state(stream, VIVS_NTE_DESCRIPTOR_INVALIDATE,
296 VIVS_NTE_DESCRIPTOR_INVALIDATE_UNK29 |
297 VIVS_NTE_DESCRIPTOR_INVALIDATE_IDX(x));
298 }
299 }
300 }
301 }
302
303 static struct etna_sampler_ts*
304 etna_ts_for_sampler_view_state(struct pipe_sampler_view *pview)
305 {
306 struct etna_sampler_view_desc *sv = etna_sampler_view_desc(pview);
307 return &sv->ts;
308 }
309
310 void
311 etna_texture_desc_init(struct pipe_context *pctx)
312 {
313 struct etna_context *ctx = etna_context(pctx);
314 DBG("etnaviv: Using descriptor-based texturing\n");
315 ctx->base.create_sampler_state = etna_create_sampler_state_desc;
316 ctx->base.delete_sampler_state = etna_delete_sampler_state_desc;
317 ctx->base.create_sampler_view = etna_create_sampler_view_desc;
318 ctx->base.sampler_view_destroy = etna_sampler_view_desc_destroy;
319 ctx->emit_texture_state = etna_emit_texture_desc;
320 ctx->ts_for_sampler_view = etna_ts_for_sampler_view_state;
321 }
322