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