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_surface.h"
30 #include "ilo_blitter.h"
31 #include "ilo_context.h"
35 ilo_resource_copy_region(struct pipe_context
*pipe
,
36 struct pipe_resource
*dst
,
38 unsigned dstx
, unsigned dsty
, unsigned dstz
,
39 struct pipe_resource
*src
,
41 const struct pipe_box
*src_box
)
43 struct ilo_context
*ilo
= ilo_context(pipe
);
45 if (ilo_blitter_blt_copy_resource(ilo
->blitter
,
46 dst
, dst_level
, dstx
, dsty
, dstz
,
47 src
, src_level
, src_box
))
50 if (ilo_blitter_pipe_copy_resource(ilo
->blitter
,
51 dst
, dst_level
, dstx
, dsty
, dstz
,
52 src
, src_level
, src_box
))
55 util_resource_copy_region(&ilo
->base
, dst
, dst_level
,
56 dstx
, dsty
, dstz
, src
, src_level
, src_box
);
60 ilo_clear(struct pipe_context
*pipe
,
62 const union pipe_color_union
*color
,
66 struct ilo_context
*ilo
= ilo_context(pipe
);
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
;
77 ilo_blitter_pipe_clear_fb(ilo
->blitter
, buffers
, color
, depth
, stencil
);
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
)
87 struct ilo_context
*ilo
= ilo_context(pipe
);
89 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
92 if (dstx
+ width
> dst
->width
)
93 width
= dst
->width
- dstx
;
94 if (dsty
+ height
> dst
->height
)
95 height
= dst
->height
- dsty
;
97 if (ilo_blitter_blt_clear_rt(ilo
->blitter
,
98 dst
, color
, dstx
, dsty
, width
, height
))
101 ilo_blitter_pipe_clear_rt(ilo
->blitter
,
102 dst
, color
, dstx
, dsty
, width
, height
);
106 ilo_clear_depth_stencil(struct pipe_context
*pipe
,
107 struct pipe_surface
*dst
,
108 unsigned clear_flags
,
111 unsigned dstx
, unsigned dsty
,
112 unsigned width
, unsigned height
)
114 struct ilo_context
*ilo
= ilo_context(pipe
);
116 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
119 if (dstx
+ width
> dst
->width
)
120 width
= dst
->width
- dstx
;
121 if (dsty
+ height
> dst
->height
)
122 height
= dst
->height
- dsty
;
124 if (ilo_blitter_blt_clear_zs(ilo
->blitter
,
125 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
))
128 ilo_blitter_pipe_clear_zs(ilo
->blitter
,
129 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
);
133 ilo_blit(struct pipe_context
*pipe
, const struct pipe_blit_info
*info
)
135 struct ilo_context
*ilo
= ilo_context(pipe
);
137 ilo_blitter_pipe_blit(ilo
->blitter
, info
);
141 ilo_flush_resource(struct pipe_context
*pipe
, struct pipe_resource
*res
)
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
;
148 ilo_blit_resolve_resource(ilo
, res
, flags
);
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
)
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
;
167 assert(tex
->base
.target
!= PIPE_BUFFER
&&
168 ilo_texture_can_enable_hiz(tex
, level
, first_slice
, num_slices
));
170 if (resolve_flags
& ILO_TEXTURE_RENDER_WRITE
) {
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.
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
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
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.
189 assert(!(resolve_flags
& (other_writers
| any_reader
)));
191 if (!(resolve_flags
& ILO_TEXTURE_CLEAR
)) {
192 bool set_clear_value
= false;
193 uint32_t first_clear_value
;
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
);
199 if (slice
->flags
& other_writers
) {
200 ilo_blitter_rectlist_resolve_hiz(ilo
->blitter
,
201 res
, level
, first_slice
+ i
);
204 first_clear_value
= slice
->clear_value
;
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;
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
);
221 else if ((resolve_flags
& any_reader
) ||
222 ((resolve_flags
& other_writers
) &&
223 !(resolve_flags
& ILO_TEXTURE_CLEAR
))) {
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.
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
);
233 if (slice
->flags
& ILO_TEXTURE_RENDER_WRITE
) {
234 ilo_blitter_rectlist_resolve_z(ilo
->blitter
,
235 &tex
->base
, level
, first_slice
+ i
);
242 * Initialize blit-related functions.
245 ilo_init_blit_functions(struct ilo_context
*ilo
)
247 ilo
->base
.resource_copy_region
= ilo_resource_copy_region
;
248 ilo
->base
.blit
= ilo_blit
;
249 ilo
->base
.flush_resource
= ilo_flush_resource
;
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
;