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
,
52 enum pipe_shader_type shader
,
57 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
60 assert(shader
< PIPE_SHADER_TYPES
);
61 assert(start
+ num
<= ARRAY_SIZE(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
,
100 enum pipe_shader_type shader
,
103 struct pipe_sampler_view
**views
)
105 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
108 assert(shader
< PIPE_SHADER_TYPES
);
109 assert(start
+ num
<= ARRAY_SIZE(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
->compute_lambda_from_grad
= softpipe_get_lambda_from_grad_func(&sp_sviewdst
->base
, shader
);
131 sp_sviewdst
->cache
= softpipe
->tex_cache
[shader
][start
+ i
];
134 memset(sp_sviewdst
, 0, sizeof(*sp_sviewsrc
));
139 /* find highest non-null sampler_views[] entry */
141 unsigned j
= MAX2(softpipe
->num_sampler_views
[shader
], start
+ num
);
142 while (j
> 0 && softpipe
->sampler_views
[shader
][j
- 1] == NULL
)
144 softpipe
->num_sampler_views
[shader
] = j
;
147 if (shader
== PIPE_SHADER_VERTEX
|| shader
== PIPE_SHADER_GEOMETRY
) {
148 draw_set_sampler_views(softpipe
->draw
,
150 softpipe
->sampler_views
[shader
],
151 softpipe
->num_sampler_views
[shader
]);
154 softpipe
->dirty
|= SP_NEW_TEXTURE
;
159 softpipe_delete_sampler_state(struct pipe_context
*pipe
,
167 prepare_shader_sampling(
168 struct softpipe_context
*sp
,
170 struct pipe_sampler_view
**views
,
171 enum pipe_shader_type shader_type
,
172 struct pipe_resource
*mapped_tex
[PIPE_MAX_SHADER_SAMPLER_VIEWS
])
176 uint32_t row_stride
[PIPE_MAX_TEXTURE_LEVELS
];
177 uint32_t img_stride
[PIPE_MAX_TEXTURE_LEVELS
];
178 uint32_t mip_offsets
[PIPE_MAX_TEXTURE_LEVELS
];
181 assert(num
<= PIPE_MAX_SHADER_SAMPLER_VIEWS
);
185 for (i
= 0; i
< num
; i
++) {
186 struct pipe_sampler_view
*view
= views
[i
];
189 struct pipe_resource
*tex
= view
->texture
;
190 struct softpipe_resource
*sp_tex
= softpipe_resource(tex
);
191 unsigned width0
= tex
->width0
;
192 unsigned num_layers
= tex
->depth0
;
193 unsigned first_level
= 0;
194 unsigned last_level
= 0;
196 /* We're referencing the texture's internal data, so save a
199 pipe_resource_reference(&mapped_tex
[i
], tex
);
202 /* regular texture - setup array of mipmap level offsets */
203 ASSERTED
struct pipe_resource
*res
= view
->texture
;
206 if (view
->target
!= PIPE_BUFFER
) {
207 first_level
= view
->u
.tex
.first_level
;
208 last_level
= view
->u
.tex
.last_level
;
209 assert(first_level
<= last_level
);
210 assert(last_level
<= res
->last_level
);
213 for (j
= first_level
; j
<= last_level
; j
++) {
214 mip_offsets
[j
] = sp_tex
->level_offset
[j
];
215 row_stride
[j
] = sp_tex
->stride
[j
];
216 img_stride
[j
] = sp_tex
->img_stride
[j
];
218 if (tex
->target
== PIPE_TEXTURE_1D_ARRAY
||
219 tex
->target
== PIPE_TEXTURE_2D_ARRAY
||
220 tex
->target
== PIPE_TEXTURE_CUBE
||
221 tex
->target
== PIPE_TEXTURE_CUBE_ARRAY
) {
222 num_layers
= view
->u
.tex
.last_layer
- view
->u
.tex
.first_layer
+ 1;
223 for (j
= first_level
; j
<= last_level
; j
++) {
224 mip_offsets
[j
] += view
->u
.tex
.first_layer
*
225 sp_tex
->img_stride
[j
];
227 if (view
->target
== PIPE_TEXTURE_CUBE
||
228 view
->target
== PIPE_TEXTURE_CUBE_ARRAY
) {
229 assert(num_layers
% 6 == 0);
231 assert(view
->u
.tex
.first_layer
<= view
->u
.tex
.last_layer
);
232 assert(view
->u
.tex
.last_layer
< res
->array_size
);
236 unsigned view_blocksize
= util_format_get_blocksize(view
->format
);
238 /* probably don't really need to fill that out */
243 /* everything specified in number of elements here. */
244 width0
= view
->u
.buf
.size
/ view_blocksize
;
245 addr
= (uint8_t *)addr
+ view
->u
.buf
.offset
;
246 assert(view
->u
.buf
.offset
+ view
->u
.buf
.size
<= res
->width0
);
250 /* display target texture/surface */
252 * XXX: Where should this be unmapped?
254 struct softpipe_screen
*screen
= softpipe_screen(tex
->screen
);
255 struct sw_winsys
*winsys
= screen
->winsys
;
256 addr
= winsys
->displaytarget_map(winsys
, sp_tex
->dt
,
258 row_stride
[0] = sp_tex
->stride
[0];
259 img_stride
[0] = sp_tex
->img_stride
[0];
263 draw_set_mapped_texture(sp
->draw
,
266 width0
, tex
->height0
, num_layers
,
267 first_level
, last_level
,
269 row_stride
, img_stride
, mip_offsets
);
276 * Called during state validation when SP_NEW_TEXTURE is set.
279 softpipe_prepare_vertex_sampling(struct softpipe_context
*sp
,
281 struct pipe_sampler_view
**views
)
283 prepare_shader_sampling(sp
, num
, views
, PIPE_SHADER_VERTEX
,
288 softpipe_cleanup_vertex_sampling(struct softpipe_context
*ctx
)
291 for (i
= 0; i
< ARRAY_SIZE(ctx
->mapped_vs_tex
); i
++) {
292 pipe_resource_reference(&ctx
->mapped_vs_tex
[i
], NULL
);
298 * Called during state validation when SP_NEW_TEXTURE is set.
301 softpipe_prepare_geometry_sampling(struct softpipe_context
*sp
,
303 struct pipe_sampler_view
**views
)
305 prepare_shader_sampling(sp
, num
, views
, PIPE_SHADER_GEOMETRY
,
310 softpipe_cleanup_geometry_sampling(struct softpipe_context
*ctx
)
313 for (i
= 0; i
< ARRAY_SIZE(ctx
->mapped_gs_tex
); i
++) {
314 pipe_resource_reference(&ctx
->mapped_gs_tex
[i
], NULL
);
320 softpipe_init_sampler_funcs(struct pipe_context
*pipe
)
322 pipe
->create_sampler_state
= softpipe_create_sampler_state
;
323 pipe
->bind_sampler_states
= softpipe_bind_sampler_states
;
324 pipe
->delete_sampler_state
= softpipe_delete_sampler_state
;
326 pipe
->create_sampler_view
= softpipe_create_sampler_view
;
327 pipe
->set_sampler_views
= softpipe_set_sampler_views
;
328 pipe
->sampler_view_destroy
= softpipe_sampler_view_destroy
;