ef6c1bb3155a04ab0a4a2535d6eecb27bdc31267
[mesa.git] / src / gallium / drivers / i965 / brw_pipe_sampler.c
1
2 #include "util/u_memory.h"
3 #include "util/u_math.h"
4
5 #include "pipe/p_context.h"
6 #include "pipe/p_state.h"
7
8 #include "brw_context.h"
9 #include "brw_defines.h"
10
11
12
13 /* The brw (and related graphics cores) do not support GL_CLAMP. The
14 * Intel drivers for "other operating systems" implement GL_CLAMP as
15 * GL_CLAMP_TO_EDGE, so the same is done here.
16 */
17 static GLuint translate_wrap_mode( unsigned wrap )
18 {
19 switch( wrap ) {
20 case PIPE_TEX_WRAP_REPEAT:
21 return BRW_TEXCOORDMODE_WRAP;
22
23 case PIPE_TEX_WRAP_CLAMP:
24 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
25 return BRW_TEXCOORDMODE_CLAMP;
26
27 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
28 return BRW_TEXCOORDMODE_CLAMP_BORDER;
29
30 case PIPE_TEX_WRAP_MIRROR_REPEAT:
31 return BRW_TEXCOORDMODE_MIRROR;
32
33 case PIPE_TEX_WRAP_MIRROR_CLAMP:
34 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
35 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
36 return BRW_TEXCOORDMODE_MIRROR_ONCE;
37
38 default:
39 return BRW_TEXCOORDMODE_WRAP;
40 }
41 }
42
43 static GLuint translate_img_filter( unsigned filter )
44 {
45 switch (filter) {
46 case PIPE_TEX_FILTER_NEAREST:
47 return BRW_MAPFILTER_NEAREST;
48 case PIPE_TEX_FILTER_LINEAR:
49 return BRW_MAPFILTER_LINEAR;
50 default:
51 assert(0);
52 return BRW_MAPFILTER_NEAREST;
53 }
54 }
55
56 static GLuint translate_mip_filter( unsigned filter )
57 {
58 switch (filter) {
59 case PIPE_TEX_MIPFILTER_NONE:
60 return BRW_MIPFILTER_NONE;
61 case PIPE_TEX_MIPFILTER_NEAREST:
62 return BRW_MIPFILTER_NEAREST;
63 case PIPE_TEX_MIPFILTER_LINEAR:
64 return BRW_MIPFILTER_LINEAR;
65 default:
66 assert(0);
67 return BRW_MIPFILTER_NONE;
68 }
69 }
70
71 /* XXX: not sure why there are special translations for the shadow tex
72 * compare functions. In particular ALWAYS is translated to NEVER.
73 * Is this a hardware issue? Does i965 really suffer from this?
74 */
75 static GLuint translate_shadow_compare_func( unsigned func )
76 {
77 switch (func) {
78 case PIPE_FUNC_NEVER:
79 return BRW_COMPAREFUNCTION_ALWAYS;
80 case PIPE_FUNC_LESS:
81 return BRW_COMPAREFUNCTION_LEQUAL;
82 case PIPE_FUNC_LEQUAL:
83 return BRW_COMPAREFUNCTION_LESS;
84 case PIPE_FUNC_GREATER:
85 return BRW_COMPAREFUNCTION_GEQUAL;
86 case PIPE_FUNC_GEQUAL:
87 return BRW_COMPAREFUNCTION_GREATER;
88 case PIPE_FUNC_NOTEQUAL:
89 return BRW_COMPAREFUNCTION_EQUAL;
90 case PIPE_FUNC_EQUAL:
91 return BRW_COMPAREFUNCTION_NOTEQUAL;
92 case PIPE_FUNC_ALWAYS:
93 return BRW_COMPAREFUNCTION_NEVER;
94 default:
95 assert(0);
96 return BRW_COMPAREFUNCTION_NEVER;
97 }
98 }
99
100
101
102
103 static void *
104 brw_create_sampler_state( struct pipe_context *pipe,
105 const struct pipe_sampler_state *template )
106 {
107 struct brw_sampler *sampler = CALLOC_STRUCT(brw_sampler);
108
109 sampler->ss0.min_filter = translate_img_filter( template->min_img_filter );
110 sampler->ss0.mag_filter = translate_img_filter( template->mag_img_filter );
111 sampler->ss0.mip_filter = translate_mip_filter( template->min_mip_filter );
112
113
114 /* XXX: anisotropy logic slightly changed:
115 */
116 if (template->max_anisotropy > 1.0) {
117 sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
118 sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
119
120 if (template->max_anisotropy > 2.0) {
121 sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2,
122 BRW_ANISORATIO_16);
123 }
124 }
125
126 sampler->ss1.r_wrap_mode = translate_wrap_mode(template->wrap_r);
127 sampler->ss1.s_wrap_mode = translate_wrap_mode(template->wrap_s);
128 sampler->ss1.t_wrap_mode = translate_wrap_mode(template->wrap_t);
129
130 /* Set LOD bias:
131 */
132 sampler->ss0.lod_bias =
133 util_signed_fixed(CLAMP(template->lod_bias, -16, 15), 6);
134
135
136 sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
137 sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
138
139 /* Set shadow function:
140 */
141 if (template->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
142
143 /* Shadowing is "enabled" by emitting a particular sampler
144 * message (sample_c). So need to recompile WM program when
145 * shadow comparison is enabled on each/any texture unit.
146 */
147 sampler->ss0.shadow_function =
148 translate_shadow_compare_func(template->compare_func);
149 }
150
151 /* Set BaseMipLevel, MaxLOD, MinLOD:
152 */
153 sampler->ss0.base_level =
154 util_unsigned_fixed(0, 1);
155
156 sampler->ss1.max_lod =
157 util_unsigned_fixed(CLAMP(template->max_lod, 0, 13), 6);
158
159 sampler->ss1.min_lod =
160 util_unsigned_fixed(CLAMP(template->min_lod, 0, 13), 6);
161
162 return (void *)sampler;
163 }
164
165 static void brw_bind_sampler_state(struct pipe_context *pipe,
166 unsigned num, void **sampler)
167 {
168 struct brw_context *brw = brw_context(pipe);
169 int i;
170
171 for (i = 0; i < num; i++)
172 brw->curr.sampler[i] = sampler[i];
173
174 for (i = num; i < brw->curr.num_samplers; i++)
175 brw->curr.sampler[i] = NULL;
176
177 brw->curr.num_samplers = num;
178 brw->state.dirty.mesa |= PIPE_NEW_SAMPLERS;
179 }
180
181 static void brw_delete_sampler_state(struct pipe_context *pipe,
182 void *cso)
183 {
184 FREE(cso);
185 }
186
187 static void brw_set_sampler_textures(struct pipe_context *pipe,
188 unsigned num,
189 struct pipe_texture **texture)
190 {
191 struct brw_context *brw = brw_context(pipe);
192 int i;
193
194 for (i = 0; i < num; i++)
195 pipe_texture_reference(&brw->curr.texture[i], texture[i]);
196
197 for (i = num; i < brw->curr.num_textures; i++)
198 pipe_texture_reference(&brw->curr.texture[i], NULL);
199
200 brw->curr.num_textures = num;
201 brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;
202 }
203
204 static void brw_set_vertex_sampler_textures(struct pipe_context *pipe,
205 unsigned num,
206 struct pipe_texture **texture)
207 {
208 }
209
210 static void brw_bind_vertex_sampler_state(struct pipe_context *pipe,
211 unsigned num, void **sampler)
212 {
213 }
214
215
216 void brw_pipe_sampler_init( struct brw_context *brw )
217 {
218 brw->base.create_sampler_state = brw_create_sampler_state;
219 brw->base.delete_sampler_state = brw_delete_sampler_state;
220
221 brw->base.set_fragment_sampler_textures = brw_set_sampler_textures;
222 brw->base.bind_fragment_sampler_states = brw_bind_sampler_state;
223
224 brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures;
225 brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state;
226
227 }
228 void brw_pipe_sampler_cleanup( struct brw_context *brw )
229 {
230 }