1 /**************************************************************************
3 * Copyright 2007 VMware, Inc.
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 VMWARE 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_memory.h"
33 #include "util/u_inlines.h"
34 #include "util/u_format.h"
36 #include "draw/draw_context.h"
38 #include "sp_context.h"
40 #include "sp_texture.h"
41 #include "sp_tex_sample.h"
42 #include "sp_tex_tile_cache.h"
43 #include "sp_screen.h"
44 #include "state_tracker/sw_winsys.h"
48 * Bind a range [start, start+num-1] of samplers for a shader stage.
51 softpipe_bind_sampler_states(struct pipe_context
*pipe
,
57 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
60 assert(shader
< PIPE_SHADER_TYPES
);
61 assert(start
+ num
<= Elements(softpipe
->samplers
[shader
]));
63 draw_flush(softpipe
->draw
);
65 /* set the new samplers */
66 for (i
= 0; i
< num
; i
++) {
67 softpipe
->samplers
[shader
][start
+ i
] = samplers
[i
];
70 /* find highest non-null samplers[] entry */
72 unsigned j
= MAX2(softpipe
->num_samplers
[shader
], start
+ num
);
73 while (j
> 0 && softpipe
->samplers
[shader
][j
- 1] == NULL
)
75 softpipe
->num_samplers
[shader
] = j
;
78 if (shader
== PIPE_SHADER_VERTEX
|| shader
== PIPE_SHADER_GEOMETRY
) {
79 draw_set_samplers(softpipe
->draw
,
81 softpipe
->samplers
[shader
],
82 softpipe
->num_samplers
[shader
]);
85 softpipe
->dirty
|= SP_NEW_SAMPLER
;
90 softpipe_sampler_view_destroy(struct pipe_context
*pipe
,
91 struct pipe_sampler_view
*view
)
93 pipe_resource_reference(&view
->texture
, NULL
);
99 softpipe_set_sampler_views(struct pipe_context
*pipe
,
103 struct pipe_sampler_view
**views
)
105 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
108 assert(shader
< PIPE_SHADER_TYPES
);
109 assert(start
+ num
<= Elements(softpipe
->sampler_views
[shader
]));
111 draw_flush(softpipe
->draw
);
113 /* set the new sampler views */
114 for (i
= 0; i
< num
; i
++) {
115 struct sp_sampler_view
*sp_sviewsrc
;
116 struct sp_sampler_view
*sp_sviewdst
=
117 &softpipe
->tgsi
.sampler
[shader
]->sp_sview
[start
+ i
];
118 struct pipe_sampler_view
**pview
= &softpipe
->sampler_views
[shader
][start
+ i
];
119 pipe_sampler_view_reference(pview
, views
[i
]);
120 sp_tex_tile_cache_set_sampler_view(softpipe
->tex_cache
[shader
][start
+ i
],
123 * We don't really have variants, however some bits are different per shader,
126 sp_sviewsrc
= (struct sp_sampler_view
*)*pview
;
128 memcpy(sp_sviewdst
, sp_sviewsrc
, sizeof(*sp_sviewsrc
));
129 sp_sviewdst
->compute_lambda
= softpipe_get_lambda_func(&sp_sviewdst
->base
, shader
);
130 sp_sviewdst
->cache
= softpipe
->tex_cache
[shader
][start
+ i
];
133 memset(sp_sviewdst
, 0, sizeof(*sp_sviewsrc
));
138 /* find highest non-null sampler_views[] entry */
140 unsigned j
= MAX2(softpipe
->num_sampler_views
[shader
], start
+ num
);
141 while (j
> 0 && softpipe
->sampler_views
[shader
][j
- 1] == NULL
)
143 softpipe
->num_sampler_views
[shader
] = j
;
146 if (shader
== PIPE_SHADER_VERTEX
|| shader
== PIPE_SHADER_GEOMETRY
) {
147 draw_set_sampler_views(softpipe
->draw
,
149 softpipe
->sampler_views
[shader
],
150 softpipe
->num_sampler_views
[shader
]);
153 softpipe
->dirty
|= SP_NEW_TEXTURE
;
158 softpipe_delete_sampler_state(struct pipe_context
*pipe
,
166 prepare_shader_sampling(
167 struct softpipe_context
*sp
,
169 struct pipe_sampler_view
**views
,
170 unsigned shader_type
,
171 struct pipe_resource
*mapped_tex
[PIPE_MAX_SHADER_SAMPLER_VIEWS
])
175 uint32_t row_stride
[PIPE_MAX_TEXTURE_LEVELS
];
176 uint32_t img_stride
[PIPE_MAX_TEXTURE_LEVELS
];
177 uint32_t mip_offsets
[PIPE_MAX_TEXTURE_LEVELS
];
180 assert(num
<= PIPE_MAX_SHADER_SAMPLER_VIEWS
);
184 for (i
= 0; i
< PIPE_MAX_SHADER_SAMPLER_VIEWS
; i
++) {
185 struct pipe_sampler_view
*view
= i
< num
? views
[i
] : NULL
;
188 struct pipe_resource
*tex
= view
->texture
;
189 struct softpipe_resource
*sp_tex
= softpipe_resource(tex
);
190 unsigned width0
= tex
->width0
;
191 unsigned num_layers
= tex
->depth0
;
192 unsigned first_level
= 0;
193 unsigned last_level
= 0;
195 /* We're referencing the texture's internal data, so save a
198 pipe_resource_reference(&mapped_tex
[i
], tex
);
201 /* regular texture - setup array of mipmap level offsets */
202 struct pipe_resource
*res
= view
->texture
;
205 if (view
->target
!= PIPE_BUFFER
) {
206 first_level
= view
->u
.tex
.first_level
;
207 last_level
= view
->u
.tex
.last_level
;
208 assert(first_level
<= last_level
);
209 assert(last_level
<= res
->last_level
);
212 for (j
= first_level
; j
<= last_level
; j
++) {
213 mip_offsets
[j
] = sp_tex
->level_offset
[j
];
214 row_stride
[j
] = sp_tex
->stride
[j
];
215 img_stride
[j
] = sp_tex
->img_stride
[j
];
217 if (tex
->target
== PIPE_TEXTURE_1D_ARRAY
||
218 tex
->target
== PIPE_TEXTURE_2D_ARRAY
||
219 tex
->target
== PIPE_TEXTURE_CUBE
||
220 tex
->target
== PIPE_TEXTURE_CUBE_ARRAY
) {
221 num_layers
= view
->u
.tex
.last_layer
- view
->u
.tex
.first_layer
+ 1;
222 for (j
= first_level
; j
<= last_level
; j
++) {
223 mip_offsets
[j
] += view
->u
.tex
.first_layer
*
224 sp_tex
->img_stride
[j
];
226 if (view
->target
== PIPE_TEXTURE_CUBE
||
227 view
->target
== PIPE_TEXTURE_CUBE_ARRAY
) {
228 assert(num_layers
% 6 == 0);
230 assert(view
->u
.tex
.first_layer
<= view
->u
.tex
.last_layer
);
231 assert(view
->u
.tex
.last_layer
< res
->array_size
);
235 unsigned view_blocksize
= util_format_get_blocksize(view
->format
);
237 /* probably don't really need to fill that out */
242 /* everything specified in number of elements here. */
243 width0
= view
->u
.buf
.last_element
- view
->u
.buf
.first_element
+ 1;
244 addr
= (uint8_t *)addr
+ view
->u
.buf
.first_element
*
246 assert(view
->u
.buf
.first_element
<= view
->u
.buf
.last_element
);
247 assert(view
->u
.buf
.last_element
* view_blocksize
< res
->width0
);
251 /* display target texture/surface */
253 * XXX: Where should this be unmapped?
255 struct softpipe_screen
*screen
= softpipe_screen(tex
->screen
);
256 struct sw_winsys
*winsys
= screen
->winsys
;
257 addr
= winsys
->displaytarget_map(winsys
, sp_tex
->dt
,
259 row_stride
[0] = sp_tex
->stride
[0];
260 img_stride
[0] = sp_tex
->img_stride
[0];
264 draw_set_mapped_texture(sp
->draw
,
267 width0
, tex
->height0
, num_layers
,
268 first_level
, last_level
,
270 row_stride
, img_stride
, mip_offsets
);
277 * Called during state validation when SP_NEW_TEXTURE is set.
280 softpipe_prepare_vertex_sampling(struct softpipe_context
*sp
,
282 struct pipe_sampler_view
**views
)
284 prepare_shader_sampling(sp
, num
, views
, PIPE_SHADER_VERTEX
,
289 softpipe_cleanup_vertex_sampling(struct softpipe_context
*ctx
)
292 for (i
= 0; i
< Elements(ctx
->mapped_vs_tex
); i
++) {
293 pipe_resource_reference(&ctx
->mapped_vs_tex
[i
], NULL
);
299 * Called during state validation when SP_NEW_TEXTURE is set.
302 softpipe_prepare_geometry_sampling(struct softpipe_context
*sp
,
304 struct pipe_sampler_view
**views
)
306 prepare_shader_sampling(sp
, num
, views
, PIPE_SHADER_GEOMETRY
,
311 softpipe_cleanup_geometry_sampling(struct softpipe_context
*ctx
)
314 for (i
= 0; i
< Elements(ctx
->mapped_gs_tex
); i
++) {
315 pipe_resource_reference(&ctx
->mapped_gs_tex
[i
], NULL
);
321 softpipe_init_sampler_funcs(struct pipe_context
*pipe
)
323 pipe
->create_sampler_state
= softpipe_create_sampler_state
;
324 pipe
->bind_sampler_states
= softpipe_bind_sampler_states
;
325 pipe
->delete_sampler_state
= softpipe_delete_sampler_state
;
327 pipe
->create_sampler_view
= softpipe_create_sampler_view
;
328 pipe
->set_sampler_views
= softpipe_set_sampler_views
;
329 pipe
->sampler_view_destroy
= softpipe_sampler_view_destroy
;