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(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 llvmpipe_resource
*src_tex
= llvmpipe_resource(src
);
46 struct llvmpipe_resource
*dst_tex
= llvmpipe_resource(dst
);
47 const enum pipe_format format
= src_tex
->base
.format
;
48 unsigned width
= src_box
->width
;
49 unsigned height
= src_box
->height
;
50 unsigned depth
= src_box
->depth
;
52 llvmpipe_flush_resource(pipe
,
54 FALSE
, /* read_only */
55 TRUE
, /* cpu_access */
56 FALSE
, /* do_not_block */
59 llvmpipe_flush_resource(pipe
,
62 TRUE
, /* cpu_access */
63 FALSE
, /* do_not_block */
66 /* Fallback for buffers. */
67 if (dst
->target
== PIPE_BUFFER
&& src
->target
== PIPE_BUFFER
) {
68 util_resource_copy_region(pipe
, dst
, dst_level
, dstx
, dsty
, dstz
,
69 src
, src_level
, src_box
);
74 printf("surface copy from %u lvl %u to %u lvl %u: %u,%u,%u to %u,%u,%u %u x %u x %u\n",
75 src_tex->id, src_level, dst_tex->id, dst_level,
76 src_box->x, src_box->y, src_box->z, dstx, dsty, dstz,
77 src_box->width, src_box->height, src_box->depth);
80 /* make sure display target resources (which cannot have levels/layers) are mapped */
82 (void) llvmpipe_resource_map(src
, src_level
, 0, LP_TEX_USAGE_READ
);
85 * Could set this to WRITE_ALL if complete dst is covered but it gets
88 (void) llvmpipe_resource_map(dst
, dst_level
, 0, LP_TEX_USAGE_READ_WRITE
);
93 const ubyte
*src_linear_ptr
94 = llvmpipe_get_texture_image_address(src_tex
, src_box
->z
,
97 = llvmpipe_get_texture_image_address(dst_tex
, dstz
,
100 if (dst_linear_ptr
&& src_linear_ptr
) {
101 util_copy_box(dst_linear_ptr
, format
,
102 llvmpipe_resource_stride(&dst_tex
->base
, dst_level
),
103 dst_tex
->img_stride
[dst_level
],
105 width
, height
, depth
,
107 llvmpipe_resource_stride(&src_tex
->base
, src_level
),
108 src_tex
->img_stride
[src_level
],
109 src_box
->x
, src_box
->y
, 0);
114 llvmpipe_resource_unmap(src
, 0, 0);
116 llvmpipe_resource_unmap(dst
, 0, 0);
121 static void lp_blit(struct pipe_context
*pipe
,
122 const struct pipe_blit_info
*blit_info
)
124 struct llvmpipe_context
*lp
= llvmpipe_context(pipe
);
125 struct pipe_blit_info info
= *blit_info
;
127 if (blit_info
->render_condition_enable
&& !llvmpipe_check_render_cond(lp
))
130 if (info
.src
.resource
->nr_samples
> 1 &&
131 info
.dst
.resource
->nr_samples
<= 1 &&
132 !util_format_is_depth_or_stencil(info
.src
.resource
->format
) &&
133 !util_format_is_pure_integer(info
.src
.resource
->format
)) {
134 debug_printf("llvmpipe: color resolve unimplemented\n");
138 if (util_try_blit_via_copy_region(pipe
, &info
)) {
142 if (info
.mask
& PIPE_MASK_S
) {
143 debug_printf("llvmpipe: cannot blit stencil, skipping\n");
144 info
.mask
&= ~PIPE_MASK_S
;
147 if (!util_blitter_is_blit_supported(lp
->blitter
, &info
)) {
148 debug_printf("llvmpipe: blit unsupported %s -> %s\n",
149 util_format_short_name(info
.src
.resource
->format
),
150 util_format_short_name(info
.dst
.resource
->format
));
154 /* XXX turn off occlusion and streamout queries */
156 util_blitter_save_vertex_buffer_slot(lp
->blitter
, lp
->vertex_buffer
);
157 util_blitter_save_vertex_elements(lp
->blitter
, (void*)lp
->velems
);
158 util_blitter_save_vertex_shader(lp
->blitter
, (void*)lp
->vs
);
159 util_blitter_save_geometry_shader(lp
->blitter
, (void*)lp
->gs
);
160 util_blitter_save_so_targets(lp
->blitter
, lp
->num_so_targets
,
161 (struct pipe_stream_output_target
**)lp
->so_targets
);
162 util_blitter_save_rasterizer(lp
->blitter
, (void*)lp
->rasterizer
);
163 util_blitter_save_viewport(lp
->blitter
, &lp
->viewports
[0]);
164 util_blitter_save_scissor(lp
->blitter
, &lp
->scissors
[0]);
165 util_blitter_save_fragment_shader(lp
->blitter
, lp
->fs
);
166 util_blitter_save_blend(lp
->blitter
, (void*)lp
->blend
);
167 util_blitter_save_depth_stencil_alpha(lp
->blitter
, (void*)lp
->depth_stencil
);
168 util_blitter_save_stencil_ref(lp
->blitter
, &lp
->stencil_ref
);
169 /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/
170 util_blitter_save_framebuffer(lp
->blitter
, &lp
->framebuffer
);
171 util_blitter_save_fragment_sampler_states(lp
->blitter
,
172 lp
->num_samplers
[PIPE_SHADER_FRAGMENT
],
173 (void**)lp
->samplers
[PIPE_SHADER_FRAGMENT
]);
174 util_blitter_save_fragment_sampler_views(lp
->blitter
,
175 lp
->num_sampler_views
[PIPE_SHADER_FRAGMENT
],
176 lp
->sampler_views
[PIPE_SHADER_FRAGMENT
]);
177 util_blitter_save_render_condition(lp
->blitter
, lp
->render_cond_query
,
178 lp
->render_cond_cond
, lp
->render_cond_mode
);
179 util_blitter_blit(lp
->blitter
, &info
);
184 lp_flush_resource(struct pipe_context
*ctx
, struct pipe_resource
*resource
)
189 static struct pipe_surface
*
190 llvmpipe_create_surface(struct pipe_context
*pipe
,
191 struct pipe_resource
*pt
,
192 const struct pipe_surface
*surf_tmpl
)
194 struct pipe_surface
*ps
;
196 if (!(pt
->bind
& (PIPE_BIND_DEPTH_STENCIL
| PIPE_BIND_RENDER_TARGET
)))
197 debug_printf("Illegal surface creation without bind flag\n");
199 ps
= CALLOC_STRUCT(pipe_surface
);
201 pipe_reference_init(&ps
->reference
, 1);
202 pipe_resource_reference(&ps
->texture
, pt
);
204 ps
->format
= surf_tmpl
->format
;
205 if (llvmpipe_resource_is_texture(pt
)) {
206 assert(surf_tmpl
->u
.tex
.level
<= pt
->last_level
);
207 assert(surf_tmpl
->u
.tex
.first_layer
<= surf_tmpl
->u
.tex
.last_layer
);
208 ps
->width
= u_minify(pt
->width0
, surf_tmpl
->u
.tex
.level
);
209 ps
->height
= u_minify(pt
->height0
, surf_tmpl
->u
.tex
.level
);
210 ps
->u
.tex
.level
= surf_tmpl
->u
.tex
.level
;
211 ps
->u
.tex
.first_layer
= surf_tmpl
->u
.tex
.first_layer
;
212 ps
->u
.tex
.last_layer
= surf_tmpl
->u
.tex
.last_layer
;
215 /* setting width as number of elements should get us correct renderbuffer width */
216 ps
->width
= surf_tmpl
->u
.buf
.last_element
- surf_tmpl
->u
.buf
.first_element
+ 1;
217 ps
->height
= pt
->height0
;
218 ps
->u
.buf
.first_element
= surf_tmpl
->u
.buf
.first_element
;
219 ps
->u
.buf
.last_element
= surf_tmpl
->u
.buf
.last_element
;
220 assert(ps
->u
.buf
.first_element
<= ps
->u
.buf
.last_element
);
221 assert(util_format_get_blocksize(surf_tmpl
->format
) *
222 (ps
->u
.buf
.last_element
+ 1) <= pt
->width0
);
230 llvmpipe_surface_destroy(struct pipe_context
*pipe
,
231 struct pipe_surface
*surf
)
233 /* Effectively do the texture_update work here - if texture images
234 * needed post-processing to put them into hardware layout, this is
235 * where it would happen. For llvmpipe, nothing to do.
237 assert(surf
->texture
);
238 pipe_resource_reference(&surf
->texture
, NULL
);
244 llvmpipe_clear_render_target(struct pipe_context
*pipe
,
245 struct pipe_surface
*dst
,
246 const union pipe_color_union
*color
,
247 unsigned dstx
, unsigned dsty
,
248 unsigned width
, unsigned height
)
250 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
252 if (!llvmpipe_check_render_cond(llvmpipe
))
255 util_clear_render_target(pipe
, dst
, color
,
256 dstx
, dsty
, width
, height
);
261 llvmpipe_clear_depth_stencil(struct pipe_context
*pipe
,
262 struct pipe_surface
*dst
,
263 unsigned clear_flags
,
266 unsigned dstx
, unsigned dsty
,
267 unsigned width
, unsigned height
)
269 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
271 if (!llvmpipe_check_render_cond(llvmpipe
))
274 util_clear_depth_stencil(pipe
, dst
, clear_flags
,
276 dstx
, dsty
, width
, height
);
281 llvmpipe_init_surface_functions(struct llvmpipe_context
*lp
)
283 lp
->pipe
.clear_render_target
= llvmpipe_clear_render_target
;
284 lp
->pipe
.clear_depth_stencil
= llvmpipe_clear_depth_stencil
;
285 lp
->pipe
.create_surface
= llvmpipe_create_surface
;
286 lp
->pipe
.surface_destroy
= llvmpipe_surface_destroy
;
287 /* These two are not actually functions dealing with surfaces */
288 lp
->pipe
.resource_copy_region
= lp_resource_copy
;
289 lp
->pipe
.blit
= lp_blit
;
290 lp
->pipe
.flush_resource
= lp_flush_resource
;