1bf215546Sopenharmony_ci
2bf215546Sopenharmony_ci#ifndef LP_LINEAR_PRIV_H
3bf215546Sopenharmony_ci#define LP_LINEAR_PRIV_H
4bf215546Sopenharmony_ci
5bf215546Sopenharmony_cistruct lp_linear_elem;
6bf215546Sopenharmony_ci
7bf215546Sopenharmony_citypedef const uint32_t *(*lp_linear_func)(struct lp_linear_elem *base);
8bf215546Sopenharmony_ci
9bf215546Sopenharmony_ci
10bf215546Sopenharmony_cistruct lp_linear_elem {
11bf215546Sopenharmony_ci   lp_linear_func fetch;
12bf215546Sopenharmony_ci};
13bf215546Sopenharmony_ci
14bf215546Sopenharmony_ci
15bf215546Sopenharmony_ci/* "Linear" refers to the fact we're on the linear (non-swizzled)
16bf215546Sopenharmony_ci * rasterization path.  Filtering mode may be either linear or
17bf215546Sopenharmony_ci * nearest.
18bf215546Sopenharmony_ci */
19bf215546Sopenharmony_cistruct lp_linear_sampler {
20bf215546Sopenharmony_ci   struct lp_linear_elem base;
21bf215546Sopenharmony_ci
22bf215546Sopenharmony_ci   const struct lp_jit_texture *texture;
23bf215546Sopenharmony_ci   int s;                       /* 16.16, biased by .5 */
24bf215546Sopenharmony_ci   int t;                       /* 16.16, biased by .5 */
25bf215546Sopenharmony_ci   int dsdx;                    /* 16.16 */
26bf215546Sopenharmony_ci   int dsdy;                    /* 16.16 */
27bf215546Sopenharmony_ci   int dtdx;                    /* 16.16 */
28bf215546Sopenharmony_ci   int dtdy;                    /* 16.16 */
29bf215546Sopenharmony_ci   int width;
30bf215546Sopenharmony_ci   boolean axis_aligned;
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci   alignas(16) uint32_t row[64];
33bf215546Sopenharmony_ci   alignas(16) uint32_t stretched_row[2][64];
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci   /**
36bf215546Sopenharmony_ci    * y coordinate of the rows stored in the stretched_row.
37bf215546Sopenharmony_ci    *
38bf215546Sopenharmony_ci    * Negative number means no stretched row is cached.
39bf215546Sopenharmony_ci    */
40bf215546Sopenharmony_ci   int stretched_row_y[2];
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   /**
43bf215546Sopenharmony_ci    * The index of stretched_row to receive the next stretched row.
44bf215546Sopenharmony_ci    */
45bf215546Sopenharmony_ci   int stretched_row_index;
46bf215546Sopenharmony_ci};
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci/* "Linear" refers to the fact we're on the linear (non-swizzled)
49bf215546Sopenharmony_ci * rasterization path.  Interpolation mode may be either constant,
50bf215546Sopenharmony_ci * linear or perspective.
51bf215546Sopenharmony_ci */
52bf215546Sopenharmony_cistruct lp_linear_interp {
53bf215546Sopenharmony_ci   struct lp_linear_elem base;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci#if defined(PIPE_ARCH_SSE)
56bf215546Sopenharmony_ci   __m128i a0;
57bf215546Sopenharmony_ci   __m128i dadx;
58bf215546Sopenharmony_ci   __m128i dady;
59bf215546Sopenharmony_ci#endif
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   int width;                   /* rounded up to multiple of 4 */
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   alignas(16) uint32_t row[64];
64bf215546Sopenharmony_ci};
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci/* Check for a sampler variant which matches our fetch_row
68bf215546Sopenharmony_ci * implementation - normalized texcoords, single mipmap with
69bf215546Sopenharmony_ci * nearest filtering.
70bf215546Sopenharmony_ci */
71bf215546Sopenharmony_cistatic inline boolean
72bf215546Sopenharmony_ciis_nearest_sampler(const struct lp_sampler_static_state *sampler)
73bf215546Sopenharmony_ci{
74bf215546Sopenharmony_ci   return
75bf215546Sopenharmony_ci      sampler->texture_state.target == PIPE_TEXTURE_2D &&
76bf215546Sopenharmony_ci      sampler->sampler_state.min_img_filter == PIPE_TEX_FILTER_NEAREST &&
77bf215546Sopenharmony_ci      sampler->sampler_state.mag_img_filter == PIPE_TEX_FILTER_NEAREST &&
78bf215546Sopenharmony_ci      (sampler->texture_state.level_zero_only ||
79bf215546Sopenharmony_ci       sampler->sampler_state.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) &&
80bf215546Sopenharmony_ci      sampler->sampler_state.compare_mode == 0 &&
81bf215546Sopenharmony_ci      sampler->sampler_state.normalized_coords == 1;
82bf215546Sopenharmony_ci}
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci/* Check for a sampler variant which matches our fetch_row
86bf215546Sopenharmony_ci * implementation - normalized texcoords, single mipmap with
87bf215546Sopenharmony_ci * linear filtering.
88bf215546Sopenharmony_ci */
89bf215546Sopenharmony_cistatic inline boolean
90bf215546Sopenharmony_ciis_linear_sampler(const struct lp_sampler_static_state *sampler)
91bf215546Sopenharmony_ci{
92bf215546Sopenharmony_ci   return
93bf215546Sopenharmony_ci      sampler->texture_state.target == PIPE_TEXTURE_2D &&
94bf215546Sopenharmony_ci      sampler->sampler_state.min_img_filter == PIPE_TEX_FILTER_LINEAR &&
95bf215546Sopenharmony_ci      sampler->sampler_state.mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
96bf215546Sopenharmony_ci      (sampler->texture_state.level_zero_only ||
97bf215546Sopenharmony_ci       sampler->sampler_state.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) &&
98bf215546Sopenharmony_ci      sampler->sampler_state.compare_mode == 0 &&
99bf215546Sopenharmony_ci      sampler->sampler_state.normalized_coords == 1;
100bf215546Sopenharmony_ci}
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci/* Check for a sampler variant which matches is_nearest_sampler
104bf215546Sopenharmony_ci * but has the additional constraints of using clamp wrapping
105bf215546Sopenharmony_ci */
106bf215546Sopenharmony_cistatic inline boolean
107bf215546Sopenharmony_ciis_nearest_clamp_sampler(const struct lp_sampler_static_state *sampler)
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   return
110bf215546Sopenharmony_ci      is_nearest_sampler(sampler) &&
111bf215546Sopenharmony_ci      sampler->sampler_state.wrap_s == PIPE_TEX_WRAP_CLAMP_TO_EDGE &&
112bf215546Sopenharmony_ci      sampler->sampler_state.wrap_t == PIPE_TEX_WRAP_CLAMP_TO_EDGE;
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci/* Check for a sampler variant which matches is_linear_sampler
117bf215546Sopenharmony_ci * but has the additional constraints of using clamp wrapping
118bf215546Sopenharmony_ci */
119bf215546Sopenharmony_cistatic inline boolean
120bf215546Sopenharmony_ciis_linear_clamp_sampler(const struct lp_sampler_static_state *sampler)
121bf215546Sopenharmony_ci{
122bf215546Sopenharmony_ci   return
123bf215546Sopenharmony_ci      is_linear_sampler(sampler) &&
124bf215546Sopenharmony_ci      sampler->sampler_state.wrap_s == PIPE_TEX_WRAP_CLAMP_TO_EDGE &&
125bf215546Sopenharmony_ci      sampler->sampler_state.wrap_t == PIPE_TEX_WRAP_CLAMP_TO_EDGE;
126bf215546Sopenharmony_ci}
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ciboolean
130bf215546Sopenharmony_cilp_linear_init_interp(struct lp_linear_interp *interp,
131bf215546Sopenharmony_ci                      int x, int y, int width, int height,
132bf215546Sopenharmony_ci                      unsigned usage_mask,
133bf215546Sopenharmony_ci                      boolean perspective,
134bf215546Sopenharmony_ci                      float oow,
135bf215546Sopenharmony_ci                      const float *a0,
136bf215546Sopenharmony_ci                      const float *dadx,
137bf215546Sopenharmony_ci                      const float *dady);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ciboolean
140bf215546Sopenharmony_cilp_linear_init_sampler(struct lp_linear_sampler *samp,
141bf215546Sopenharmony_ci                       const struct lp_tgsi_texture_info *info,
142bf215546Sopenharmony_ci                       const struct lp_sampler_static_state *sampler_state,
143bf215546Sopenharmony_ci                       const struct lp_jit_texture *texture,
144bf215546Sopenharmony_ci                       int x0, int y0, int width, int height,
145bf215546Sopenharmony_ci                       const float (*a0)[4],
146bf215546Sopenharmony_ci                       const float (*dadx)[4],
147bf215546Sopenharmony_ci                       const float (*dady)[4]);
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ciboolean
151bf215546Sopenharmony_cilp_linear_check_fastpath(struct lp_fragment_shader_variant *variant);
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ciboolean
154bf215546Sopenharmony_cilp_linear_check_sampler(const struct lp_sampler_static_state *sampler,
155bf215546Sopenharmony_ci                        const struct lp_tgsi_texture_info *tex);
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_civoid
159bf215546Sopenharmony_cilp_linear_init_noop_interp(struct lp_linear_interp *interp);
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_civoid
162bf215546Sopenharmony_cilp_linear_init_noop_sampler(struct lp_linear_sampler *samp);
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci#define FAIL(s) do {                                    \
166bf215546Sopenharmony_ci      if (LP_DEBUG & DEBUG_LINEAR)                      \
167bf215546Sopenharmony_ci         debug_printf("%s: %s\n", __FUNCTION__, s);     \
168bf215546Sopenharmony_ci      return FALSE;                                     \
169bf215546Sopenharmony_ci} while (0)
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci#endif
172