g3dvl: Use sobel filter for chroma interpolation
[mesa/nouveau-pmpeg.git] / src / gallium / drivers / llvmpipe / lp_state_sampler.c
blobdf9fb89cc8ec38eb983ae9b5f60172d5c580fce7
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 /* Authors:
29 * Brian Paul
32 #include "util/u_inlines.h"
33 #include "util/u_memory.h"
35 #include "draw/draw_context.h"
37 #include "lp_context.h"
38 #include "lp_screen.h"
39 #include "lp_state.h"
40 #include "lp_debug.h"
41 #include "state_tracker/sw_winsys.h"
44 static void *
45 llvmpipe_create_sampler_state(struct pipe_context *pipe,
46 const struct pipe_sampler_state *sampler)
48 struct pipe_sampler_state *state = mem_dup(sampler, sizeof *sampler);
50 if (LP_PERF & PERF_NO_MIP_LINEAR) {
51 if (state->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR)
52 state->min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
55 if (LP_PERF & PERF_NO_MIPMAPS)
56 state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
58 if (LP_PERF & PERF_NO_LINEAR) {
59 state->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
60 state->min_img_filter = PIPE_TEX_FILTER_NEAREST;
63 return state;
67 static void
68 llvmpipe_bind_sampler_states(struct pipe_context *pipe,
69 unsigned num, void **sampler)
71 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
72 unsigned i;
74 assert(num <= PIPE_MAX_SAMPLERS);
76 /* Check for no-op */
77 if (num == llvmpipe->num_samplers &&
78 !memcmp(llvmpipe->sampler, sampler, num * sizeof(void *)))
79 return;
81 draw_flush(llvmpipe->draw);
83 for (i = 0; i < num; ++i)
84 llvmpipe->sampler[i] = sampler[i];
85 for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
86 llvmpipe->sampler[i] = NULL;
88 llvmpipe->num_samplers = num;
90 llvmpipe->dirty |= LP_NEW_SAMPLER;
94 static void
95 llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
96 unsigned num_samplers,
97 void **samplers)
99 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
100 unsigned i;
102 assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
104 /* Check for no-op */
105 if (num_samplers == llvmpipe->num_vertex_samplers &&
106 !memcmp(llvmpipe->vertex_samplers, samplers, num_samplers * sizeof(void *)))
107 return;
109 draw_flush(llvmpipe->draw);
111 for (i = 0; i < num_samplers; ++i)
112 llvmpipe->vertex_samplers[i] = samplers[i];
113 for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
114 llvmpipe->vertex_samplers[i] = NULL;
116 llvmpipe->num_vertex_samplers = num_samplers;
118 draw_set_samplers(llvmpipe->draw,
119 llvmpipe->vertex_samplers,
120 llvmpipe->num_vertex_samplers);
122 llvmpipe->dirty |= LP_NEW_SAMPLER;
126 static void
127 llvmpipe_bind_geometry_sampler_states(struct pipe_context *pipe,
128 unsigned num, void **sampler)
130 /* XXX: implementation missing */
133 static void
134 llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
135 unsigned num,
136 struct pipe_sampler_view **views)
138 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
139 uint i;
141 assert(num <= PIPE_MAX_SAMPLERS);
143 /* Check for no-op */
144 if (num == llvmpipe->num_fragment_sampler_views &&
145 !memcmp(llvmpipe->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
146 return;
148 draw_flush(llvmpipe->draw);
150 for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
151 struct pipe_sampler_view *view = i < num ? views[i] : NULL;
153 pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], view);
156 llvmpipe->num_fragment_sampler_views = num;
158 llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
162 static void
163 llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
164 unsigned num,
165 struct pipe_sampler_view **views)
167 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
168 uint i;
170 assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
172 /* Check for no-op */
173 if (num == llvmpipe->num_vertex_sampler_views &&
174 !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
175 return;
178 draw_flush(llvmpipe->draw);
180 for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
181 struct pipe_sampler_view *view = i < num ? views[i] : NULL;
183 pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view);
186 llvmpipe->num_vertex_sampler_views = num;
188 draw_set_sampler_views(llvmpipe->draw,
189 llvmpipe->vertex_sampler_views,
190 llvmpipe->num_vertex_sampler_views);
192 llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
196 static void
197 llvmpipe_set_geometry_sampler_views(struct pipe_context *pipe,
198 unsigned num,
199 struct pipe_sampler_view **views)
201 /*XXX: implementation missing */
204 static struct pipe_sampler_view *
205 llvmpipe_create_sampler_view(struct pipe_context *pipe,
206 struct pipe_resource *texture,
207 const struct pipe_sampler_view *templ)
209 struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
211 if (view) {
212 *view = *templ;
213 view->reference.count = 1;
214 view->texture = NULL;
215 pipe_resource_reference(&view->texture, texture);
216 view->context = pipe;
219 return view;
223 static void
224 llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
225 struct pipe_sampler_view *view)
227 pipe_resource_reference(&view->texture, NULL);
228 FREE(view);
232 static void
233 llvmpipe_delete_sampler_state(struct pipe_context *pipe,
234 void *sampler)
236 FREE( sampler );
241 * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
243 void
244 llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
245 unsigned num,
246 struct pipe_sampler_view **views)
248 unsigned i;
249 uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
250 uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
251 const void *data[PIPE_MAX_TEXTURE_LEVELS];
253 assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
254 if (!num)
255 return;
257 for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
258 struct pipe_sampler_view *view = i < num ? views[i] : NULL;
260 if (view) {
261 struct pipe_resource *tex = view->texture;
262 struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
264 /* We're referencing the texture's internal data, so save a
265 * reference to it.
267 pipe_resource_reference(&lp->mapped_vs_tex[i], tex);
269 if (!lp_tex->dt) {
270 /* regular texture - setup array of mipmap level pointers */
271 int j;
272 for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
273 data[j] =
274 llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
275 LP_TEX_LAYOUT_LINEAR);
276 row_stride[j] = lp_tex->row_stride[j];
277 img_stride[j] = lp_tex->img_stride[j];
280 else {
281 /* display target texture/surface */
283 * XXX: Where should this be unmapped?
285 struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
286 struct sw_winsys *winsys = screen->winsys;
287 data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
288 PIPE_TRANSFER_READ);
289 row_stride[0] = lp_tex->row_stride[0];
290 img_stride[0] = lp_tex->img_stride[0];
291 assert(data[0]);
293 draw_set_mapped_texture(lp->draw,
295 tex->width0, tex->height0, tex->depth0,
296 view->u.tex.first_level, tex->last_level,
297 row_stride, img_stride, data);
302 void
303 llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
305 unsigned i;
306 for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
307 pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
311 void
312 llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
314 llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
316 llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
317 llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
318 llvmpipe->pipe.bind_geometry_sampler_states = llvmpipe_bind_geometry_sampler_states;
319 llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
320 llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
321 llvmpipe->pipe.set_geometry_sampler_views = llvmpipe_set_geometry_sampler_views;
322 llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
323 llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
324 llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;