2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include "util/u_surface.h"
24 #include "util/u_blitter.h"
25 #include "util/u_format.h"
26 #include "radeonsi_pipe.h"
29 enum r600_blitter_op
/* bitmask */
31 R600_SAVE_TEXTURES
= 1,
32 R600_SAVE_FRAMEBUFFER
= 2,
33 R600_DISABLE_RENDER_COND
= 4,
37 R600_CLEAR_SURFACE
= R600_SAVE_FRAMEBUFFER
,
39 R600_COPY
= R600_SAVE_FRAMEBUFFER
| R600_SAVE_TEXTURES
|
40 R600_DISABLE_RENDER_COND
,
42 R600_BLIT
= R600_SAVE_FRAMEBUFFER
| R600_SAVE_TEXTURES
|
43 R600_DISABLE_RENDER_COND
,
45 R600_DECOMPRESS
= R600_SAVE_FRAMEBUFFER
| R600_DISABLE_RENDER_COND
,
47 R600_COLOR_RESOLVE
= R600_SAVE_FRAMEBUFFER
| R600_DISABLE_RENDER_COND
50 static void r600_blitter_begin(struct pipe_context
*ctx
, enum r600_blitter_op op
)
52 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
54 r600_context_queries_suspend(rctx
);
56 util_blitter_save_blend(rctx
->blitter
, rctx
->queued
.named
.blend
);
57 util_blitter_save_depth_stencil_alpha(rctx
->blitter
, rctx
->queued
.named
.dsa
);
58 util_blitter_save_stencil_ref(rctx
->blitter
, &rctx
->stencil_ref
);
59 util_blitter_save_rasterizer(rctx
->blitter
, rctx
->queued
.named
.rasterizer
);
60 util_blitter_save_fragment_shader(rctx
->blitter
, rctx
->ps_shader
);
61 util_blitter_save_vertex_shader(rctx
->blitter
, rctx
->vs_shader
);
62 util_blitter_save_vertex_elements(rctx
->blitter
, rctx
->vertex_elements
);
63 if (rctx
->queued
.named
.viewport
) {
64 util_blitter_save_viewport(rctx
->blitter
, &rctx
->queued
.named
.viewport
->viewport
);
66 util_blitter_save_vertex_buffer_slot(rctx
->blitter
, rctx
->vertex_buffer
);
67 util_blitter_save_so_targets(rctx
->blitter
, rctx
->b
.streamout
.num_targets
,
68 (struct pipe_stream_output_target
**)rctx
->b
.streamout
.targets
);
70 if (op
& R600_SAVE_FRAMEBUFFER
)
71 util_blitter_save_framebuffer(rctx
->blitter
, &rctx
->framebuffer
);
73 if (op
& R600_SAVE_TEXTURES
) {
74 util_blitter_save_fragment_sampler_states(
75 rctx
->blitter
, rctx
->samplers
[PIPE_SHADER_FRAGMENT
].n_samplers
,
76 (void**)rctx
->samplers
[PIPE_SHADER_FRAGMENT
].samplers
);
78 util_blitter_save_fragment_sampler_views(rctx
->blitter
,
79 util_last_bit(rctx
->samplers
[PIPE_SHADER_FRAGMENT
].views
.desc
.enabled_mask
&
80 ((1 << NUM_TEX_UNITS
) - 1)),
81 rctx
->samplers
[PIPE_SHADER_FRAGMENT
].views
.views
);
84 if ((op
& R600_DISABLE_RENDER_COND
) && rctx
->current_render_cond
) {
85 rctx
->saved_render_cond
= rctx
->current_render_cond
;
86 rctx
->saved_render_cond_cond
= rctx
->current_render_cond_cond
;
87 rctx
->saved_render_cond_mode
= rctx
->current_render_cond_mode
;
88 rctx
->b
.b
.render_condition(&rctx
->b
.b
, NULL
, FALSE
, 0);
93 static void r600_blitter_end(struct pipe_context
*ctx
)
95 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
96 if (rctx
->saved_render_cond
) {
97 rctx
->b
.b
.render_condition(&rctx
->b
.b
,
98 rctx
->saved_render_cond
,
99 rctx
->saved_render_cond_cond
,
100 rctx
->saved_render_cond_mode
);
101 rctx
->saved_render_cond
= NULL
;
103 r600_context_queries_resume(rctx
);
106 static unsigned u_max_sample(struct pipe_resource
*r
)
108 return r
->nr_samples
? r
->nr_samples
- 1 : 0;
111 static void r600_blit_decompress_depth(struct pipe_context
*ctx
,
112 struct r600_texture
*texture
,
113 struct r600_texture
*staging
,
114 unsigned first_level
, unsigned last_level
,
115 unsigned first_layer
, unsigned last_layer
,
116 unsigned first_sample
, unsigned last_sample
)
118 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
119 unsigned layer
, level
, sample
, checked_last_layer
, max_layer
, max_sample
;
121 const struct util_format_description
*desc
;
123 struct r600_texture
*flushed_depth_texture
= staging
?
124 staging
: texture
->flushed_depth_texture
;
126 if (!staging
&& !texture
->dirty_level_mask
)
129 max_sample
= u_max_sample(&texture
->resource
.b
.b
);
131 desc
= util_format_description(flushed_depth_texture
->resource
.b
.b
.format
);
132 switch (util_format_has_depth(desc
) | util_format_has_stencil(desc
) << 1) {
134 assert(!"No depth or stencil to uncompress");
137 custom_dsa
= rctx
->custom_dsa_flush_depth_stencil
;
140 custom_dsa
= rctx
->custom_dsa_flush_stencil
;
143 custom_dsa
= rctx
->custom_dsa_flush_depth
;
147 for (level
= first_level
; level
<= last_level
; level
++) {
148 if (!staging
&& !(texture
->dirty_level_mask
& (1 << level
)))
151 /* The smaller the mipmap level, the less layers there are
152 * as far as 3D textures are concerned. */
153 max_layer
= util_max_layer(&texture
->resource
.b
.b
, level
);
154 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
156 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
157 for (sample
= first_sample
; sample
<= last_sample
; sample
++) {
158 struct pipe_surface
*zsurf
, *cbsurf
, surf_tmpl
;
160 surf_tmpl
.format
= texture
->resource
.b
.b
.format
;
161 surf_tmpl
.u
.tex
.level
= level
;
162 surf_tmpl
.u
.tex
.first_layer
= layer
;
163 surf_tmpl
.u
.tex
.last_layer
= layer
;
165 zsurf
= ctx
->create_surface(ctx
, &texture
->resource
.b
.b
, &surf_tmpl
);
167 surf_tmpl
.format
= flushed_depth_texture
->resource
.b
.b
.format
;
168 cbsurf
= ctx
->create_surface(ctx
,
169 (struct pipe_resource
*)flushed_depth_texture
, &surf_tmpl
);
171 r600_blitter_begin(ctx
, R600_DECOMPRESS
);
172 util_blitter_custom_depth_stencil(rctx
->blitter
, zsurf
, cbsurf
, 1 << sample
,
173 custom_dsa
[sample
], depth
);
174 r600_blitter_end(ctx
);
176 pipe_surface_reference(&zsurf
, NULL
);
177 pipe_surface_reference(&cbsurf
, NULL
);
181 /* The texture will always be dirty if some layers aren't flushed.
182 * I don't think this case can occur though. */
184 first_layer
== 0 && last_layer
== max_layer
&&
185 first_sample
== 0 && last_sample
== max_sample
) {
186 texture
->dirty_level_mask
&= ~(1 << level
);
191 static void si_blit_decompress_depth_in_place(struct r600_context
*rctx
,
192 struct r600_texture
*texture
,
193 unsigned first_level
, unsigned last_level
,
194 unsigned first_layer
, unsigned last_layer
)
196 struct pipe_surface
*zsurf
, surf_tmpl
= {{0}};
197 unsigned layer
, max_layer
, checked_last_layer
, level
;
199 surf_tmpl
.format
= texture
->resource
.b
.b
.format
;
201 for (level
= first_level
; level
<= last_level
; level
++) {
202 if (!(texture
->dirty_level_mask
& (1 << level
)))
205 surf_tmpl
.u
.tex
.level
= level
;
207 /* The smaller the mipmap level, the less layers there are
208 * as far as 3D textures are concerned. */
209 max_layer
= util_max_layer(&texture
->resource
.b
.b
, level
);
210 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
212 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
213 surf_tmpl
.u
.tex
.first_layer
= layer
;
214 surf_tmpl
.u
.tex
.last_layer
= layer
;
216 zsurf
= rctx
->b
.b
.create_surface(&rctx
->b
.b
, &texture
->resource
.b
.b
, &surf_tmpl
);
218 r600_blitter_begin(&rctx
->b
.b
, R600_DECOMPRESS
);
219 util_blitter_custom_depth_stencil(rctx
->blitter
, zsurf
, NULL
, ~0,
220 rctx
->custom_dsa_flush_inplace
,
222 r600_blitter_end(&rctx
->b
.b
);
224 pipe_surface_reference(&zsurf
, NULL
);
227 /* The texture will always be dirty if some layers aren't flushed.
228 * I don't think this case occurs often though. */
229 if (first_layer
== 0 && last_layer
== max_layer
) {
230 texture
->dirty_level_mask
&= ~(1 << level
);
235 void si_flush_depth_textures(struct r600_context
*rctx
,
236 struct r600_textures_info
*textures
)
240 for (i
= 0; i
< textures
->n_views
; ++i
) {
241 struct pipe_sampler_view
*view
;
242 struct r600_texture
*tex
;
244 view
= textures
->views
.views
[i
];
247 tex
= (struct r600_texture
*)view
->texture
;
248 if (!tex
->is_depth
|| tex
->is_flushing_texture
)
251 si_blit_decompress_depth_in_place(rctx
, tex
,
252 view
->u
.tex
.first_level
, view
->u
.tex
.last_level
,
253 0, util_max_layer(&tex
->resource
.b
.b
, view
->u
.tex
.first_level
));
257 static void r600_blit_decompress_color(struct pipe_context
*ctx
,
258 struct r600_texture
*rtex
,
259 unsigned first_level
, unsigned last_level
,
260 unsigned first_layer
, unsigned last_layer
)
262 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
263 unsigned layer
, level
, checked_last_layer
, max_layer
;
265 if (!rtex
->dirty_level_mask
)
268 for (level
= first_level
; level
<= last_level
; level
++) {
269 if (!(rtex
->dirty_level_mask
& (1 << level
)))
272 /* The smaller the mipmap level, the less layers there are
273 * as far as 3D textures are concerned. */
274 max_layer
= util_max_layer(&rtex
->resource
.b
.b
, level
);
275 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
277 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
278 struct pipe_surface
*cbsurf
, surf_tmpl
;
280 surf_tmpl
.format
= rtex
->resource
.b
.b
.format
;
281 surf_tmpl
.u
.tex
.level
= level
;
282 surf_tmpl
.u
.tex
.first_layer
= layer
;
283 surf_tmpl
.u
.tex
.last_layer
= layer
;
284 cbsurf
= ctx
->create_surface(ctx
, &rtex
->resource
.b
.b
, &surf_tmpl
);
286 r600_blitter_begin(ctx
, R600_DECOMPRESS
);
287 util_blitter_custom_color(rctx
->blitter
, cbsurf
,
288 rctx
->custom_blend_decompress
);
289 r600_blitter_end(ctx
);
291 pipe_surface_reference(&cbsurf
, NULL
);
294 /* The texture will always be dirty if some layers aren't flushed.
295 * I don't think this case occurs often though. */
296 if (first_layer
== 0 && last_layer
== max_layer
) {
297 rtex
->dirty_level_mask
&= ~(1 << level
);
302 void r600_decompress_color_textures(struct r600_context
*rctx
,
303 struct r600_textures_info
*textures
)
306 unsigned mask
= textures
->compressed_colortex_mask
;
309 struct pipe_sampler_view
*view
;
310 struct r600_texture
*tex
;
312 i
= u_bit_scan(&mask
);
314 view
= textures
->views
.views
[i
];
317 tex
= (struct r600_texture
*)view
->texture
;
318 assert(tex
->cmask
.size
|| tex
->fmask
.size
);
320 r600_blit_decompress_color(&rctx
->b
.b
, tex
,
321 view
->u
.tex
.first_level
, view
->u
.tex
.last_level
,
322 0, util_max_layer(&tex
->resource
.b
.b
, view
->u
.tex
.first_level
));
326 static void r600_clear(struct pipe_context
*ctx
, unsigned buffers
,
327 const union pipe_color_union
*color
,
328 double depth
, unsigned stencil
)
330 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
331 struct pipe_framebuffer_state
*fb
= &rctx
->framebuffer
;
333 r600_blitter_begin(ctx
, R600_CLEAR
);
334 util_blitter_clear(rctx
->blitter
, fb
->width
, fb
->height
,
335 buffers
, color
, depth
, stencil
);
336 r600_blitter_end(ctx
);
339 static void r600_clear_render_target(struct pipe_context
*ctx
,
340 struct pipe_surface
*dst
,
341 const union pipe_color_union
*color
,
342 unsigned dstx
, unsigned dsty
,
343 unsigned width
, unsigned height
)
345 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
347 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
348 util_blitter_clear_render_target(rctx
->blitter
, dst
, color
,
349 dstx
, dsty
, width
, height
);
350 r600_blitter_end(ctx
);
353 static void r600_clear_depth_stencil(struct pipe_context
*ctx
,
354 struct pipe_surface
*dst
,
355 unsigned clear_flags
,
358 unsigned dstx
, unsigned dsty
,
359 unsigned width
, unsigned height
)
361 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
363 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
364 util_blitter_clear_depth_stencil(rctx
->blitter
, dst
, clear_flags
, depth
, stencil
,
365 dstx
, dsty
, width
, height
);
366 r600_blitter_end(ctx
);
369 /* Helper for decompressing a portion of a color or depth resource before
370 * blitting if any decompression is needed.
371 * The driver doesn't decompress resources automatically while u_blitter is
373 static void r600_decompress_subresource(struct pipe_context
*ctx
,
374 struct pipe_resource
*tex
,
376 unsigned first_layer
, unsigned last_layer
)
378 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
379 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
381 if (rtex
->is_depth
&& !rtex
->is_flushing_texture
) {
382 si_blit_decompress_depth_in_place(rctx
, rtex
,
384 first_layer
, last_layer
);
385 } else if (rtex
->fmask
.size
|| rtex
->cmask
.size
) {
386 r600_blit_decompress_color(ctx
, rtex
, level
, level
,
387 first_layer
, last_layer
);
391 struct texture_orig_info
{
401 static void r600_compressed_to_blittable(struct pipe_resource
*tex
,
403 struct texture_orig_info
*orig
)
405 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
406 unsigned pixsize
= util_format_get_blocksize(rtex
->resource
.b
.b
.format
);
408 int new_height
, new_width
;
410 orig
->format
= tex
->format
;
411 orig
->width0
= tex
->width0
;
412 orig
->height0
= tex
->height0
;
413 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
414 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
415 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
416 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
419 new_format
= PIPE_FORMAT_R16G16B16A16_UINT
; /* 64-bit block */
421 new_format
= PIPE_FORMAT_R32G32B32A32_UINT
; /* 128-bit block */
423 new_width
= util_format_get_nblocksx(tex
->format
, orig
->width0
);
424 new_height
= util_format_get_nblocksy(tex
->format
, orig
->height0
);
426 tex
->width0
= new_width
;
427 tex
->height0
= new_height
;
428 tex
->format
= new_format
;
429 rtex
->surface
.level
[0].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix0_x
);
430 rtex
->surface
.level
[0].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix0_y
);
431 rtex
->surface
.level
[level
].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix_x
);
432 rtex
->surface
.level
[level
].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix_y
);
434 /* By dividing the dimensions by 4, we effectively decrement
435 * last_level by 2, therefore the last 2 mipmap levels disappear and
436 * aren't blittable. Note that the last 3 mipmap levels (4x4, 2x2,
437 * 1x1) have equal slice sizes, which is an important assumption
440 * In order to make the last 2 mipmap levels blittable, we have to
441 * add the slice size of the last mipmap level to the texture
442 * address, so that even though the hw thinks it reads last_level-2,
443 * it will actually read last_level-1, and if we add the slice size*2,
444 * it will read last_level. That's how this workaround works.
446 if (level
> rtex
->resource
.b
.b
.last_level
-2)
447 rtex
->mipmap_shift
= level
- (rtex
->resource
.b
.b
.last_level
-2);
450 static void r600_change_format(struct pipe_resource
*tex
,
452 struct texture_orig_info
*orig
,
453 enum pipe_format format
)
455 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
457 orig
->format
= tex
->format
;
458 orig
->width0
= tex
->width0
;
459 orig
->height0
= tex
->height0
;
460 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
461 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
462 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
463 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
465 tex
->format
= format
;
468 static void r600_reset_blittable_to_orig(struct pipe_resource
*tex
,
470 struct texture_orig_info
*orig
)
472 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
474 tex
->format
= orig
->format
;
475 tex
->width0
= orig
->width0
;
476 tex
->height0
= orig
->height0
;
477 rtex
->surface
.level
[0].npix_x
= orig
->npix0_x
;
478 rtex
->surface
.level
[0].npix_y
= orig
->npix0_y
;
479 rtex
->surface
.level
[level
].npix_x
= orig
->npix_x
;
480 rtex
->surface
.level
[level
].npix_y
= orig
->npix_y
;
481 rtex
->mipmap_shift
= 0;
484 static void r600_resource_copy_region(struct pipe_context
*ctx
,
485 struct pipe_resource
*dst
,
487 unsigned dstx
, unsigned dsty
, unsigned dstz
,
488 struct pipe_resource
*src
,
490 const struct pipe_box
*src_box
)
492 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
493 struct texture_orig_info orig_info
[2];
494 struct pipe_box sbox
;
495 const struct pipe_box
*psbox
= src_box
;
496 boolean restore_orig
[2];
498 memset(orig_info
, 0, sizeof(orig_info
));
500 /* Fallback for buffers. */
501 if (dst
->target
== PIPE_BUFFER
&& src
->target
== PIPE_BUFFER
) {
502 util_resource_copy_region(ctx
, dst
, dst_level
, dstx
, dsty
, dstz
,
503 src
, src_level
, src_box
);
507 /* The driver doesn't decompress resources automatically while
508 * u_blitter is rendering. */
509 r600_decompress_subresource(ctx
, src
, src_level
,
510 src_box
->z
, src_box
->z
+ src_box
->depth
- 1);
512 restore_orig
[0] = restore_orig
[1] = FALSE
;
514 if (util_format_is_compressed(src
->format
) &&
515 util_format_is_compressed(dst
->format
)) {
516 r600_compressed_to_blittable(src
, src_level
, &orig_info
[0]);
517 restore_orig
[0] = TRUE
;
518 sbox
.x
= util_format_get_nblocksx(orig_info
[0].format
, src_box
->x
);
519 sbox
.y
= util_format_get_nblocksy(orig_info
[0].format
, src_box
->y
);
521 sbox
.width
= util_format_get_nblocksx(orig_info
[0].format
, src_box
->width
);
522 sbox
.height
= util_format_get_nblocksy(orig_info
[0].format
, src_box
->height
);
523 sbox
.depth
= src_box
->depth
;
526 r600_compressed_to_blittable(dst
, dst_level
, &orig_info
[1]);
527 restore_orig
[1] = TRUE
;
528 /* translate the dst box as well */
529 dstx
= util_format_get_nblocksx(orig_info
[1].format
, dstx
);
530 dsty
= util_format_get_nblocksy(orig_info
[1].format
, dsty
);
531 } else if (!util_blitter_is_copy_supported(rctx
->blitter
, dst
, src
,
533 unsigned blocksize
= util_format_get_blocksize(src
->format
);
537 r600_change_format(src
, src_level
, &orig_info
[0],
538 PIPE_FORMAT_R8_UNORM
);
539 r600_change_format(dst
, dst_level
, &orig_info
[1],
540 PIPE_FORMAT_R8_UNORM
);
543 r600_change_format(src
, src_level
, &orig_info
[0],
544 PIPE_FORMAT_R8G8_UNORM
);
545 r600_change_format(dst
, dst_level
, &orig_info
[1],
546 PIPE_FORMAT_R8G8_UNORM
);
549 r600_change_format(src
, src_level
, &orig_info
[0],
550 PIPE_FORMAT_R8G8B8A8_UNORM
);
551 r600_change_format(dst
, dst_level
, &orig_info
[1],
552 PIPE_FORMAT_R8G8B8A8_UNORM
);
555 r600_change_format(src
, src_level
, &orig_info
[0],
556 PIPE_FORMAT_R16G16B16A16_UINT
);
557 r600_change_format(dst
, dst_level
, &orig_info
[1],
558 PIPE_FORMAT_R16G16B16A16_UINT
);
561 r600_change_format(src
, src_level
, &orig_info
[0],
562 PIPE_FORMAT_R32G32B32A32_UINT
);
563 r600_change_format(dst
, dst_level
, &orig_info
[1],
564 PIPE_FORMAT_R32G32B32A32_UINT
);
567 fprintf(stderr
, "Unhandled format %s with blocksize %u\n",
568 util_format_short_name(src
->format
), blocksize
);
571 restore_orig
[0] = TRUE
;
572 restore_orig
[1] = TRUE
;
575 r600_blitter_begin(ctx
, R600_COPY
);
576 util_blitter_copy_texture(rctx
->blitter
, dst
, dst_level
, dstx
, dsty
, dstz
,
577 src
, src_level
, psbox
, PIPE_MASK_RGBAZS
, TRUE
);
578 r600_blitter_end(ctx
);
581 r600_reset_blittable_to_orig(src
, src_level
, &orig_info
[0]);
584 r600_reset_blittable_to_orig(dst
, dst_level
, &orig_info
[1]);
587 static boolean
is_simple_msaa_resolve(const struct pipe_blit_info
*info
)
589 unsigned dst_width
= u_minify(info
->dst
.resource
->width0
, info
->dst
.level
);
590 unsigned dst_height
= u_minify(info
->dst
.resource
->height0
, info
->dst
.level
);
591 struct r600_texture
*dst
= (struct r600_texture
*)info
->dst
.resource
;
592 unsigned dst_tile_mode
= dst
->surface
.level
[info
->dst
.level
].mode
;
593 bool dst_is_scanout
= (dst
->surface
.flags
& RADEON_SURF_SCANOUT
) != 0;
595 return info
->dst
.resource
->format
== info
->src
.resource
->format
&&
596 info
->dst
.resource
->format
== info
->dst
.format
&&
597 info
->src
.resource
->format
== info
->src
.format
&&
598 !info
->scissor_enable
&&
599 info
->mask
== PIPE_MASK_RGBA
&&
600 dst_width
== info
->src
.resource
->width0
&&
601 dst_height
== info
->src
.resource
->height0
&&
602 info
->dst
.box
.x
== 0 &&
603 info
->dst
.box
.y
== 0 &&
604 info
->dst
.box
.width
== dst_width
&&
605 info
->dst
.box
.height
== dst_height
&&
606 info
->src
.box
.x
== 0 &&
607 info
->src
.box
.y
== 0 &&
608 info
->src
.box
.width
== dst_width
&&
609 info
->src
.box
.height
== dst_height
&&
610 /* Dst must be tiled. If it's not, we have to use a temporary
611 * resource which is tiled. */
612 dst_tile_mode
>= RADEON_SURF_MODE_1D
&&
616 /* For MSAA integer resolving to work, we change the format to NORM using this function. */
617 static enum pipe_format
int_to_norm_format(enum pipe_format format
)
620 #define REPLACE_FORMAT_SIGN(format,sign) \
621 case PIPE_FORMAT_##format##_##sign##INT: \
622 return PIPE_FORMAT_##format##_##sign##NORM
623 #define REPLACE_FORMAT(format) \
624 REPLACE_FORMAT_SIGN(format, U); \
625 REPLACE_FORMAT_SIGN(format, S)
627 REPLACE_FORMAT_SIGN(B10G10R10A2
, U
);
629 REPLACE_FORMAT(R8G8
);
630 REPLACE_FORMAT(R8G8B8X8
);
631 REPLACE_FORMAT(R8G8B8A8
);
635 REPLACE_FORMAT(L8A8
);
637 REPLACE_FORMAT(R16G16
);
638 REPLACE_FORMAT(R16G16B16X16
);
639 REPLACE_FORMAT(R16G16B16A16
);
643 REPLACE_FORMAT(L16A16
);
645 #undef REPLACE_FORMAT
646 #undef REPLACE_FORMAT_SIGN
652 static void si_msaa_color_resolve(struct pipe_context
*ctx
,
653 const struct pipe_blit_info
*info
)
655 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
656 struct pipe_screen
*screen
= ctx
->screen
;
657 struct pipe_resource
*tmp
, templ
;
658 struct pipe_blit_info blit
;
659 unsigned sample_mask
= ~0;
661 assert(info
->src
.level
== 0);
662 assert(info
->src
.box
.depth
== 1);
663 assert(info
->dst
.box
.depth
== 1);
665 if (is_simple_msaa_resolve(info
)) {
666 r600_blitter_begin(ctx
, R600_COLOR_RESOLVE
);
667 util_blitter_custom_resolve_color(rctx
->blitter
,
668 info
->dst
.resource
, info
->dst
.level
,
670 info
->src
.resource
, info
->src
.box
.z
,
671 sample_mask
, rctx
->custom_blend_resolve
,
672 int_to_norm_format(info
->dst
.format
));
673 r600_blitter_end(ctx
);
677 /* resolve into a temporary texture, then blit */
678 templ
.target
= PIPE_TEXTURE_2D
;
679 templ
.format
= info
->src
.resource
->format
;
680 templ
.width0
= info
->src
.resource
->width0
;
681 templ
.height0
= info
->src
.resource
->height0
;
683 templ
.array_size
= 1;
684 templ
.last_level
= 0;
685 templ
.nr_samples
= 0;
686 templ
.usage
= PIPE_USAGE_STATIC
;
687 templ
.bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
688 templ
.flags
= R600_RESOURCE_FLAG_FORCE_TILING
; /* dst must not have a linear layout */
690 tmp
= screen
->resource_create(screen
, &templ
);
693 r600_blitter_begin(ctx
, R600_COLOR_RESOLVE
);
694 util_blitter_custom_resolve_color(rctx
->blitter
,
696 info
->src
.resource
, info
->src
.box
.z
,
697 sample_mask
, rctx
->custom_blend_resolve
,
698 int_to_norm_format(tmp
->format
));
699 r600_blitter_end(ctx
);
703 blit
.src
.resource
= tmp
;
706 r600_blitter_begin(ctx
, R600_BLIT
);
707 util_blitter_blit(rctx
->blitter
, &blit
);
708 r600_blitter_end(ctx
);
710 pipe_resource_reference(&tmp
, NULL
);
713 static void si_blit(struct pipe_context
*ctx
,
714 const struct pipe_blit_info
*info
)
716 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
718 if (info
->src
.resource
->nr_samples
> 1 &&
719 info
->dst
.resource
->nr_samples
<= 1 &&
720 !util_format_is_depth_or_stencil(info
->src
.resource
->format
) &&
721 !util_format_is_pure_integer(info
->src
.resource
->format
)) {
722 si_msaa_color_resolve(ctx
, info
);
726 assert(util_blitter_is_blit_supported(rctx
->blitter
, info
));
728 /* The driver doesn't decompress resources automatically while
729 * u_blitter is rendering. */
730 r600_decompress_subresource(ctx
, info
->src
.resource
, info
->src
.level
,
732 info
->src
.box
.z
+ info
->src
.box
.depth
- 1);
734 r600_blitter_begin(ctx
, R600_BLIT
);
735 util_blitter_blit(rctx
->blitter
, info
);
736 r600_blitter_end(ctx
);
739 static void si_flush_resource(struct pipe_context
*ctx
,
740 struct pipe_resource
*resource
)
744 void si_init_blit_functions(struct r600_context
*rctx
)
746 rctx
->b
.b
.clear
= r600_clear
;
747 rctx
->b
.b
.clear_render_target
= r600_clear_render_target
;
748 rctx
->b
.b
.clear_depth_stencil
= r600_clear_depth_stencil
;
749 rctx
->b
.b
.resource_copy_region
= r600_resource_copy_region
;
750 rctx
->b
.b
.blit
= si_blit
;
751 rctx
->b
.b
.flush_resource
= si_flush_resource
;
752 rctx
->b
.blit_decompress_depth
= r600_blit_decompress_depth
;