Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /* |
2 | * Copyright © 2015 Broadcom |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice (including the next |
||
12 | * paragraph) shall be included in all copies or substantial portions of the |
||
13 | * Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||
21 | * IN THE SOFTWARE. |
||
22 | */ |
||
23 | |||
24 | #include "util/u_format.h" |
||
25 | #include "util/u_surface.h" |
||
26 | #include "util/u_blitter.h" |
||
27 | #include "vc4_context.h" |
||
28 | |||
29 | static void |
||
30 | vc4_tile_blit_color_rcl(struct vc4_context *vc4, |
||
31 | struct vc4_surface *dst_surf, |
||
32 | struct vc4_surface *src_surf) |
||
33 | { |
||
34 | struct vc4_resource *src = vc4_resource(src_surf->base.texture); |
||
35 | struct vc4_resource *dst = vc4_resource(dst_surf->base.texture); |
||
36 | |||
37 | uint32_t min_x_tile = 0; |
||
38 | uint32_t min_y_tile = 0; |
||
39 | uint32_t max_x_tile = (dst_surf->base.width - 1) / 64; |
||
40 | uint32_t max_y_tile = (dst_surf->base.height - 1) / 64; |
||
41 | uint32_t xtiles = max_x_tile - min_x_tile + 1; |
||
42 | uint32_t ytiles = max_y_tile - min_y_tile + 1; |
||
43 | uint32_t reloc_size = 9; |
||
44 | uint32_t config_size = 11 + reloc_size; |
||
45 | uint32_t loadstore_size = 7 + reloc_size; |
||
46 | uint32_t tilecoords_size = 3; |
||
47 | cl_ensure_space(&vc4->rcl, |
||
48 | config_size + |
||
49 | xtiles * ytiles * (loadstore_size * 2 + |
||
50 | tilecoords_size * 1)); |
||
51 | cl_ensure_space(&vc4->bo_handles, 2 * sizeof(uint32_t)); |
||
52 | cl_ensure_space(&vc4->bo_pointers, 2 * sizeof(struct vc4_bo *)); |
||
53 | |||
54 | cl_start_reloc(&vc4->rcl, 1); |
||
55 | cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); |
||
56 | cl_reloc(vc4, &vc4->rcl, dst->bo, dst_surf->offset); |
||
57 | cl_u16(&vc4->rcl, dst_surf->base.width); |
||
58 | cl_u16(&vc4->rcl, dst_surf->base.height); |
||
59 | cl_u16(&vc4->rcl, ((dst_surf->tiling << |
||
60 | VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT) | |
||
61 | (vc4_rt_format_is_565(dst_surf->base.format) ? |
||
62 | VC4_RENDER_CONFIG_FORMAT_BGR565 : |
||
63 | VC4_RENDER_CONFIG_FORMAT_RGBA8888))); |
||
64 | |||
65 | uint32_t src_hindex = vc4_gem_hindex(vc4, src->bo); |
||
66 | |||
67 | for (int y = min_y_tile; y <= max_y_tile; y++) { |
||
68 | for (int x = min_x_tile; x <= max_x_tile; x++) { |
||
69 | bool end_of_frame = (x == max_x_tile && |
||
70 | y == max_y_tile); |
||
71 | |||
72 | cl_start_reloc(&vc4->rcl, 1); |
||
73 | cl_u8(&vc4->rcl, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); |
||
74 | cl_u8(&vc4->rcl, |
||
75 | VC4_LOADSTORE_TILE_BUFFER_COLOR | |
||
76 | (src_surf->tiling << |
||
77 | VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT)); |
||
78 | cl_u8(&vc4->rcl, |
||
79 | vc4_rt_format_is_565(src_surf->base.format) ? |
||
80 | VC4_LOADSTORE_TILE_BUFFER_BGR565 : |
||
81 | VC4_LOADSTORE_TILE_BUFFER_RGBA8888); |
||
82 | cl_reloc_hindex(&vc4->rcl, src_hindex, |
||
83 | src_surf->offset); |
||
84 | |||
85 | cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES); |
||
86 | cl_u8(&vc4->rcl, x); |
||
87 | cl_u8(&vc4->rcl, y); |
||
88 | |||
89 | if (end_of_frame) { |
||
90 | cl_u8(&vc4->rcl, |
||
91 | VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF); |
||
92 | } else { |
||
93 | cl_u8(&vc4->rcl, |
||
94 | VC4_PACKET_STORE_MS_TILE_BUFFER); |
||
95 | } |
||
96 | } |
||
97 | } |
||
98 | |||
99 | vc4->draw_min_x = 0; |
||
100 | vc4->draw_min_y = 0; |
||
101 | vc4->draw_max_x = dst_surf->base.width; |
||
102 | vc4->draw_max_y = dst_surf->base.height; |
||
103 | |||
104 | dst->writes++; |
||
105 | vc4->needs_flush = true; |
||
106 | } |
||
107 | |||
108 | static struct vc4_surface * |
||
109 | vc4_get_blit_surface(struct pipe_context *pctx, |
||
110 | struct pipe_resource *prsc, unsigned level) |
||
111 | { |
||
112 | struct pipe_surface tmpl; |
||
113 | |||
114 | memset(&tmpl, 0, sizeof(tmpl)); |
||
115 | tmpl.format = prsc->format; |
||
116 | tmpl.u.tex.level = level; |
||
117 | tmpl.u.tex.first_layer = 0; |
||
118 | tmpl.u.tex.last_layer = 0; |
||
119 | |||
120 | return vc4_surface(pctx->create_surface(pctx, prsc, &tmpl)); |
||
121 | } |
||
122 | |||
123 | static bool |
||
124 | vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) |
||
125 | { |
||
126 | struct vc4_context *vc4 = vc4_context(pctx); |
||
127 | |||
128 | if (util_format_is_depth_or_stencil(info->dst.resource->format)) |
||
129 | return false; |
||
130 | |||
131 | if ((info->mask & PIPE_MASK_RGBA) == 0) |
||
132 | return false; |
||
133 | |||
134 | if (info->dst.box.x != 0 || info->dst.box.y != 0 || |
||
135 | info->src.box.x != 0 || info->src.box.y != 0 || |
||
136 | info->dst.box.width != info->src.box.width || |
||
137 | info->dst.box.height != info->src.box.height) { |
||
138 | return false; |
||
139 | } |
||
140 | |||
141 | if (info->dst.resource->format != info->src.resource->format) |
||
142 | return false; |
||
143 | |||
144 | struct vc4_surface *dst_surf = |
||
145 | vc4_get_blit_surface(pctx, info->dst.resource, info->dst.level); |
||
146 | struct vc4_surface *src_surf = |
||
147 | vc4_get_blit_surface(pctx, info->src.resource, info->src.level); |
||
148 | |||
149 | vc4_flush(pctx); |
||
150 | vc4_tile_blit_color_rcl(vc4, dst_surf, src_surf); |
||
151 | vc4_job_submit(vc4); |
||
152 | |||
153 | pctx->surface_destroy(pctx, &dst_surf->base); |
||
154 | pctx->surface_destroy(pctx, &src_surf->base); |
||
155 | |||
156 | return true; |
||
157 | } |
||
158 | |||
159 | static bool |
||
160 | vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info) |
||
161 | { |
||
162 | struct vc4_context *vc4 = vc4_context(ctx); |
||
163 | |||
164 | if (!util_blitter_is_blit_supported(vc4->blitter, info)) { |
||
165 | fprintf(stderr, "blit unsupported %s -> %s", |
||
166 | util_format_short_name(info->src.resource->format), |
||
167 | util_format_short_name(info->dst.resource->format)); |
||
168 | return false; |
||
169 | } |
||
170 | |||
171 | util_blitter_save_vertex_buffer_slot(vc4->blitter, vc4->vertexbuf.vb); |
||
172 | util_blitter_save_vertex_elements(vc4->blitter, vc4->vtx); |
||
173 | util_blitter_save_vertex_shader(vc4->blitter, vc4->prog.bind_vs); |
||
174 | util_blitter_save_rasterizer(vc4->blitter, vc4->rasterizer); |
||
175 | util_blitter_save_viewport(vc4->blitter, &vc4->viewport); |
||
176 | util_blitter_save_scissor(vc4->blitter, &vc4->scissor); |
||
177 | util_blitter_save_fragment_shader(vc4->blitter, vc4->prog.bind_fs); |
||
178 | util_blitter_save_blend(vc4->blitter, vc4->blend); |
||
179 | util_blitter_save_depth_stencil_alpha(vc4->blitter, vc4->zsa); |
||
180 | util_blitter_save_stencil_ref(vc4->blitter, &vc4->stencil_ref); |
||
181 | util_blitter_save_sample_mask(vc4->blitter, vc4->sample_mask); |
||
182 | util_blitter_save_framebuffer(vc4->blitter, &vc4->framebuffer); |
||
183 | util_blitter_save_fragment_sampler_states(vc4->blitter, |
||
184 | vc4->fragtex.num_samplers, |
||
185 | (void **)vc4->fragtex.samplers); |
||
186 | util_blitter_save_fragment_sampler_views(vc4->blitter, |
||
187 | vc4->fragtex.num_textures, vc4->fragtex.textures); |
||
188 | |||
189 | util_blitter_blit(vc4->blitter, info); |
||
190 | |||
191 | return true; |
||
192 | } |
||
193 | |||
194 | /* Optimal hardware path for blitting pixels. |
||
195 | * Scaling, format conversion, up- and downsampling (resolve) are allowed. |
||
196 | */ |
||
197 | void |
||
198 | vc4_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) |
||
199 | { |
||
200 | struct pipe_blit_info info = *blit_info; |
||
201 | |||
202 | if (info.src.resource->nr_samples > 1 && |
||
203 | info.dst.resource->nr_samples <= 1 && |
||
204 | !util_format_is_depth_or_stencil(info.src.resource->format) && |
||
205 | !util_format_is_pure_integer(info.src.resource->format)) { |
||
206 | fprintf(stderr, "color resolve unimplemented"); |
||
207 | return; |
||
208 | } |
||
209 | |||
210 | if (vc4_tile_blit(pctx, blit_info)) |
||
211 | return; |
||
212 | |||
213 | if (util_try_blit_via_copy_region(pctx, &info)) { |
||
214 | return; /* done */ |
||
215 | } |
||
216 | |||
217 | if (info.mask & PIPE_MASK_S) { |
||
218 | fprintf(stderr, "cannot blit stencil, skipping"); |
||
219 | info.mask &= ~PIPE_MASK_S; |
||
220 | } |
||
221 | |||
222 | vc4_render_blit(pctx, &info); |
||
223 | }=> |