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
*r
,
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_resource
*res
= ilo_resource(r
);
52 struct intel_bo
*bo_check
[2];
54 /* how to support Y-tiling? */
55 if (res
->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(res
->base
.format
);
68 cmd
|= XY_BLT_WRITE_ALPHA
| XY_BLT_WRITE_RGB
;
82 stride
= res
->bo_stride
;
83 if (res
->tiling
!= INTEL_TILING_NONE
) {
84 assert(res
->tiling
== INTEL_TILING_X
);
91 /* make room if necessary */
92 bo_check
[0] = ilo
->cp
->bo
;
93 bo_check
[1] = res
->bo
;
94 if (ilo
->winsys
->check_aperture_space(ilo
->winsys
, bo_check
, 2))
95 ilo_cp_flush(ilo
->cp
);
97 ilo_cp_set_ring(ilo
->cp
, ILO_CP_RING_BLT
);
99 ilo_cp_begin(ilo
->cp
, cmd_len
);
100 ilo_cp_write(ilo
->cp
, cmd
);
101 ilo_cp_write(ilo
->cp
, br13
| stride
);
102 ilo_cp_write(ilo
->cp
, (y1
<< 16) | x1
);
103 ilo_cp_write(ilo
->cp
, (y2
<< 16) | x2
);
104 ilo_cp_write_bo(ilo
->cp
, 0, res
->bo
,
106 INTEL_DOMAIN_RENDER
);
107 ilo_cp_write(ilo
->cp
, color
);
113 enum ilo_blitter_op
{
115 ILO_BLITTER_CLEAR_SURFACE
,
120 ilo_blitter_begin(struct ilo_context
*ilo
, enum ilo_blitter_op op
)
122 /* as documented in util/u_blitter.h */
123 util_blitter_save_vertex_buffer_slot(ilo
->blitter
,
124 ilo
->vertex_buffers
.buffers
);
125 util_blitter_save_vertex_elements(ilo
->blitter
, ilo
->vertex_elements
);
126 util_blitter_save_vertex_shader(ilo
->blitter
, ilo
->vs
);
127 util_blitter_save_geometry_shader(ilo
->blitter
, ilo
->gs
);
128 util_blitter_save_so_targets(ilo
->blitter
,
129 ilo
->stream_output_targets
.num_targets
,
130 ilo
->stream_output_targets
.targets
);
132 util_blitter_save_fragment_shader(ilo
->blitter
, ilo
->fs
);
133 util_blitter_save_depth_stencil_alpha(ilo
->blitter
,
134 ilo
->depth_stencil_alpha
);
135 util_blitter_save_blend(ilo
->blitter
, ilo
->blend
);
138 util_blitter_save_viewport(ilo
->blitter
, &ilo
->viewport
);
139 util_blitter_save_stencil_ref(ilo
->blitter
, &ilo
->stencil_ref
);
140 util_blitter_save_sample_mask(ilo
->blitter
, ilo
->sample_mask
);
143 case ILO_BLITTER_CLEAR
:
144 util_blitter_save_rasterizer(ilo
->blitter
, ilo
->rasterizer
);
146 case ILO_BLITTER_CLEAR_SURFACE
:
147 util_blitter_save_framebuffer(ilo
->blitter
, &ilo
->framebuffer
);
149 case ILO_BLITTER_BLIT
:
150 util_blitter_save_rasterizer(ilo
->blitter
, ilo
->rasterizer
);
151 util_blitter_save_framebuffer(ilo
->blitter
, &ilo
->framebuffer
);
153 util_blitter_save_fragment_sampler_states(ilo
->blitter
,
154 ilo
->samplers
[PIPE_SHADER_FRAGMENT
].num_samplers
,
155 (void **) ilo
->samplers
[PIPE_SHADER_FRAGMENT
].samplers
);
157 util_blitter_save_fragment_sampler_views(ilo
->blitter
,
158 ilo
->sampler_views
[PIPE_SHADER_FRAGMENT
].num_views
,
159 ilo
->sampler_views
[PIPE_SHADER_FRAGMENT
].views
);
161 /* disable render condition? */
169 ilo_blitter_end(struct ilo_context
*ilo
)
174 ilo_clear(struct pipe_context
*pipe
,
176 const union pipe_color_union
*color
,
180 struct ilo_context
*ilo
= ilo_context(pipe
);
182 /* TODO we should pause/resume some queries */
183 ilo_blitter_begin(ilo
, ILO_BLITTER_CLEAR
);
185 util_blitter_clear(ilo
->blitter
,
186 ilo
->framebuffer
.width
, ilo
->framebuffer
.height
,
187 ilo
->framebuffer
.nr_cbufs
, buffers
,
188 (ilo
->framebuffer
.nr_cbufs
) ? ilo
->framebuffer
.cbufs
[0]->format
:
190 color
, depth
, stencil
);
192 ilo_blitter_end(ilo
);
196 ilo_clear_render_target(struct pipe_context
*pipe
,
197 struct pipe_surface
*dst
,
198 const union pipe_color_union
*color
,
199 unsigned dstx
, unsigned dsty
,
200 unsigned width
, unsigned height
)
202 struct ilo_context
*ilo
= ilo_context(pipe
);
203 union util_color packed
;
205 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
208 if (dstx
+ width
> dst
->width
)
209 width
= dst
->width
- dstx
;
210 if (dsty
+ height
> dst
->height
)
211 height
= dst
->height
- dsty
;
213 util_pack_color(color
->f
, dst
->format
, &packed
);
215 /* try HW blit first */
216 if (blitter_xy_color_blt(pipe
, dst
->texture
,
218 dstx
+ width
, dsty
+ height
,
222 ilo_blitter_begin(ilo
, ILO_BLITTER_CLEAR_SURFACE
);
223 util_blitter_clear_render_target(ilo
->blitter
,
224 dst
, color
, dstx
, dsty
, width
, height
);
225 ilo_blitter_end(ilo
);
229 ilo_clear_depth_stencil(struct pipe_context
*pipe
,
230 struct pipe_surface
*dst
,
231 unsigned clear_flags
,
234 unsigned dstx
, unsigned dsty
,
235 unsigned width
, unsigned height
)
237 struct ilo_context
*ilo
= ilo_context(pipe
);
240 * The PRM claims that HW blit supports Y-tiling since GEN6, but it does
241 * not tell us how to program it. Since depth buffers are always Y-tiled,
242 * HW blit will not work.
244 ilo_blitter_begin(ilo
, ILO_BLITTER_CLEAR_SURFACE
);
245 util_blitter_clear_depth_stencil(ilo
->blitter
,
246 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
);
247 ilo_blitter_end(ilo
);
251 ilo_blit(struct pipe_context
*pipe
, const struct pipe_blit_info
*info
)
253 struct ilo_context
*ilo
= ilo_context(pipe
);
254 struct pipe_blit_info skip_stencil
;
256 if (util_try_blit_via_copy_region(pipe
, info
))
259 if (!util_blitter_is_blit_supported(ilo
->blitter
, info
)) {
260 /* try without stencil */
261 if (info
->mask
& PIPE_MASK_S
) {
262 skip_stencil
= *info
;
263 skip_stencil
.mask
= info
->mask
& ~PIPE_MASK_S
;
265 if (util_blitter_is_blit_supported(ilo
->blitter
, &skip_stencil
))
266 info
= &skip_stencil
;
269 if (info
== &skip_stencil
) {
270 ilo_warn("ignore stencil buffer blitting\n");
273 ilo_warn("failed to blit with the generic blitter\n");
278 ilo_blitter_begin(ilo
, ILO_BLITTER_BLIT
);
279 util_blitter_blit(ilo
->blitter
, info
);
280 ilo_blitter_end(ilo
);
284 * Initialize blit-related functions.
287 ilo_init_blit_functions(struct ilo_context
*ilo
)
289 ilo
->base
.resource_copy_region
= util_resource_copy_region
;
290 ilo
->base
.blit
= ilo_blit
;
292 ilo
->base
.clear
= ilo_clear
;
293 ilo
->base
.clear_render_target
= ilo_clear_render_target
;
294 ilo
->base
.clear_depth_stencil
= ilo_clear_depth_stencil
;