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 llvmpipe_flush_resource(pipe
,
47 FALSE
, /* read_only */
48 TRUE
, /* cpu_access */
49 FALSE
, /* do_not_block */
52 llvmpipe_flush_resource(pipe
,
55 TRUE
, /* cpu_access */
56 FALSE
, /* do_not_block */
59 util_resource_copy_region(pipe
, dst
, dst_level
, dstx
, dsty
, dstz
,
60 src
, src_level
, src_box
);
64 static void lp_blit(struct pipe_context
*pipe
,
65 const struct pipe_blit_info
*blit_info
)
67 struct llvmpipe_context
*lp
= llvmpipe_context(pipe
);
68 struct pipe_blit_info info
= *blit_info
;
70 if (blit_info
->render_condition_enable
&& !llvmpipe_check_render_cond(lp
))
73 if (info
.src
.resource
->nr_samples
> 1 &&
74 info
.dst
.resource
->nr_samples
<= 1 &&
75 !util_format_is_depth_or_stencil(info
.src
.resource
->format
) &&
76 !util_format_is_pure_integer(info
.src
.resource
->format
)) {
77 debug_printf("llvmpipe: color resolve unimplemented\n");
81 if (util_try_blit_via_copy_region(pipe
, &info
)) {
85 if (!util_blitter_is_blit_supported(lp
->blitter
, &info
)) {
86 debug_printf("llvmpipe: blit unsupported %s -> %s\n",
87 util_format_short_name(info
.src
.resource
->format
),
88 util_format_short_name(info
.dst
.resource
->format
));
92 /* XXX turn off occlusion and streamout queries */
94 util_blitter_save_vertex_buffer_slot(lp
->blitter
, lp
->vertex_buffer
);
95 util_blitter_save_vertex_elements(lp
->blitter
, (void*)lp
->velems
);
96 util_blitter_save_vertex_shader(lp
->blitter
, (void*)lp
->vs
);
97 util_blitter_save_geometry_shader(lp
->blitter
, (void*)lp
->gs
);
98 util_blitter_save_so_targets(lp
->blitter
, lp
->num_so_targets
,
99 (struct pipe_stream_output_target
**)lp
->so_targets
);
100 util_blitter_save_rasterizer(lp
->blitter
, (void*)lp
->rasterizer
);
101 util_blitter_save_viewport(lp
->blitter
, &lp
->viewports
[0]);
102 util_blitter_save_scissor(lp
->blitter
, &lp
->scissors
[0]);
103 util_blitter_save_fragment_shader(lp
->blitter
, lp
->fs
);
104 util_blitter_save_blend(lp
->blitter
, (void*)lp
->blend
);
105 util_blitter_save_depth_stencil_alpha(lp
->blitter
, (void*)lp
->depth_stencil
);
106 util_blitter_save_stencil_ref(lp
->blitter
, &lp
->stencil_ref
);
107 /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/
108 util_blitter_save_framebuffer(lp
->blitter
, &lp
->framebuffer
);
109 util_blitter_save_fragment_sampler_states(lp
->blitter
,
110 lp
->num_samplers
[PIPE_SHADER_FRAGMENT
],
111 (void**)lp
->samplers
[PIPE_SHADER_FRAGMENT
]);
112 util_blitter_save_fragment_sampler_views(lp
->blitter
,
113 lp
->num_sampler_views
[PIPE_SHADER_FRAGMENT
],
114 lp
->sampler_views
[PIPE_SHADER_FRAGMENT
]);
115 util_blitter_save_render_condition(lp
->blitter
, lp
->render_cond_query
,
116 lp
->render_cond_cond
, lp
->render_cond_mode
);
117 util_blitter_blit(lp
->blitter
, &info
);
122 lp_flush_resource(struct pipe_context
*ctx
, struct pipe_resource
*resource
)
127 static struct pipe_surface
*
128 llvmpipe_create_surface(struct pipe_context
*pipe
,
129 struct pipe_resource
*pt
,
130 const struct pipe_surface
*surf_tmpl
)
132 struct pipe_surface
*ps
;
134 if (!(pt
->bind
& (PIPE_BIND_DEPTH_STENCIL
| PIPE_BIND_RENDER_TARGET
)))
135 debug_printf("Illegal surface creation without bind flag\n");
137 ps
= CALLOC_STRUCT(pipe_surface
);
139 pipe_reference_init(&ps
->reference
, 1);
140 pipe_resource_reference(&ps
->texture
, pt
);
142 ps
->format
= surf_tmpl
->format
;
143 if (llvmpipe_resource_is_texture(pt
)) {
144 assert(surf_tmpl
->u
.tex
.level
<= pt
->last_level
);
145 assert(surf_tmpl
->u
.tex
.first_layer
<= surf_tmpl
->u
.tex
.last_layer
);
146 ps
->width
= u_minify(pt
->width0
, surf_tmpl
->u
.tex
.level
);
147 ps
->height
= u_minify(pt
->height0
, surf_tmpl
->u
.tex
.level
);
148 ps
->u
.tex
.level
= surf_tmpl
->u
.tex
.level
;
149 ps
->u
.tex
.first_layer
= surf_tmpl
->u
.tex
.first_layer
;
150 ps
->u
.tex
.last_layer
= surf_tmpl
->u
.tex
.last_layer
;
153 /* setting width as number of elements should get us correct renderbuffer width */
154 ps
->width
= surf_tmpl
->u
.buf
.last_element
- surf_tmpl
->u
.buf
.first_element
+ 1;
155 ps
->height
= pt
->height0
;
156 ps
->u
.buf
.first_element
= surf_tmpl
->u
.buf
.first_element
;
157 ps
->u
.buf
.last_element
= surf_tmpl
->u
.buf
.last_element
;
158 assert(ps
->u
.buf
.first_element
<= ps
->u
.buf
.last_element
);
159 assert(util_format_get_blocksize(surf_tmpl
->format
) *
160 (ps
->u
.buf
.last_element
+ 1) <= pt
->width0
);
168 llvmpipe_surface_destroy(struct pipe_context
*pipe
,
169 struct pipe_surface
*surf
)
171 /* Effectively do the texture_update work here - if texture images
172 * needed post-processing to put them into hardware layout, this is
173 * where it would happen. For llvmpipe, nothing to do.
175 assert(surf
->texture
);
176 pipe_resource_reference(&surf
->texture
, NULL
);
182 llvmpipe_clear_render_target(struct pipe_context
*pipe
,
183 struct pipe_surface
*dst
,
184 const union pipe_color_union
*color
,
185 unsigned dstx
, unsigned dsty
,
186 unsigned width
, unsigned height
)
188 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
190 if (!llvmpipe_check_render_cond(llvmpipe
))
193 util_clear_render_target(pipe
, dst
, color
,
194 dstx
, dsty
, width
, height
);
199 llvmpipe_clear_depth_stencil(struct pipe_context
*pipe
,
200 struct pipe_surface
*dst
,
201 unsigned clear_flags
,
204 unsigned dstx
, unsigned dsty
,
205 unsigned width
, unsigned height
)
207 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
209 if (!llvmpipe_check_render_cond(llvmpipe
))
212 util_clear_depth_stencil(pipe
, dst
, clear_flags
,
214 dstx
, dsty
, width
, height
);
219 llvmpipe_init_surface_functions(struct llvmpipe_context
*lp
)
221 lp
->pipe
.clear_render_target
= llvmpipe_clear_render_target
;
222 lp
->pipe
.clear_depth_stencil
= llvmpipe_clear_depth_stencil
;
223 lp
->pipe
.create_surface
= llvmpipe_create_surface
;
224 lp
->pipe
.surface_destroy
= llvmpipe_surface_destroy
;
225 /* These two are not actually functions dealing with surfaces */
226 lp
->pipe
.resource_copy_region
= lp_resource_copy
;
227 lp
->pipe
.blit
= lp_blit
;
228 lp
->pipe
.flush_resource
= lp_flush_resource
;