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 **************************************************************************/
28 #include "util/u_rect.h"
29 #include "util/u_surface.h"
30 #include "lp_context.h"
32 #include "lp_limits.h"
33 #include "lp_surface.h"
34 #include "lp_texture.h"
39 lp_resource_copy_ms(struct pipe_context
*pipe
,
40 struct pipe_resource
*dst
, unsigned dst_level
,
41 unsigned dstx
, unsigned dsty
, unsigned dstz
,
42 struct pipe_resource
*src
, unsigned src_level
,
43 const struct pipe_box
*src_box
)
45 struct pipe_box dst_box
= *src_box
;
46 enum pipe_format src_format
;
51 src_format
= src
->format
;
53 for (unsigned i
= 0; i
< src
->nr_samples
; i
++) {
54 struct pipe_transfer
*src_trans
, *dst_trans
;
55 const uint8_t *src_map
= llvmpipe_transfer_map_ms(pipe
,
56 src
, 0, PIPE_TRANSFER_READ
, i
,
62 uint8_t *dst_map
= llvmpipe_transfer_map_ms(pipe
,
63 dst
, 0, PIPE_TRANSFER_WRITE
, i
,
67 pipe
->transfer_unmap(pipe
, src_trans
);
71 util_copy_box(dst_map
,
73 dst_trans
->stride
, dst_trans
->layer_stride
,
75 src_box
->width
, src_box
->height
, src_box
->depth
,
77 src_trans
->stride
, src_trans
->layer_stride
,
79 pipe
->transfer_unmap(pipe
, dst_trans
);
80 pipe
->transfer_unmap(pipe
, src_trans
);
84 lp_resource_copy(struct pipe_context
*pipe
,
85 struct pipe_resource
*dst
, unsigned dst_level
,
86 unsigned dstx
, unsigned dsty
, unsigned dstz
,
87 struct pipe_resource
*src
, unsigned src_level
,
88 const struct pipe_box
*src_box
)
90 llvmpipe_flush_resource(pipe
,
92 FALSE
, /* read_only */
93 TRUE
, /* cpu_access */
94 FALSE
, /* do_not_block */
97 llvmpipe_flush_resource(pipe
,
100 TRUE
, /* cpu_access */
101 FALSE
, /* do_not_block */
104 if (dst
->nr_samples
> 1 &&
105 dst
->nr_samples
== src
->nr_samples
) {
106 lp_resource_copy_ms(pipe
, dst
, dst_level
, dstx
, dsty
, dstz
,
107 src
, src_level
, src_box
);
110 util_resource_copy_region(pipe
, dst
, dst_level
, dstx
, dsty
, dstz
,
111 src
, src_level
, src_box
);
115 static void lp_blit(struct pipe_context
*pipe
,
116 const struct pipe_blit_info
*blit_info
)
118 struct llvmpipe_context
*lp
= llvmpipe_context(pipe
);
119 struct pipe_blit_info info
= *blit_info
;
121 if (blit_info
->render_condition_enable
&& !llvmpipe_check_render_cond(lp
))
124 if (util_try_blit_via_copy_region(pipe
, &info
)) {
128 if (!util_blitter_is_blit_supported(lp
->blitter
, &info
)) {
129 debug_printf("llvmpipe: blit unsupported %s -> %s\n",
130 util_format_short_name(info
.src
.resource
->format
),
131 util_format_short_name(info
.dst
.resource
->format
));
135 /* for 32-bit unorm depth, avoid the conversions to float and back,
136 which can introduce accuracy errors. */
137 if (blit_info
->src
.format
== PIPE_FORMAT_Z32_UNORM
&&
138 blit_info
->dst
.format
== PIPE_FORMAT_Z32_UNORM
&& info
.filter
== PIPE_TEX_FILTER_NEAREST
) {
139 info
.src
.format
= PIPE_FORMAT_R32_UINT
;
140 info
.dst
.format
= PIPE_FORMAT_R32_UINT
;
141 info
.mask
= PIPE_MASK_R
;
144 /* XXX turn off occlusion and streamout queries */
146 util_blitter_save_vertex_buffer_slot(lp
->blitter
, lp
->vertex_buffer
);
147 util_blitter_save_vertex_elements(lp
->blitter
, (void*)lp
->velems
);
148 util_blitter_save_vertex_shader(lp
->blitter
, (void*)lp
->vs
);
149 util_blitter_save_geometry_shader(lp
->blitter
, (void*)lp
->gs
);
150 util_blitter_save_so_targets(lp
->blitter
, lp
->num_so_targets
,
151 (struct pipe_stream_output_target
**)lp
->so_targets
);
152 util_blitter_save_rasterizer(lp
->blitter
, (void*)lp
->rasterizer
);
153 util_blitter_save_viewport(lp
->blitter
, &lp
->viewports
[0]);
154 util_blitter_save_scissor(lp
->blitter
, &lp
->scissors
[0]);
155 util_blitter_save_fragment_shader(lp
->blitter
, lp
->fs
);
156 util_blitter_save_blend(lp
->blitter
, (void*)lp
->blend
);
157 util_blitter_save_tessctrl_shader(lp
->blitter
, (void*)lp
->tcs
);
158 util_blitter_save_tesseval_shader(lp
->blitter
, (void*)lp
->tes
);
159 util_blitter_save_depth_stencil_alpha(lp
->blitter
, (void*)lp
->depth_stencil
);
160 util_blitter_save_stencil_ref(lp
->blitter
, &lp
->stencil_ref
);
161 util_blitter_save_sample_mask(lp
->blitter
, lp
->sample_mask
);
162 util_blitter_save_framebuffer(lp
->blitter
, &lp
->framebuffer
);
163 util_blitter_save_fragment_sampler_states(lp
->blitter
,
164 lp
->num_samplers
[PIPE_SHADER_FRAGMENT
],
165 (void**)lp
->samplers
[PIPE_SHADER_FRAGMENT
]);
166 util_blitter_save_fragment_sampler_views(lp
->blitter
,
167 lp
->num_sampler_views
[PIPE_SHADER_FRAGMENT
],
168 lp
->sampler_views
[PIPE_SHADER_FRAGMENT
]);
169 util_blitter_save_render_condition(lp
->blitter
, lp
->render_cond_query
,
170 lp
->render_cond_cond
, lp
->render_cond_mode
);
171 util_blitter_blit(lp
->blitter
, &info
);
176 lp_flush_resource(struct pipe_context
*ctx
, struct pipe_resource
*resource
)
181 static struct pipe_surface
*
182 llvmpipe_create_surface(struct pipe_context
*pipe
,
183 struct pipe_resource
*pt
,
184 const struct pipe_surface
*surf_tmpl
)
186 struct pipe_surface
*ps
;
188 if (!(pt
->bind
& (PIPE_BIND_DEPTH_STENCIL
| PIPE_BIND_RENDER_TARGET
))) {
189 debug_printf("Illegal surface creation without bind flag\n");
190 if (util_format_is_depth_or_stencil(surf_tmpl
->format
)) {
191 pt
->bind
|= PIPE_BIND_DEPTH_STENCIL
;
194 pt
->bind
|= PIPE_BIND_RENDER_TARGET
;
198 ps
= CALLOC_STRUCT(pipe_surface
);
200 pipe_reference_init(&ps
->reference
, 1);
201 pipe_resource_reference(&ps
->texture
, pt
);
203 ps
->format
= surf_tmpl
->format
;
204 if (llvmpipe_resource_is_texture(pt
)) {
205 assert(surf_tmpl
->u
.tex
.level
<= pt
->last_level
);
206 assert(surf_tmpl
->u
.tex
.first_layer
<= surf_tmpl
->u
.tex
.last_layer
);
207 ps
->width
= u_minify(pt
->width0
, surf_tmpl
->u
.tex
.level
);
208 ps
->height
= u_minify(pt
->height0
, surf_tmpl
->u
.tex
.level
);
209 ps
->u
.tex
.level
= surf_tmpl
->u
.tex
.level
;
210 ps
->u
.tex
.first_layer
= surf_tmpl
->u
.tex
.first_layer
;
211 ps
->u
.tex
.last_layer
= surf_tmpl
->u
.tex
.last_layer
;
214 /* setting width as number of elements should get us correct renderbuffer width */
215 ps
->width
= surf_tmpl
->u
.buf
.last_element
- surf_tmpl
->u
.buf
.first_element
+ 1;
216 ps
->height
= pt
->height0
;
217 ps
->u
.buf
.first_element
= surf_tmpl
->u
.buf
.first_element
;
218 ps
->u
.buf
.last_element
= surf_tmpl
->u
.buf
.last_element
;
219 assert(ps
->u
.buf
.first_element
<= ps
->u
.buf
.last_element
);
220 assert(util_format_get_blocksize(surf_tmpl
->format
) *
221 (ps
->u
.buf
.last_element
+ 1) <= pt
->width0
);
229 llvmpipe_surface_destroy(struct pipe_context
*pipe
,
230 struct pipe_surface
*surf
)
232 /* Effectively do the texture_update work here - if texture images
233 * needed post-processing to put them into hardware layout, this is
234 * where it would happen. For llvmpipe, nothing to do.
236 assert(surf
->texture
);
237 pipe_resource_reference(&surf
->texture
, NULL
);
244 llvmpipe_get_sample_position(struct pipe_context
*pipe
,
245 unsigned sample_count
,
246 unsigned sample_index
,
249 switch (sample_count
) {
251 out_value
[0] = lp_sample_pos_4x
[sample_index
][0];
252 out_value
[1] = lp_sample_pos_4x
[sample_index
][1];
260 lp_clear_color_texture_helper(struct pipe_transfer
*dst_trans
,
262 enum pipe_format format
,
263 const union pipe_color_union
*color
,
264 unsigned width
, unsigned height
, unsigned depth
)
268 assert(dst_trans
->stride
> 0);
270 util_pack_color_union(format
, &uc
, color
);
272 util_fill_box(dst_map
, format
,
273 dst_trans
->stride
, dst_trans
->layer_stride
,
274 0, 0, 0, width
, height
, depth
, &uc
);
278 lp_clear_color_texture_msaa(struct pipe_context
*pipe
,
279 struct pipe_resource
*texture
,
280 enum pipe_format format
,
281 const union pipe_color_union
*color
,
283 const struct pipe_box
*box
)
285 struct pipe_transfer
*dst_trans
;
288 dst_map
= llvmpipe_transfer_map_ms(pipe
, texture
, 0, PIPE_TRANSFER_WRITE
,
289 sample
, box
, &dst_trans
);
293 if (dst_trans
->stride
> 0) {
294 lp_clear_color_texture_helper(dst_trans
, dst_map
, format
, color
,
295 box
->width
, box
->height
, box
->depth
);
297 pipe
->transfer_unmap(pipe
, dst_trans
);
301 llvmpipe_clear_render_target(struct pipe_context
*pipe
,
302 struct pipe_surface
*dst
,
303 const union pipe_color_union
*color
,
304 unsigned dstx
, unsigned dsty
,
305 unsigned width
, unsigned height
,
306 bool render_condition_enabled
)
308 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
310 if (render_condition_enabled
&& !llvmpipe_check_render_cond(llvmpipe
))
313 if (dst
->texture
->nr_samples
> 1) {
315 u_box_2d(dstx
, dsty
, width
, height
, &box
);
316 for (unsigned s
= 0; s
< util_res_sample_count(dst
->texture
); s
++) {
317 lp_clear_color_texture_msaa(pipe
, dst
->texture
, dst
->format
,
321 util_clear_render_target(pipe
, dst
, color
,
322 dstx
, dsty
, width
, height
);
327 lp_clear_depth_stencil_texture_msaa(struct pipe_context
*pipe
,
328 struct pipe_resource
*texture
,
329 enum pipe_format format
,
330 unsigned clear_flags
,
331 uint64_t zstencil
, unsigned sample
,
332 const struct pipe_box
*box
)
334 struct pipe_transfer
*dst_trans
;
336 boolean need_rmw
= FALSE
;
338 if ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) &&
339 ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) != PIPE_CLEAR_DEPTHSTENCIL
) &&
340 util_format_is_depth_and_stencil(format
))
343 dst_map
= llvmpipe_transfer_map_ms(pipe
,
346 (need_rmw
? PIPE_TRANSFER_READ_WRITE
:
347 PIPE_TRANSFER_WRITE
),
348 sample
, box
, &dst_trans
);
353 assert(dst_trans
->stride
> 0);
355 util_fill_zs_box(dst_map
, format
, need_rmw
, clear_flags
,
356 dst_trans
->stride
, dst_trans
->layer_stride
,
357 box
->width
, box
->height
, box
->depth
, zstencil
);
359 pipe
->transfer_unmap(pipe
, dst_trans
);
363 llvmpipe_clear_depth_stencil(struct pipe_context
*pipe
,
364 struct pipe_surface
*dst
,
365 unsigned clear_flags
,
368 unsigned dstx
, unsigned dsty
,
369 unsigned width
, unsigned height
,
370 bool render_condition_enabled
)
372 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
374 if (render_condition_enabled
&& !llvmpipe_check_render_cond(llvmpipe
))
377 if (dst
->texture
->nr_samples
> 1) {
378 uint64_t zstencil
= util_pack64_z_stencil(dst
->format
, depth
, stencil
);
380 u_box_2d(dstx
, dsty
, width
, height
, &box
);
381 for (unsigned s
= 0; s
< util_res_sample_count(dst
->texture
); s
++)
382 lp_clear_depth_stencil_texture_msaa(pipe
, dst
->texture
,
383 dst
->format
, clear_flags
,
386 util_clear_depth_stencil(pipe
, dst
, clear_flags
,
388 dstx
, dsty
, width
, height
);
392 llvmpipe_clear_texture(struct pipe_context
*pipe
,
393 struct pipe_resource
*tex
,
395 const struct pipe_box
*box
,
398 const struct util_format_description
*desc
=
399 util_format_description(tex
->format
);
400 if (tex
->nr_samples
<= 1) {
401 util_clear_texture(pipe
, tex
, level
, box
, data
);
404 union pipe_color_union color
;
406 if (util_format_is_depth_or_stencil(tex
->format
)) {
412 if (util_format_has_depth(desc
)) {
413 clear
|= PIPE_CLEAR_DEPTH
;
414 util_format_unpack_z_float(tex
->format
, &depth
, data
, 1);
417 if (util_format_has_stencil(desc
)) {
418 clear
|= PIPE_CLEAR_STENCIL
;
419 util_format_unpack_s_8uint(tex
->format
, &stencil
, data
, 1);
422 zstencil
= util_pack64_z_stencil(tex
->format
, depth
, stencil
);
424 for (unsigned s
= 0; s
< util_res_sample_count(tex
); s
++)
425 lp_clear_depth_stencil_texture_msaa(pipe
, tex
, tex
->format
, clear
, zstencil
,
428 util_format_unpack_rgba(tex
->format
, color
.ui
, data
, 1);
430 for (unsigned s
= 0; s
< util_res_sample_count(tex
); s
++) {
431 lp_clear_color_texture_msaa(pipe
, tex
, tex
->format
, &color
, s
,
438 llvmpipe_init_surface_functions(struct llvmpipe_context
*lp
)
440 lp
->pipe
.clear_render_target
= llvmpipe_clear_render_target
;
441 lp
->pipe
.clear_depth_stencil
= llvmpipe_clear_depth_stencil
;
442 lp
->pipe
.create_surface
= llvmpipe_create_surface
;
443 lp
->pipe
.surface_destroy
= llvmpipe_surface_destroy
;
444 /* These are not actually functions dealing with surfaces */
445 lp
->pipe
.clear_texture
= llvmpipe_clear_texture
;
446 lp
->pipe
.resource_copy_region
= lp_resource_copy
;
447 lp
->pipe
.blit
= lp_blit
;
448 lp
->pipe
.flush_resource
= lp_flush_resource
;
449 lp
->pipe
.get_sample_position
= llvmpipe_get_sample_position
;