1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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
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 **************************************************************************/
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"
40 #include "state_tracker/sw_winsys.h"
44 llvmpipe_create_sampler_state(struct pipe_context
*pipe
,
45 const struct pipe_sampler_state
*sampler
)
47 return mem_dup(sampler
, sizeof(*sampler
));
52 llvmpipe_bind_sampler_states(struct pipe_context
*pipe
,
53 unsigned num
, void **sampler
)
55 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
58 assert(num
<= PIPE_MAX_SAMPLERS
);
61 if (num
== llvmpipe
->num_samplers
&&
62 !memcmp(llvmpipe
->sampler
, sampler
, num
* sizeof(void *)))
65 draw_flush(llvmpipe
->draw
);
67 for (i
= 0; i
< num
; ++i
)
68 llvmpipe
->sampler
[i
] = sampler
[i
];
69 for (i
= num
; i
< PIPE_MAX_SAMPLERS
; ++i
)
70 llvmpipe
->sampler
[i
] = NULL
;
72 llvmpipe
->num_samplers
= num
;
74 llvmpipe
->dirty
|= LP_NEW_SAMPLER
;
79 llvmpipe_bind_vertex_sampler_states(struct pipe_context
*pipe
,
80 unsigned num_samplers
,
83 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
86 assert(num_samplers
<= PIPE_MAX_VERTEX_SAMPLERS
);
89 if (num_samplers
== llvmpipe
->num_vertex_samplers
&&
90 !memcmp(llvmpipe
->vertex_samplers
, samplers
, num_samplers
* sizeof(void *)))
93 draw_flush(llvmpipe
->draw
);
95 for (i
= 0; i
< num_samplers
; ++i
)
96 llvmpipe
->vertex_samplers
[i
] = samplers
[i
];
97 for (i
= num_samplers
; i
< PIPE_MAX_VERTEX_SAMPLERS
; ++i
)
98 llvmpipe
->vertex_samplers
[i
] = NULL
;
100 llvmpipe
->num_vertex_samplers
= num_samplers
;
102 draw_set_samplers(llvmpipe
->draw
,
103 llvmpipe
->vertex_samplers
,
104 llvmpipe
->num_vertex_samplers
);
106 llvmpipe
->dirty
|= LP_NEW_SAMPLER
;
111 llvmpipe_bind_geometry_sampler_states(struct pipe_context
*pipe
,
112 unsigned num
, void **sampler
)
114 /* XXX: implementation missing */
118 llvmpipe_set_fragment_sampler_views(struct pipe_context
*pipe
,
120 struct pipe_sampler_view
**views
)
122 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
125 assert(num
<= PIPE_MAX_SAMPLERS
);
127 /* Check for no-op */
128 if (num
== llvmpipe
->num_fragment_sampler_views
&&
129 !memcmp(llvmpipe
->fragment_sampler_views
, views
, num
* sizeof(struct pipe_sampler_view
*)))
132 draw_flush(llvmpipe
->draw
);
134 for (i
= 0; i
< PIPE_MAX_SAMPLERS
; i
++) {
135 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
137 pipe_sampler_view_reference(&llvmpipe
->fragment_sampler_views
[i
], view
);
140 llvmpipe
->num_fragment_sampler_views
= num
;
142 llvmpipe
->dirty
|= LP_NEW_SAMPLER_VIEW
;
147 llvmpipe_set_vertex_sampler_views(struct pipe_context
*pipe
,
149 struct pipe_sampler_view
**views
)
151 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
154 assert(num
<= PIPE_MAX_VERTEX_SAMPLERS
);
156 /* Check for no-op */
157 if (num
== llvmpipe
->num_vertex_sampler_views
&&
158 !memcmp(llvmpipe
->vertex_sampler_views
, views
, num
* sizeof(struct pipe_sampler_view
*))) {
162 draw_flush(llvmpipe
->draw
);
164 for (i
= 0; i
< PIPE_MAX_VERTEX_SAMPLERS
; i
++) {
165 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
167 pipe_sampler_view_reference(&llvmpipe
->vertex_sampler_views
[i
], view
);
170 llvmpipe
->num_vertex_sampler_views
= num
;
172 draw_set_sampler_views(llvmpipe
->draw
,
173 llvmpipe
->vertex_sampler_views
,
174 llvmpipe
->num_vertex_sampler_views
);
176 llvmpipe
->dirty
|= LP_NEW_SAMPLER_VIEW
;
181 llvmpipe_set_geometry_sampler_views(struct pipe_context
*pipe
,
183 struct pipe_sampler_view
**views
)
185 /*XXX: implementation missing */
188 static struct pipe_sampler_view
*
189 llvmpipe_create_sampler_view(struct pipe_context
*pipe
,
190 struct pipe_resource
*texture
,
191 const struct pipe_sampler_view
*templ
)
193 struct pipe_sampler_view
*view
= CALLOC_STRUCT(pipe_sampler_view
);
197 view
->reference
.count
= 1;
198 view
->texture
= NULL
;
199 pipe_resource_reference(&view
->texture
, texture
);
200 view
->context
= pipe
;
208 llvmpipe_sampler_view_destroy(struct pipe_context
*pipe
,
209 struct pipe_sampler_view
*view
)
211 pipe_resource_reference(&view
->texture
, NULL
);
217 llvmpipe_delete_sampler_state(struct pipe_context
*pipe
,
225 * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
228 llvmpipe_prepare_vertex_sampling(struct llvmpipe_context
*lp
,
230 struct pipe_sampler_view
**views
)
233 uint32_t row_stride
[DRAW_MAX_TEXTURE_LEVELS
];
234 uint32_t img_stride
[DRAW_MAX_TEXTURE_LEVELS
];
235 const void *data
[DRAW_MAX_TEXTURE_LEVELS
];
237 assert(num
<= PIPE_MAX_VERTEX_SAMPLERS
);
241 for (i
= 0; i
< PIPE_MAX_VERTEX_SAMPLERS
; i
++) {
242 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
245 struct pipe_resource
*tex
= view
->texture
;
246 struct llvmpipe_resource
*lp_tex
= llvmpipe_resource(tex
);
248 /* We're referencing the texture's internal data, so save a
251 pipe_resource_reference(&lp
->mapped_vs_tex
[i
], tex
);
254 /* regular texture - setup array of mipmap level pointers */
256 for (j
= 0; j
<= tex
->last_level
; j
++) {
258 llvmpipe_get_texture_image_all(lp_tex
, j
, LP_TEX_USAGE_READ
,
259 LP_TEX_LAYOUT_LINEAR
);
260 row_stride
[j
] = lp_tex
->row_stride
[j
];
261 img_stride
[j
] = lp_tex
->img_stride
[j
];
265 /* display target texture/surface */
267 * XXX: Where should this be unmapped?
269 struct llvmpipe_screen
*screen
= llvmpipe_screen(tex
->screen
);
270 struct sw_winsys
*winsys
= screen
->winsys
;
271 data
[0] = winsys
->displaytarget_map(winsys
, lp_tex
->dt
,
273 row_stride
[0] = lp_tex
->row_stride
[0];
274 img_stride
[0] = lp_tex
->img_stride
[0];
277 draw_set_mapped_texture(lp
->draw
,
279 tex
->width0
, tex
->height0
, tex
->depth0
,
281 row_stride
, img_stride
, data
);
287 llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context
*ctx
)
290 for (i
= 0; i
< Elements(ctx
->mapped_vs_tex
); i
++) {
291 pipe_resource_reference(&ctx
->mapped_vs_tex
[i
], NULL
);
296 llvmpipe_init_sampler_funcs(struct llvmpipe_context
*llvmpipe
)
298 llvmpipe
->pipe
.create_sampler_state
= llvmpipe_create_sampler_state
;
300 llvmpipe
->pipe
.bind_fragment_sampler_states
= llvmpipe_bind_sampler_states
;
301 llvmpipe
->pipe
.bind_vertex_sampler_states
= llvmpipe_bind_vertex_sampler_states
;
302 llvmpipe
->pipe
.bind_geometry_sampler_states
= llvmpipe_bind_geometry_sampler_states
;
303 llvmpipe
->pipe
.set_fragment_sampler_views
= llvmpipe_set_fragment_sampler_views
;
304 llvmpipe
->pipe
.set_vertex_sampler_views
= llvmpipe_set_vertex_sampler_views
;
305 llvmpipe
->pipe
.set_geometry_sampler_views
= llvmpipe_set_geometry_sampler_views
;
306 llvmpipe
->pipe
.create_sampler_view
= llvmpipe_create_sampler_view
;
307 llvmpipe
->pipe
.sampler_view_destroy
= llvmpipe_sampler_view_destroy
;
308 llvmpipe
->pipe
.delete_sampler_state
= llvmpipe_delete_sampler_state
;