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