OSDN Git Service

ilo: replace cp hooks by cp owner and flush callback
[android-x86/external-mesa.git] / src / gallium / drivers / ilo / ilo_blit.c
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2012-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_clear.h"
30 #include "util/u_pack_color.h"
31 #include "util/u_surface.h"
32 #include "intel_reg.h"
33
34 #include "ilo_context.h"
35 #include "ilo_cp.h"
36 #include "ilo_resource.h"
37 #include "ilo_screen.h"
38 #include "ilo_blit.h"
39
40 static bool
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,
45                      uint32_t color)
46 {
47    const int cmd_len = 6;
48    struct ilo_context *ilo = ilo_context(pipe);
49    struct ilo_texture *tex = ilo_texture(res);
50    uint32_t cmd, br13;
51    int cpp, stride;
52    struct intel_bo *bo_check[2];
53
54    /* how to support Y-tiling? */
55    if (tex->tiling == INTEL_TILING_Y)
56       return false;
57
58    /* nothing to clear */
59    if (x1 >= x2 || y1 >= y2)
60       return true;
61
62    cmd = XY_COLOR_BLT_CMD | (cmd_len - 2);
63    br13 = 0xf0 << 16;
64
65    cpp = util_format_get_blocksize(tex->base.format);
66    switch (cpp) {
67    case 4:
68       cmd |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
69       br13 |= BR13_8888;
70       break;
71    case 2:
72       br13 |= BR13_565;
73       break;
74    case 1:
75       br13 |= BR13_8;
76       break;
77    default:
78       return false;
79       break;
80    }
81
82    stride = tex->bo_stride;
83    if (tex->tiling != INTEL_TILING_NONE) {
84       assert(tex->tiling == INTEL_TILING_X);
85
86       cmd |= XY_DST_TILED;
87       /* in dwords */
88       stride /= 4;
89    }
90
91    ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT);
92    ilo_cp_set_owner(ilo->cp, NULL, 0);
93
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);
99
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,
106                    INTEL_DOMAIN_RENDER,
107                    INTEL_DOMAIN_RENDER);
108    ilo_cp_write(ilo->cp, color);
109    ilo_cp_end(ilo->cp);
110
111    return true;
112 }
113
114 enum ilo_blitter_op {
115    ILO_BLITTER_CLEAR,
116    ILO_BLITTER_CLEAR_SURFACE,
117    ILO_BLITTER_BLIT,
118 };
119
120 static void
121 ilo_blitter_begin(struct ilo_context *ilo, enum ilo_blitter_op op)
122 {
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);
132
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);
137
138    /* undocumented? */
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);
142
143    switch (op) {
144    case ILO_BLITTER_CLEAR:
145       util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
146       break;
147    case ILO_BLITTER_CLEAR_SURFACE:
148       util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
149       break;
150    case ILO_BLITTER_BLIT:
151       util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
152       util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
153
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);
157
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);
161
162       /* disable render condition? */
163       break;
164    default:
165       break;
166    }
167 }
168
169 static void
170 ilo_blitter_end(struct ilo_context *ilo)
171 {
172 }
173
174 static void
175 ilo_clear(struct pipe_context *pipe,
176           unsigned buffers,
177           const union pipe_color_union *color,
178           double depth,
179           unsigned stencil)
180 {
181    struct ilo_context *ilo = ilo_context(pipe);
182
183    /* TODO we should pause/resume some queries */
184    ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR);
185
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 :
190                                         PIPE_FORMAT_NONE,
191          color, depth, stencil);
192
193    ilo_blitter_end(ilo);
194 }
195
196 static void
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)
202 {
203    struct ilo_context *ilo = ilo_context(pipe);
204    union util_color packed;
205
206    if (!width || !height || dstx >= dst->width || dsty >= dst->height)
207       return;
208
209    if (dstx + width > dst->width)
210       width = dst->width - dstx;
211    if (dsty + height > dst->height)
212       height = dst->height - dsty;
213
214    util_pack_color(color->f, dst->format, &packed);
215
216    /* try HW blit first */
217    if (blitter_xy_color_blt(pipe, dst->texture,
218                             dstx, dsty,
219                             dstx + width, dsty + height,
220                             packed.ui))
221       return;
222
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);
227 }
228
229 static void
230 ilo_clear_depth_stencil(struct pipe_context *pipe,
231                         struct pipe_surface *dst,
232                         unsigned clear_flags,
233                         double depth,
234                         unsigned stencil,
235                         unsigned dstx, unsigned dsty,
236                         unsigned width, unsigned height)
237 {
238    struct ilo_context *ilo = ilo_context(pipe);
239
240    /*
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.
244     */
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);
249 }
250
251 static void
252 ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
253 {
254    struct ilo_context *ilo = ilo_context(pipe);
255    struct pipe_blit_info skip_stencil;
256
257    if (util_try_blit_via_copy_region(pipe, info))
258       return;
259
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;
265
266          if (util_blitter_is_blit_supported(ilo->blitter, &skip_stencil))
267             info = &skip_stencil;
268       }
269
270       if (info == &skip_stencil) {
271          ilo_warn("ignore stencil buffer blitting\n");
272       }
273       else {
274          ilo_warn("failed to blit with the generic blitter\n");
275          return;
276       }
277    }
278
279    ilo_blitter_begin(ilo, ILO_BLITTER_BLIT);
280    util_blitter_blit(ilo->blitter, info);
281    ilo_blitter_end(ilo);
282 }
283
284 /**
285  * Initialize blit-related functions.
286  */
287 void
288 ilo_init_blit_functions(struct ilo_context *ilo)
289 {
290    ilo->base.resource_copy_region = util_resource_copy_region;
291    ilo->base.blit = ilo_blit;
292
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;
296 }