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
,
87 bool render_condition_enabled
)
89 struct ilo_context
*ilo
= ilo_context(pipe
);
91 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
94 if (dstx
+ width
> dst
->width
)
95 width
= dst
->width
- dstx
;
96 if (dsty
+ height
> dst
->height
)
97 height
= dst
->height
- dsty
;
99 if (ilo_blitter_blt_clear_rt(ilo
->blitter
,
100 dst
, color
, dstx
, dsty
, width
, height
))
103 ilo_blitter_pipe_clear_rt(ilo
->blitter
,
104 dst
, color
, dstx
, dsty
, width
, height
);
108 ilo_clear_depth_stencil(struct pipe_context
*pipe
,
109 struct pipe_surface
*dst
,
110 unsigned clear_flags
,
113 unsigned dstx
, unsigned dsty
,
114 unsigned width
, unsigned height
,
115 bool render_condition_enabled
)
117 struct ilo_context
*ilo
= ilo_context(pipe
);
119 if (!width
|| !height
|| dstx
>= dst
->width
|| dsty
>= dst
->height
)
122 if (dstx
+ width
> dst
->width
)
123 width
= dst
->width
- dstx
;
124 if (dsty
+ height
> dst
->height
)
125 height
= dst
->height
- dsty
;
127 if (ilo_blitter_blt_clear_zs(ilo
->blitter
,
128 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
))
131 ilo_blitter_pipe_clear_zs(ilo
->blitter
,
132 dst
, clear_flags
, depth
, stencil
, dstx
, dsty
, width
, height
);
136 ilo_blit(struct pipe_context
*pipe
, const struct pipe_blit_info
*info
)
138 struct ilo_context
*ilo
= ilo_context(pipe
);
140 ilo_blitter_pipe_blit(ilo
->blitter
, info
);
144 ilo_flush_resource(struct pipe_context
*pipe
, struct pipe_resource
*res
)
146 struct ilo_context
*ilo
= ilo_context(pipe
);
147 const unsigned flags
= ILO_TEXTURE_CPU_READ
|
148 ILO_TEXTURE_BLT_READ
|
149 ILO_TEXTURE_RENDER_READ
;
151 ilo_blit_resolve_resource(ilo
, res
, flags
);
155 ilo_blit_resolve_slices_for_hiz(struct ilo_context
*ilo
,
156 struct pipe_resource
*res
, unsigned level
,
157 unsigned first_slice
, unsigned num_slices
,
158 unsigned resolve_flags
)
160 struct ilo_texture
*tex
= ilo_texture(res
);
161 const unsigned any_reader
=
162 ILO_TEXTURE_RENDER_READ
|
163 ILO_TEXTURE_BLT_READ
|
164 ILO_TEXTURE_CPU_READ
;
165 const unsigned other_writers
=
166 ILO_TEXTURE_BLT_WRITE
|
167 ILO_TEXTURE_CPU_WRITE
;
170 assert(tex
->base
.target
!= PIPE_BUFFER
&&
171 ilo_image_can_enable_aux(&tex
->image
, level
));
173 if (resolve_flags
& ILO_TEXTURE_RENDER_WRITE
) {
175 * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We
176 * need to perform a HiZ Buffer Resolve in case the resource was
177 * previously written by another writer, unless this is a clear.
179 * When slices have different clear values, we perform a Depth Buffer
180 * Resolve on all slices not sharing the clear value of the first slice.
181 * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can
182 * be made to have the same clear value as the first slice does. This
185 * - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice
186 * - we will not resolve unnecessarily next time this function is
189 * Since slice clear value is the value the slice is cleared to when
190 * ILO_TEXTURE_CLEAR is set, the bit needs to be unset.
192 assert(!(resolve_flags
& (other_writers
| any_reader
)));
194 if (!(resolve_flags
& ILO_TEXTURE_CLEAR
)) {
195 const uint32_t first_clear_value
= ilo_texture_get_slice(tex
,
196 level
, first_slice
)->clear_value
;
197 bool set_clear_value
= false;
199 for (i
= 0; i
< num_slices
; i
++) {
200 const struct ilo_texture_slice
*slice
=
201 ilo_texture_get_slice(tex
, level
, first_slice
+ i
);
203 if (slice
->flags
& other_writers
) {
204 ilo_blitter_rectlist_resolve_hiz(ilo
->blitter
,
205 res
, level
, first_slice
+ i
);
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
;