nv50/ir/tgsi: TGSI_OPCODE_POW replicates its result
[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 if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ilo->fb.state.zsbuf) {
69 if (ilo_blitter_rectlist_clear_zs(ilo->blitter, ilo->fb.state.zsbuf,
70 buffers & PIPE_CLEAR_DEPTHSTENCIL, depth, stencil))
71 buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
72
73 if (!buffers)
74 return;
75 }
76
77 ilo_blitter_pipe_clear_fb(ilo->blitter, buffers, color, depth, stencil);
78 }
79
80 static void
81 ilo_clear_render_target(struct pipe_context *pipe,
82 struct pipe_surface *dst,
83 const union pipe_color_union *color,
84 unsigned dstx, unsigned dsty,
85 unsigned width, unsigned height)
86 {
87 struct ilo_context *ilo = ilo_context(pipe);
88
89 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
90 return;
91
92 if (dstx + width > dst->width)
93 width = dst->width - dstx;
94 if (dsty + height > dst->height)
95 height = dst->height - dsty;
96
97 if (ilo_blitter_blt_clear_rt(ilo->blitter,
98 dst, color, dstx, dsty, width, height))
99 return;
100
101 ilo_blitter_pipe_clear_rt(ilo->blitter,
102 dst, color, dstx, dsty, width, height);
103 }
104
105 static void
106 ilo_clear_depth_stencil(struct pipe_context *pipe,
107 struct pipe_surface *dst,
108 unsigned clear_flags,
109 double depth,
110 unsigned stencil,
111 unsigned dstx, unsigned dsty,
112 unsigned width, unsigned height)
113 {
114 struct ilo_context *ilo = ilo_context(pipe);
115
116 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
117 return;
118
119 if (dstx + width > dst->width)
120 width = dst->width - dstx;
121 if (dsty + height > dst->height)
122 height = dst->height - dsty;
123
124 if (ilo_blitter_blt_clear_zs(ilo->blitter,
125 dst, clear_flags, depth, stencil, dstx, dsty, width, height))
126 return;
127
128 ilo_blitter_pipe_clear_zs(ilo->blitter,
129 dst, clear_flags, depth, stencil, dstx, dsty, width, height);
130 }
131
132 static void
133 ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
134 {
135 struct ilo_context *ilo = ilo_context(pipe);
136
137 ilo_blitter_pipe_blit(ilo->blitter, info);
138 }
139
140 static void
141 ilo_flush_resource(struct pipe_context *pipe, struct pipe_resource *res)
142 {
143 struct ilo_context *ilo = ilo_context(pipe);
144 const unsigned flags = ILO_TEXTURE_CPU_READ |
145 ILO_TEXTURE_BLT_READ |
146 ILO_TEXTURE_RENDER_READ;
147
148 ilo_blit_resolve_resource(ilo, res, flags);
149 }
150
151 void
152 ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
153 struct pipe_resource *res, unsigned level,
154 unsigned first_slice, unsigned num_slices,
155 unsigned resolve_flags)
156 {
157 struct ilo_texture *tex = ilo_texture(res);
158 const unsigned any_reader =
159 ILO_TEXTURE_RENDER_READ |
160 ILO_TEXTURE_BLT_READ |
161 ILO_TEXTURE_CPU_READ;
162 const unsigned other_writers =
163 ILO_TEXTURE_BLT_WRITE |
164 ILO_TEXTURE_CPU_WRITE;
165 unsigned i;
166
167 assert(tex->base.target != PIPE_BUFFER &&
168 ilo_texture_can_enable_hiz(tex, level, first_slice, num_slices));
169
170 if (resolve_flags & ILO_TEXTURE_RENDER_WRITE) {
171 /*
172 * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We
173 * need to perform a HiZ Buffer Resolve in case the resource was
174 * previously written by another writer, unless this is a clear.
175 *
176 * When slices have different clear values, we perform a Depth Buffer
177 * Resolve on all slices not sharing the clear value of the first slice.
178 * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can
179 * be made to have the same clear value as the first slice does. This
180 * way,
181 *
182 * - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice
183 * - we will not resolve unnecessarily next time this function is
184 * called
185 *
186 * Since slice clear value is the value the slice is cleared to when
187 * ILO_TEXTURE_CLEAR is set, the bit needs to be unset.
188 */
189 assert(!(resolve_flags & (other_writers | any_reader)));
190
191 if (!(resolve_flags & ILO_TEXTURE_CLEAR)) {
192 bool set_clear_value = false;
193 uint32_t first_clear_value;
194
195 for (i = 0; i < num_slices; i++) {
196 const struct ilo_texture_slice *slice =
197 ilo_texture_get_slice(tex, level, first_slice + i);
198
199 if (slice->flags & other_writers) {
200 ilo_blitter_rectlist_resolve_hiz(ilo->blitter,
201 res, level, first_slice + i);
202 }
203 else if (i == 0) {
204 first_clear_value = slice->clear_value;
205 }
206 else if (slice->clear_value != first_clear_value &&
207 (slice->flags & ILO_TEXTURE_RENDER_WRITE)) {
208 ilo_blitter_rectlist_resolve_z(ilo->blitter,
209 res, level, first_slice + i);
210 set_clear_value = true;
211 }
212 }
213
214 if (set_clear_value) {
215 /* ILO_TEXTURE_CLEAR will be cleared later */
216 ilo_texture_set_slice_clear_value(tex, level,
217 first_slice, num_slices, first_clear_value);
218 }
219 }
220 }
221 else if ((resolve_flags & any_reader) ||
222 ((resolve_flags & other_writers) &&
223 !(resolve_flags & ILO_TEXTURE_CLEAR))) {
224 /*
225 * When there is at least a reader or writer, we need to perform a
226 * Depth Buffer Resolve in case the resource was previously written
227 * by ILO_TEXTURE_RENDER_WRITE.
228 */
229 for (i = 0; i < num_slices; i++) {
230 const struct ilo_texture_slice *slice =
231 ilo_texture_get_slice(tex, level, first_slice + i);
232
233 if (slice->flags & ILO_TEXTURE_RENDER_WRITE) {
234 ilo_blitter_rectlist_resolve_z(ilo->blitter,
235 &tex->base, level, first_slice + i);
236 }
237 }
238 }
239 }
240
241 /**
242 * Initialize blit-related functions.
243 */
244 void
245 ilo_init_blit_functions(struct ilo_context *ilo)
246 {
247 ilo->base.resource_copy_region = ilo_resource_copy_region;
248 ilo->base.blit = ilo_blit;
249 ilo->base.flush_resource = ilo_flush_resource;
250
251 ilo->base.clear = ilo_clear;
252 ilo->base.clear_render_target = ilo_clear_render_target;
253 ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;
254 }