0bfe7827f11d77f3fedd64889b74d4c5d7c73a7d
[mesa.git] / src / gallium / drivers / ilo / ilo_blitter_pipe.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "util/u_blitter.h"
29 #include "util/u_surface.h"
30
31 #include "ilo_context.h"
32 #include "ilo_blitter.h"
33
34 enum ilo_blitter_pipe_op {
35 ILO_BLITTER_PIPE_BLIT,
36 ILO_BLITTER_PIPE_COPY,
37 ILO_BLITTER_PIPE_CLEAR,
38 ILO_BLITTER_PIPE_CLEAR_FB,
39 };
40
41 static void
42 ilo_blitter_pipe_begin(struct ilo_blitter *blitter,
43 enum ilo_blitter_pipe_op op,
44 bool scissor_enable)
45 {
46 struct blitter_context *b = blitter->pipe_blitter;
47 struct ilo_state_vector *vec = &blitter->ilo->state_vector;
48
49 /* vertex states */
50 util_blitter_save_vertex_buffer_slot(b, vec->vb.states);
51 util_blitter_save_vertex_elements(b, (void *) vec->ve);
52 util_blitter_save_vertex_shader(b, vec->vs);
53 util_blitter_save_geometry_shader(b, vec->gs);
54 util_blitter_save_so_targets(b, vec->so.count, vec->so.states);
55 util_blitter_save_rasterizer(b, (void *) vec->rasterizer);
56
57 /* fragment states */
58 util_blitter_save_fragment_shader(b, vec->fs);
59 util_blitter_save_depth_stencil_alpha(b, (void *) vec->dsa);
60 util_blitter_save_blend(b, (void *) vec->blend);
61 util_blitter_save_sample_mask(b, vec->sample_mask);
62 util_blitter_save_stencil_ref(b, &vec->stencil_ref);
63 util_blitter_save_viewport(b, &vec->viewport.viewport0);
64
65 if (scissor_enable)
66 util_blitter_save_scissor(b, &vec->viewport.scissor0);
67
68 switch (op) {
69 case ILO_BLITTER_PIPE_BLIT:
70 case ILO_BLITTER_PIPE_COPY:
71 /*
72 * We are about to call util_blitter_blit() or
73 * util_blitter_copy_texture(). Note that util_blitter uses at most two
74 * textures.
75 */
76 util_blitter_save_fragment_sampler_states(b,
77 2, (void **) vec->sampler[PIPE_SHADER_FRAGMENT].cso);
78
79 util_blitter_save_fragment_sampler_views(b,
80 vec->view[PIPE_SHADER_FRAGMENT].count,
81 vec->view[PIPE_SHADER_FRAGMENT].states);
82
83 util_blitter_save_framebuffer(b, &vec->fb.state);
84
85 /* resource_copy_region() or blit() does not honor render condition */
86 util_blitter_save_render_condition(b,
87 blitter->ilo->render_condition.query,
88 blitter->ilo->render_condition.condition,
89 blitter->ilo->render_condition.mode);
90 break;
91 case ILO_BLITTER_PIPE_CLEAR:
92 /*
93 * we are about to call util_blitter_clear_render_target() or
94 * util_blitter_clear_depth_stencil()
95 */
96 util_blitter_save_framebuffer(b, &vec->fb.state);
97 break;
98 case ILO_BLITTER_PIPE_CLEAR_FB:
99 /* we are about to call util_blitter_clear() */
100 break;
101 default:
102 break;
103 }
104 }
105
106 static void
107 ilo_blitter_pipe_end(struct ilo_blitter *blitter)
108 {
109 }
110
111 bool
112 ilo_blitter_pipe_blit(struct ilo_blitter *blitter,
113 const struct pipe_blit_info *info)
114 {
115 struct blitter_context *b = blitter->pipe_blitter;
116 struct pipe_blit_info skip_stencil;
117
118 if (util_try_blit_via_copy_region(&blitter->ilo->base, info))
119 return true;
120
121 if (!util_blitter_is_blit_supported(b, info)) {
122 /* try without stencil */
123 if (info->mask & PIPE_MASK_S) {
124 skip_stencil = *info;
125 skip_stencil.mask = info->mask & ~PIPE_MASK_S;
126
127 if (util_blitter_is_blit_supported(blitter->pipe_blitter,
128 &skip_stencil)) {
129 ilo_warn("ignore stencil buffer blitting\n");
130 info = &skip_stencil;
131 }
132 }
133
134 if (info != &skip_stencil) {
135 ilo_warn("failed to blit with pipe blitter\n");
136 return false;
137 }
138 }
139
140 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_BLIT,
141 info->scissor_enable);
142 util_blitter_blit(b, info);
143 ilo_blitter_pipe_end(blitter);
144
145 return true;
146 }
147
148 bool
149 ilo_blitter_pipe_copy_resource(struct ilo_blitter *blitter,
150 struct pipe_resource *dst, unsigned dst_level,
151 unsigned dst_x, unsigned dst_y, unsigned dst_z,
152 struct pipe_resource *src, unsigned src_level,
153 const struct pipe_box *src_box)
154 {
155 /* not until we allow rendertargets to be buffers */
156 if (dst->target == PIPE_BUFFER || src->target == PIPE_BUFFER)
157 return false;
158
159 if (!util_blitter_is_copy_supported(blitter->pipe_blitter, dst, src))
160 return false;
161
162 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_COPY, false);
163
164 util_blitter_copy_texture(blitter->pipe_blitter,
165 dst, dst_level, dst_x, dst_y, dst_z,
166 src, src_level, src_box);
167
168 ilo_blitter_pipe_end(blitter);
169
170 return true;
171 }
172
173 bool
174 ilo_blitter_pipe_clear_rt(struct ilo_blitter *blitter,
175 struct pipe_surface *rt,
176 const union pipe_color_union *color,
177 unsigned x, unsigned y,
178 unsigned width, unsigned height)
179 {
180 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR, false);
181
182 util_blitter_clear_render_target(blitter->pipe_blitter,
183 rt, color, x, y, width, height);
184
185 ilo_blitter_pipe_end(blitter);
186
187 return true;
188 }
189
190 bool
191 ilo_blitter_pipe_clear_zs(struct ilo_blitter *blitter,
192 struct pipe_surface *zs,
193 unsigned clear_flags,
194 double depth, unsigned stencil,
195 unsigned x, unsigned y,
196 unsigned width, unsigned height)
197 {
198 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR, false);
199
200 util_blitter_clear_depth_stencil(blitter->pipe_blitter,
201 zs, clear_flags, depth, stencil, x, y, width, height);
202
203 ilo_blitter_pipe_end(blitter);
204
205 return true;
206 }
207
208 bool
209 ilo_blitter_pipe_clear_fb(struct ilo_blitter *blitter,
210 unsigned buffers,
211 const union pipe_color_union *color,
212 double depth, unsigned stencil)
213 {
214 struct ilo_state_vector *vec = &blitter->ilo->state_vector;
215
216 /* TODO we should pause/resume some queries */
217 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR_FB, false);
218
219 util_blitter_clear(blitter->pipe_blitter,
220 vec->fb.state.width, vec->fb.state.height, 1,
221 buffers, color, depth, stencil);
222
223 ilo_blitter_pipe_end(blitter);
224
225 return true;
226 }