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
;