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 /* XXX turn off occlusion and streamout queries */
137 util_blitter_save_vertex_buffer_slot(lp
->blitter
, lp
->vertex_buffer
);
138 util_blitter_save_vertex_elements(lp
->blitter
, (void*)lp
->velems
);
139 util_blitter_save_vertex_shader(lp
->blitter
, (void*)lp
->vs
);
140 util_blitter_save_geometry_shader(lp
->blitter
, (void*)lp
->gs
);
141 util_blitter_save_so_targets(lp
->blitter
, lp
->num_so_targets
,
142 (struct pipe_stream_output_target
**)lp
->so_targets
);
143 util_blitter_save_rasterizer(lp
->blitter
, (void*)lp
->rasterizer
);
144 util_blitter_save_viewport(lp
->blitter
, &lp
->viewports
[0]);
145 util_blitter_save_scissor(lp
->blitter
, &lp
->scissors
[0]);
146 util_blitter_save_fragment_shader(lp
->blitter
, lp
->fs
);
147 util_blitter_save_blend(lp
->blitter
, (void*)lp
->blend
);
148 util_blitter_save_tessctrl_shader(lp
->blitter
, (void*)lp
->tcs
);
149 util_blitter_save_tesseval_shader(lp
->blitter
, (void*)lp
->tes
);
150 util_blitter_save_depth_stencil_alpha(lp
->blitter
, (void*)lp
->depth_stencil
);
151 util_blitter_save_stencil_ref(lp
->blitter
, &lp
->stencil_ref
);
152 util_blitter_save_sample_mask(lp
->blitter
, lp
->sample_mask
);
153 util_blitter_save_framebuffer(lp
->blitter
, &lp
->framebuffer
);
154 util_blitter_save_fragment_sampler_states(lp
->blitter
,
155 lp
->num_samplers
[PIPE_SHADER_FRAGMENT
],
156 (void**)lp
->samplers
[PIPE_SHADER_FRAGMENT
]);
157 util_blitter_save_fragment_sampler_views(lp
->blitter
,
158 lp
->num_sampler_views
[PIPE_SHADER_FRAGMENT
],
159 lp
->sampler_views
[PIPE_SHADER_FRAGMENT
]);
160 util_blitter_save_render_condition(lp
->blitter
, lp
->render_cond_query
,
161 lp
->render_cond_cond
, lp
->render_cond_mode
);
162 util_blitter_blit(lp
->blitter
, &info
);
167 lp_flush_resource(struct pipe_context
*ctx
, struct pipe_resource
*resource
)
172 static struct pipe_surface
*
173 llvmpipe_create_surface(struct pipe_context
*pipe
,
174 struct pipe_resource
*pt
,
175 const struct pipe_surface
*surf_tmpl
)
177 struct pipe_surface
*ps
;
179 if (!(pt
->bind
& (PIPE_BIND_DEPTH_STENCIL
| PIPE_BIND_RENDER_TARGET
))) {
180 debug_printf("Illegal surface creation without bind flag\n");
181 if (util_format_is_depth_or_stencil(surf_tmpl
->format
)) {
182 pt
->bind
|= PIPE_BIND_DEPTH_STENCIL
;
185 pt
->bind
|= PIPE_BIND_RENDER_TARGET
;
189 ps
= CALLOC_STRUCT(pipe_surface
);
191 pipe_reference_init(&ps
->reference
, 1);
192 pipe_resource_reference(&ps
->texture
, pt
);
194 ps
->format
= surf_tmpl
->format
;
195 if (llvmpipe_resource_is_texture(pt
)) {
196 assert(surf_tmpl
->u
.tex
.level
<= pt
->last_level
);
197 assert(surf_tmpl
->u
.tex
.first_layer
<= surf_tmpl
->u
.tex
.last_layer
);
198 ps
->width
= u_minify(pt
->width0
, surf_tmpl
->u
.tex
.level
);
199 ps
->height
= u_minify(pt
->height0
, surf_tmpl
->u
.tex
.level
);
200 ps
->u
.tex
.level
= surf_tmpl
->u
.tex
.level
;
201 ps
->u
.tex
.first_layer
= surf_tmpl
->u
.tex
.first_layer
;
202 ps
->u
.tex
.last_layer
= surf_tmpl
->u
.tex
.last_layer
;
205 /* setting width as number of elements should get us correct renderbuffer width */
206 ps
->width
= surf_tmpl
->u
.buf
.last_element
- surf_tmpl
->u
.buf
.first_element
+ 1;
207 ps
->height
= pt
->height0
;
208 ps
->u
.buf
.first_element
= surf_tmpl
->u
.buf
.first_element
;
209 ps
->u
.buf
.last_element
= surf_tmpl
->u
.buf
.last_element
;
210 assert(ps
->u
.buf
.first_element
<= ps
->u
.buf
.last_element
);
211 assert(util_format_get_blocksize(surf_tmpl
->format
) *
212 (ps
->u
.buf
.last_element
+ 1) <= pt
->width0
);
220 llvmpipe_surface_destroy(struct pipe_context
*pipe
,
221 struct pipe_surface
*surf
)
223 /* Effectively do the texture_update work here - if texture images
224 * needed post-processing to put them into hardware layout, this is
225 * where it would happen. For llvmpipe, nothing to do.
227 assert(surf
->texture
);
228 pipe_resource_reference(&surf
->texture
, NULL
);
235 llvmpipe_get_sample_position(struct pipe_context
*pipe
,
236 unsigned sample_count
,
237 unsigned sample_index
,
240 switch (sample_count
) {
242 out_value
[0] = lp_sample_pos_4x
[sample_index
][0];
243 out_value
[1] = lp_sample_pos_4x
[sample_index
][1];
251 lp_clear_color_texture_helper(struct pipe_transfer
*dst_trans
,
253 enum pipe_format format
,
254 const union pipe_color_union
*color
,
255 unsigned width
, unsigned height
, unsigned depth
)
259 assert(dst_trans
->stride
> 0);
261 util_pack_color_union(format
, &uc
, color
);
263 util_fill_box(dst_map
, format
,
264 dst_trans
->stride
, dst_trans
->layer_stride
,
265 0, 0, 0, width
, height
, depth
, &uc
);
269 lp_clear_color_texture_msaa(struct pipe_context
*pipe
,
270 struct pipe_resource
*texture
,
271 enum pipe_format format
,
272 const union pipe_color_union
*color
,
274 const struct pipe_box
*box
)
276 struct pipe_transfer
*dst_trans
;
279 dst_map
= llvmpipe_transfer_map_ms(pipe
, texture
, 0, PIPE_TRANSFER_WRITE
,
280 sample
, box
, &dst_trans
);
284 if (dst_trans
->stride
> 0) {
285 lp_clear_color_texture_helper(dst_trans
, dst_map
, format
, color
,
286 box
->width
, box
->height
, box
->depth
);
288 pipe
->transfer_unmap(pipe
, dst_trans
);
292 llvmpipe_clear_render_target(struct pipe_context
*pipe
,
293 struct pipe_surface
*dst
,
294 const union pipe_color_union
*color
,
295 unsigned dstx
, unsigned dsty
,
296 unsigned width
, unsigned height
,
297 bool render_condition_enabled
)
299 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
301 if (render_condition_enabled
&& !llvmpipe_check_render_cond(llvmpipe
))
304 if (dst
->texture
->nr_samples
> 1) {
306 u_box_2d(dstx
, dsty
, width
, height
, &box
);
307 for (unsigned s
= 0; s
< util_res_sample_count(dst
->texture
); s
++) {
308 lp_clear_color_texture_msaa(pipe
, dst
->texture
, dst
->format
,
312 util_clear_render_target(pipe
, dst
, color
,
313 dstx
, dsty
, width
, height
);
318 lp_clear_depth_stencil_texture_msaa(struct pipe_context
*pipe
,
319 struct pipe_resource
*texture
,
320 enum pipe_format format
,
321 unsigned clear_flags
,
322 uint64_t zstencil
, unsigned sample
,
323 const struct pipe_box
*box
)
325 struct pipe_transfer
*dst_trans
;
327 boolean need_rmw
= FALSE
;
329 if ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) &&
330 ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) != PIPE_CLEAR_DEPTHSTENCIL
) &&
331 util_format_is_depth_and_stencil(format
))
334 dst_map
= llvmpipe_transfer_map_ms(pipe
,
337 (need_rmw
? PIPE_TRANSFER_READ_WRITE
:
338 PIPE_TRANSFER_WRITE
),
339 sample
, box
, &dst_trans
);
344 assert(dst_trans
->stride
> 0);
346 util_fill_zs_box(dst_map
, format
, need_rmw
, clear_flags
,
347 dst_trans
->stride
, dst_trans
->layer_stride
,
348 box
->width
, box
->height
, box
->depth
, zstencil
);
350 pipe
->transfer_unmap(pipe
, dst_trans
);
354 llvmpipe_clear_depth_stencil(struct pipe_context
*pipe
,
355 struct pipe_surface
*dst
,
356 unsigned clear_flags
,
359 unsigned dstx
, unsigned dsty
,
360 unsigned width
, unsigned height
,
361 bool render_condition_enabled
)
363 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
365 if (render_condition_enabled
&& !llvmpipe_check_render_cond(llvmpipe
))
368 if (dst
->texture
->nr_samples
> 1) {
369 uint64_t zstencil
= util_pack64_z_stencil(dst
->format
, depth
, stencil
);
371 u_box_2d(dstx
, dsty
, width
, height
, &box
);
372 for (unsigned s
= 0; s
< util_res_sample_count(dst
->texture
); s
++)
373 lp_clear_depth_stencil_texture_msaa(pipe
, dst
->texture
,
374 dst
->format
, clear_flags
,
377 util_clear_depth_stencil(pipe
, dst
, clear_flags
,
379 dstx
, dsty
, width
, height
);
383 llvmpipe_clear_texture(struct pipe_context
*pipe
,
384 struct pipe_resource
*tex
,
386 const struct pipe_box
*box
,
389 const struct util_format_description
*desc
=
390 util_format_description(tex
->format
);
391 if (tex
->nr_samples
<= 1) {
392 util_clear_texture(pipe
, tex
, level
, box
, data
);
395 union pipe_color_union color
;
397 if (util_format_is_depth_or_stencil(tex
->format
)) {
403 if (util_format_has_depth(desc
)) {
404 clear
|= PIPE_CLEAR_DEPTH
;
405 util_format_unpack_z_float(tex
->format
, &depth
, data
, 1);
408 if (util_format_has_stencil(desc
)) {
409 clear
|= PIPE_CLEAR_STENCIL
;
410 util_format_unpack_s_8uint(tex
->format
, &stencil
, data
, 1);
413 zstencil
= util_pack64_z_stencil(tex
->format
, depth
, stencil
);
415 for (unsigned s
= 0; s
< util_res_sample_count(tex
); s
++)
416 lp_clear_depth_stencil_texture_msaa(pipe
, tex
, tex
->format
, clear
, zstencil
,
419 util_format_unpack_rgba(tex
->format
, color
.ui
, data
, 1);
421 for (unsigned s
= 0; s
< util_res_sample_count(tex
); s
++) {
422 lp_clear_color_texture_msaa(pipe
, tex
, tex
->format
, &color
, s
,
429 llvmpipe_init_surface_functions(struct llvmpipe_context
*lp
)
431 lp
->pipe
.clear_render_target
= llvmpipe_clear_render_target
;
432 lp
->pipe
.clear_depth_stencil
= llvmpipe_clear_depth_stencil
;
433 lp
->pipe
.create_surface
= llvmpipe_create_surface
;
434 lp
->pipe
.surface_destroy
= llvmpipe_surface_destroy
;
435 /* These are not actually functions dealing with surfaces */
436 lp
->pipe
.clear_texture
= llvmpipe_clear_texture
;
437 lp
->pipe
.resource_copy_region
= lp_resource_copy
;
438 lp
->pipe
.blit
= lp_blit
;
439 lp
->pipe
.flush_resource
= lp_flush_resource
;
440 lp
->pipe
.get_sample_position
= llvmpipe_get_sample_position
;