2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "util/u_blitter.h"
29 #include "util/u_clear.h"
30 #include "util/u_pack_color.h"
31 #include "util/u_surface.h"
32 #include "intel_reg.h"
34 #include "ilo_context.h"
36 #include "ilo_resource.h"
37 #include "ilo_screen.h"
41 blitter_xy_color_blt(struct pipe_context *pipe,
42 struct pipe_resource *res,
43 int16_t x1, int16_t y1,
44 int16_t x2, int16_t y2,
47 const int cmd_len = 6;
48 struct ilo_context *ilo = ilo_context(pipe);
49 struct ilo_texture *tex = ilo_texture(res);
52 struct intel_bo *bo_check[2];
54 /* how to support Y-tiling? */
55 if (tex->tiling == INTEL_TILING_Y)
58 /* nothing to clear */
59 if (x1 >= x2 || y1 >= y2)
62 cmd = XY_COLOR_BLT_CMD | (cmd_len - 2);
65 cpp = util_format_get_blocksize(tex->base.format);
68 cmd |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
82 stride = tex->bo_stride;
83 if (tex->tiling != INTEL_TILING_NONE) {
84 assert(tex->tiling == INTEL_TILING_X);
91 ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT);
92 ilo_cp_set_owner(ilo->cp, NULL, 0);
94 /* make room if necessary */
95 bo_check[0] = ilo->cp->bo;
96 bo_check[1] = tex->bo;
97 if (ilo->winsys->check_aperture_space(ilo->winsys, bo_check, 2))
98 ilo_cp_flush(ilo->cp);
100 ilo_cp_begin(ilo->cp, cmd_len);
101 ilo_cp_write(ilo->cp, cmd);
102 ilo_cp_write(ilo->cp, br13 | stride);
103 ilo_cp_write(ilo->cp, (y1 << 16) | x1);
104 ilo_cp_write(ilo->cp, (y2 << 16) | x2);
105 ilo_cp_write_bo(ilo->cp, 0, tex->bo,
107 INTEL_DOMAIN_RENDER);
108 ilo_cp_write(ilo->cp, color);
114 enum ilo_blitter_op {
116 ILO_BLITTER_CLEAR_SURFACE,
121 ilo_blitter_begin(struct ilo_context *ilo, enum ilo_blitter_op op)
123 /* as documented in util/u_blitter.h */
124 util_blitter_save_vertex_buffer_slot(ilo->blitter,
125 ilo->vertex_buffers.buffers);
126 util_blitter_save_vertex_elements(ilo->blitter, ilo->vertex_elements);
127 util_blitter_save_vertex_shader(ilo->blitter, ilo->vs);
128 util_blitter_save_geometry_shader(ilo->blitter, ilo->gs);
129 util_blitter_save_so_targets(ilo->blitter,
130 ilo->stream_output_targets.num_targets,
131 ilo->stream_output_targets.targets);
133 util_blitter_save_fragment_shader(ilo->blitter, ilo->fs);
134 util_blitter_save_depth_stencil_alpha(ilo->blitter,
135 ilo->depth_stencil_alpha);
136 util_blitter_save_blend(ilo->blitter, ilo->blend);
139 util_blitter_save_viewport(ilo->blitter, &ilo->viewport);
140 util_blitter_save_stencil_ref(ilo->blitter, &ilo->stencil_ref);
141 util_blitter_save_sample_mask(ilo->blitter, ilo->sample_mask);
144 case ILO_BLITTER_CLEAR:
145 util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
147 case ILO_BLITTER_CLEAR_SURFACE:
148 util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
150 case ILO_BLITTER_BLIT:
151 util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
152 util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
154 util_blitter_save_fragment_sampler_states(ilo->blitter,
155 ilo->samplers[PIPE_SHADER_FRAGMENT].num_samplers,
156 (void **) ilo->samplers[PIPE_SHADER_FRAGMENT].samplers);
158 util_blitter_save_fragment_sampler_views(ilo->blitter,
159 ilo->sampler_views[PIPE_SHADER_FRAGMENT].num_views,
160 ilo->sampler_views[PIPE_SHADER_FRAGMENT].views);
162 /* disable render condition? */
170 ilo_blitter_end(struct ilo_context *ilo)
175 ilo_clear(struct pipe_context *pipe,
177 const union pipe_color_union *color,
181 struct ilo_context *ilo = ilo_context(pipe);
183 /* TODO we should pause/resume some queries */
184 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR);
186 util_blitter_clear(ilo->blitter,
187 ilo->framebuffer.width, ilo->framebuffer.height,
188 ilo->framebuffer.nr_cbufs, buffers,
189 (ilo->framebuffer.nr_cbufs) ? ilo->framebuffer.cbufs[0]->format :
191 color, depth, stencil);
193 ilo_blitter_end(ilo);
197 ilo_clear_render_target(struct pipe_context *pipe,
198 struct pipe_surface *dst,
199 const union pipe_color_union *color,
200 unsigned dstx, unsigned dsty,
201 unsigned width, unsigned height)
203 struct ilo_context *ilo = ilo_context(pipe);
204 union util_color packed;
206 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
209 if (dstx + width > dst->width)
210 width = dst->width - dstx;
211 if (dsty + height > dst->height)
212 height = dst->height - dsty;
214 util_pack_color(color->f, dst->format, &packed);
216 /* try HW blit first */
217 if (blitter_xy_color_blt(pipe, dst->texture,
219 dstx + width, dsty + height,
223 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
224 util_blitter_clear_render_target(ilo->blitter,
225 dst, color, dstx, dsty, width, height);
226 ilo_blitter_end(ilo);
230 ilo_clear_depth_stencil(struct pipe_context *pipe,
231 struct pipe_surface *dst,
232 unsigned clear_flags,
235 unsigned dstx, unsigned dsty,
236 unsigned width, unsigned height)
238 struct ilo_context *ilo = ilo_context(pipe);
241 * The PRM claims that HW blit supports Y-tiling since GEN6, but it does
242 * not tell us how to program it. Since depth buffers are always Y-tiled,
243 * HW blit will not work.
245 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
246 util_blitter_clear_depth_stencil(ilo->blitter,
247 dst, clear_flags, depth, stencil, dstx, dsty, width, height);
248 ilo_blitter_end(ilo);
252 ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
254 struct ilo_context *ilo = ilo_context(pipe);
255 struct pipe_blit_info skip_stencil;
257 if (util_try_blit_via_copy_region(pipe, info))
260 if (!util_blitter_is_blit_supported(ilo->blitter, info)) {
261 /* try without stencil */
262 if (info->mask & PIPE_MASK_S) {
263 skip_stencil = *info;
264 skip_stencil.mask = info->mask & ~PIPE_MASK_S;
266 if (util_blitter_is_blit_supported(ilo->blitter, &skip_stencil))
267 info = &skip_stencil;
270 if (info == &skip_stencil) {
271 ilo_warn("ignore stencil buffer blitting\n");
274 ilo_warn("failed to blit with the generic blitter\n");
279 ilo_blitter_begin(ilo, ILO_BLITTER_BLIT);
280 util_blitter_blit(ilo->blitter, info);
281 ilo_blitter_end(ilo);
285 * Initialize blit-related functions.
288 ilo_init_blit_functions(struct ilo_context *ilo)
290 ilo->base.resource_copy_region = util_resource_copy_region;
291 ilo->base.blit = ilo_blit;
293 ilo->base.clear = ilo_clear;
294 ilo->base.clear_render_target = ilo_clear_render_target;
295 ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;