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
);
67 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
69 if ((buffers
& PIPE_CLEAR_DEPTHSTENCIL
) && vec
->fb
.state
.zsbuf
) {
70 if (ilo_blitter_rectlist_clear_zs(ilo
->blitter
, vec
->fb
.state
.zsbuf
,
71 buffers
& PIPE_CLEAR_DEPTHSTENCIL
, depth
, stencil
))
72 buffers
&= ~PIPE_CLEAR_DEPTHSTENCIL
;
78 ilo_blitter_pipe_clear_fb(ilo
->blitter
, buffers
, color
, depth
, stencil
);
82 ilo_clear_render_target(struct pipe_context
*pipe
,
83 struct pipe_surface
*dst
,
84 const union pipe_color_union
*color
,
85 unsigned dstx
, unsigned dsty
,
86 unsigned width
, unsigned height
)
88 struct ilo_context
*ilo
= ilo_context(pipe
);
90 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
93 if (dstx
+ width
> dst
->width
)
94 width
= dst
->width
- dstx
;
95 if (dsty
+ height
> dst
->height
)
96 height
= dst
->height
- dsty
;
98 if (ilo_blitter_blt_clear_rt(ilo
->blitter
,
99 dst
, color
, dstx
, dsty
, width
, height
))
102 ilo_blitter_pipe_clear_rt(ilo
->blitter
,
103 dst
, color
, dstx
, dsty
, width
, height
);
107 ilo_clear_depth_stencil(struct pipe_context
*pipe
,
108 struct pipe_surface
*dst
,
109 unsigned clear_flags
,
112 unsigned dstx
, unsigned dsty
,
113 unsigned width
, unsigned height
)
115 struct ilo_context
*ilo
= ilo_context(pipe
);
117 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
120 if (dstx
+ width
> dst
->width
)
121 width
= dst
->width
- dstx
;
122 if (dsty
+ height
> dst
->height
)
123 height
= dst
->height
- dsty
;
125 if (ilo_blitter_blt_clear_zs(ilo
->blitter
,
126 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
))
129 ilo_blitter_pipe_clear_zs(ilo
->blitter
,
130 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
);
134 ilo_blit(struct pipe_context
*pipe
, const struct pipe_blit_info
*info
)
136 struct ilo_context
*ilo
= ilo_context(pipe
);
138 ilo_blitter_pipe_blit(ilo
->blitter
, info
);
142 ilo_flush_resource(struct pipe_context
*pipe
, struct pipe_resource
*res
)
144 struct ilo_context
*ilo
= ilo_context(pipe
);
145 const unsigned flags
= ILO_TEXTURE_CPU_READ
|
146 ILO_TEXTURE_BLT_READ
|
147 ILO_TEXTURE_RENDER_READ
;
149 ilo_blit_resolve_resource(ilo
, res
, flags
);
153 ilo_blit_resolve_slices_for_hiz(struct ilo_context
*ilo
,
154 struct pipe_resource
*res
, unsigned level
,
155 unsigned first_slice
, unsigned num_slices
,
156 unsigned resolve_flags
)
158 struct ilo_texture
*tex
= ilo_texture(res
);
159 const unsigned any_reader
=
160 ILO_TEXTURE_RENDER_READ
|
161 ILO_TEXTURE_BLT_READ
|
162 ILO_TEXTURE_CPU_READ
;
163 const unsigned other_writers
=
164 ILO_TEXTURE_BLT_WRITE
|
165 ILO_TEXTURE_CPU_WRITE
;
168 assert(tex
->base
.target
!= PIPE_BUFFER
&&
169 ilo_image_can_enable_aux(&tex
->image
, level
));
171 if (resolve_flags
& ILO_TEXTURE_RENDER_WRITE
) {
173 * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We
174 * need to perform a HiZ Buffer Resolve in case the resource was
175 * previously written by another writer, unless this is a clear.
177 * When slices have different clear values, we perform a Depth Buffer
178 * Resolve on all slices not sharing the clear value of the first slice.
179 * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can
180 * be made to have the same clear value as the first slice does. This
183 * - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice
184 * - we will not resolve unnecessarily next time this function is
187 * Since slice clear value is the value the slice is cleared to when
188 * ILO_TEXTURE_CLEAR is set, the bit needs to be unset.
190 assert(!(resolve_flags
& (other_writers
| any_reader
)));
192 if (!(resolve_flags
& ILO_TEXTURE_CLEAR
)) {
193 const uint32_t first_clear_value
= ilo_texture_get_slice(tex
,
194 level
, first_slice
)->clear_value
;
195 bool set_clear_value
= false;
197 for (i
= 0; i
< num_slices
; i
++) {
198 const struct ilo_texture_slice
*slice
=
199 ilo_texture_get_slice(tex
, level
, first_slice
+ i
);
201 if (slice
->flags
& other_writers
) {
202 ilo_blitter_rectlist_resolve_hiz(ilo
->blitter
,
203 res
, level
, first_slice
+ i
);
204 } else if (slice
->clear_value
!= first_clear_value
&&
205 (slice
->flags
& ILO_TEXTURE_RENDER_WRITE
)) {
206 ilo_blitter_rectlist_resolve_z(ilo
->blitter
,
207 res
, level
, first_slice
+ i
);
208 set_clear_value
= true;
212 if (set_clear_value
) {
213 /* ILO_TEXTURE_CLEAR will be cleared later */
214 ilo_texture_set_slice_clear_value(tex
, level
,
215 first_slice
, num_slices
, first_clear_value
);
219 else if ((resolve_flags
& any_reader
) ||
220 ((resolve_flags
& other_writers
) &&
221 !(resolve_flags
& ILO_TEXTURE_CLEAR
))) {
223 * When there is at least a reader or writer, we need to perform a
224 * Depth Buffer Resolve in case the resource was previously written
225 * by ILO_TEXTURE_RENDER_WRITE.
227 for (i
= 0; i
< num_slices
; i
++) {
228 const struct ilo_texture_slice
*slice
=
229 ilo_texture_get_slice(tex
, level
, first_slice
+ i
);
231 if (slice
->flags
& ILO_TEXTURE_RENDER_WRITE
) {
232 ilo_blitter_rectlist_resolve_z(ilo
->blitter
,
233 &tex
->base
, level
, first_slice
+ i
);
240 * Initialize blit-related functions.
243 ilo_init_blit_functions(struct ilo_context
*ilo
)
245 ilo
->base
.resource_copy_region
= ilo_resource_copy_region
;
246 ilo
->base
.blit
= ilo_blit
;
247 ilo
->base
.flush_resource
= ilo_flush_resource
;
249 ilo
->base
.clear
= ilo_clear
;
250 ilo
->base
.clear_render_target
= ilo_clear_render_target
;
251 ilo
->base
.clear_depth_stencil
= ilo_clear_depth_stencil
;