clover: Define an intrusive smart reference class.
[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_surface.h"
29
30 #include "ilo_blitter.h"
31 #include "ilo_context.h"
32 #include "ilo_blit.h"
33
34 static void
35 ilo_resource_copy_region(struct pipe_context *pipe,
36 struct pipe_resource *dst,
37 unsigned dst_level,
38 unsigned dstx, unsigned dsty, unsigned dstz,
39 struct pipe_resource *src,
40 unsigned src_level,
41 const struct pipe_box *src_box)
42 {
43 struct ilo_context *ilo = ilo_context(pipe);
44
45 if (ilo_blitter_blt_copy_resource(ilo->blitter,
46 dst, dst_level, dstx, dsty, dstz,
47 src, src_level, src_box))
48 return;
49
50 if (ilo_blitter_pipe_copy_resource(ilo->blitter,
51 dst, dst_level, dstx, dsty, dstz,
52 src, src_level, src_box))
53 return;
54
55 util_resource_copy_region(&ilo->base, dst, dst_level,
56 dstx, dsty, dstz, src, src_level, src_box);
57 }
58
59 static void
60 ilo_clear(struct pipe_context *pipe,
61 unsigned buffers,
62 const union pipe_color_union *color,
63 double depth,
64 unsigned stencil)
65 {
66 struct ilo_context *ilo = ilo_context(pipe);
67
68 ilo_blitter_pipe_clear_fb(ilo->blitter, buffers, color, depth, stencil);
69 }
70
71 static void
72 ilo_clear_render_target(struct pipe_context *pipe,
73 struct pipe_surface *dst,
74 const union pipe_color_union *color,
75 unsigned dstx, unsigned dsty,
76 unsigned width, unsigned height)
77 {
78 struct ilo_context *ilo = ilo_context(pipe);
79
80 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
81 return;
82
83 if (dstx + width > dst->width)
84 width = dst->width - dstx;
85 if (dsty + height > dst->height)
86 height = dst->height - dsty;
87
88 if (ilo_blitter_blt_clear_rt(ilo->blitter,
89 dst, color, dstx, dsty, width, height))
90 return;
91
92 ilo_blitter_pipe_clear_rt(ilo->blitter,
93 dst, color, dstx, dsty, width, height);
94 }
95
96 static void
97 ilo_clear_depth_stencil(struct pipe_context *pipe,
98 struct pipe_surface *dst,
99 unsigned clear_flags,
100 double depth,
101 unsigned stencil,
102 unsigned dstx, unsigned dsty,
103 unsigned width, unsigned height)
104 {
105 struct ilo_context *ilo = ilo_context(pipe);
106
107 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
108 return;
109
110 if (dstx + width > dst->width)
111 width = dst->width - dstx;
112 if (dsty + height > dst->height)
113 height = dst->height - dsty;
114
115 if (ilo_blitter_blt_clear_zs(ilo->blitter,
116 dst, clear_flags, depth, stencil, dstx, dsty, width, height))
117 return;
118
119 ilo_blitter_pipe_clear_zs(ilo->blitter,
120 dst, clear_flags, depth, stencil, dstx, dsty, width, height);
121 }
122
123 static void
124 ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
125 {
126 struct ilo_context *ilo = ilo_context(pipe);
127
128 ilo_blitter_pipe_blit(ilo->blitter, info);
129 }
130
131 static void
132 ilo_flush_resource(struct pipe_context *pipe, struct pipe_resource *res)
133 {
134 struct ilo_context *ilo = ilo_context(pipe);
135 const unsigned flags = ILO_TEXTURE_CPU_READ |
136 ILO_TEXTURE_BLT_READ |
137 ILO_TEXTURE_RENDER_READ;
138
139 ilo_blit_resolve_resource(ilo, res, flags);
140 }
141
142 void
143 ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
144 struct pipe_resource *res, unsigned level,
145 unsigned first_slice, unsigned num_slices,
146 unsigned flags)
147 {
148 struct ilo_texture *tex = ilo_texture(res);
149 const unsigned any_reader =
150 ILO_TEXTURE_RENDER_READ |
151 ILO_TEXTURE_BLT_READ |
152 ILO_TEXTURE_CPU_READ;
153 const unsigned other_writers =
154 ILO_TEXTURE_BLT_WRITE |
155 ILO_TEXTURE_CPU_WRITE;
156 unsigned i;
157
158 assert(tex->base.target != PIPE_BUFFER &&
159 ilo_texture_can_enable_hiz(tex, level, first_slice, num_slices));
160
161 if (flags & ILO_TEXTURE_RENDER_WRITE) {
162 /*
163 * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We
164 * need to perform a HiZ Buffer Resolve in case the resource was
165 * previously written by another writer, unless this is a clear.
166 */
167 assert(!(flags & (other_writers | any_reader)));
168
169 if (!(flags & ILO_TEXTURE_CLEAR)) {
170 for (i = 0; i < num_slices; i++) {
171 const struct ilo_texture_slice *slice =
172 ilo_texture_get_slice(tex, level, first_slice + i);
173
174 if (slice->flags & other_writers) {
175 ilo_blitter_rectlist_resolve_hiz(ilo->blitter,
176 res, level, first_slice + i);
177 }
178 }
179 }
180 }
181 else if ((flags & any_reader) ||
182 ((flags & other_writers) && !(flags & ILO_TEXTURE_CLEAR))) {
183 /*
184 * When there is at least a reader or writer, we need to perform a
185 * Depth Buffer Resolve in case the resource was previously written
186 * by ILO_TEXTURE_RENDER_WRITE.
187 */
188 for (i = 0; i < num_slices; i++) {
189 const struct ilo_texture_slice *slice =
190 ilo_texture_get_slice(tex, level, first_slice + i);
191
192 if (slice->flags & ILO_TEXTURE_RENDER_WRITE) {
193 ilo_blitter_rectlist_resolve_z(ilo->blitter,
194 &tex->base, level, first_slice + i);
195 }
196 }
197 }
198 }
199
200 /**
201 * Initialize blit-related functions.
202 */
203 void
204 ilo_init_blit_functions(struct ilo_context *ilo)
205 {
206 ilo->base.resource_copy_region = ilo_resource_copy_region;
207 ilo->base.blit = ilo_blit;
208 ilo->base.flush_resource = ilo_flush_resource;
209
210 ilo->base.clear = ilo_clear;
211 ilo->base.clear_render_target = ilo_clear_render_target;
212 ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;
213 }