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