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
->num_so_targets
,
68 (struct pipe_stream_output_target
**)rctx
->so_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 rctx
->samplers
[PIPE_SHADER_FRAGMENT
].views
.views
);
83 if ((op
& R600_DISABLE_RENDER_COND
) && rctx
->current_render_cond
) {
84 rctx
->saved_render_cond
= rctx
->current_render_cond
;
85 rctx
->saved_render_cond_cond
= rctx
->current_render_cond_cond
;
86 rctx
->saved_render_cond_mode
= rctx
->current_render_cond_mode
;
87 rctx
->context
.render_condition(&rctx
->context
, NULL
, FALSE
, 0);
92 static void r600_blitter_end(struct pipe_context
*ctx
)
94 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
95 if (rctx
->saved_render_cond
) {
96 rctx
->context
.render_condition(&rctx
->context
,
97 rctx
->saved_render_cond
,
98 rctx
->saved_render_cond_cond
,
99 rctx
->saved_render_cond_mode
);
100 rctx
->saved_render_cond
= NULL
;
102 r600_context_queries_resume(rctx
);
105 static unsigned u_max_sample(struct pipe_resource
*r
)
107 return r
->nr_samples
? r
->nr_samples
- 1 : 0;
110 void r600_blit_decompress_depth(struct pipe_context
*ctx
,
111 struct r600_texture
*texture
,
112 struct r600_texture
*staging
,
113 unsigned first_level
, unsigned last_level
,
114 unsigned first_layer
, unsigned last_layer
,
115 unsigned first_sample
, unsigned last_sample
)
117 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
118 unsigned layer
, level
, sample
, checked_last_layer
, max_layer
, max_sample
;
120 const struct util_format_description
*desc
;
122 struct r600_texture
*flushed_depth_texture
= staging
?
123 staging
: texture
->flushed_depth_texture
;
125 if (!staging
&& !texture
->dirty_level_mask
)
128 max_sample
= u_max_sample(&texture
->resource
.b
.b
);
130 desc
= util_format_description(flushed_depth_texture
->resource
.b
.b
.format
);
131 switch (util_format_has_depth(desc
) | util_format_has_stencil(desc
) << 1) {
133 assert(!"No depth or stencil to uncompress");
136 custom_dsa
= rctx
->custom_dsa_flush_depth_stencil
;
139 custom_dsa
= rctx
->custom_dsa_flush_stencil
;
142 custom_dsa
= rctx
->custom_dsa_flush_depth
;
146 for (level
= first_level
; level
<= last_level
; level
++) {
147 if (!staging
&& !(texture
->dirty_level_mask
& (1 << level
)))
150 /* The smaller the mipmap level, the less layers there are
151 * as far as 3D textures are concerned. */
152 max_layer
= util_max_layer(&texture
->resource
.b
.b
, level
);
153 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
155 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
156 for (sample
= first_sample
; sample
<= last_sample
; sample
++) {
157 struct pipe_surface
*zsurf
, *cbsurf
, surf_tmpl
;
159 surf_tmpl
.format
= texture
->resource
.b
.b
.format
;
160 surf_tmpl
.u
.tex
.level
= level
;
161 surf_tmpl
.u
.tex
.first_layer
= layer
;
162 surf_tmpl
.u
.tex
.last_layer
= layer
;
164 zsurf
= ctx
->create_surface(ctx
, &texture
->resource
.b
.b
, &surf_tmpl
);
166 surf_tmpl
.format
= flushed_depth_texture
->resource
.b
.b
.format
;
167 cbsurf
= ctx
->create_surface(ctx
,
168 (struct pipe_resource
*)flushed_depth_texture
, &surf_tmpl
);
170 r600_blitter_begin(ctx
, R600_DECOMPRESS
);
171 util_blitter_custom_depth_stencil(rctx
->blitter
, zsurf
, cbsurf
, 1 << sample
,
172 custom_dsa
[sample
], depth
);
173 r600_blitter_end(ctx
);
175 pipe_surface_reference(&zsurf
, NULL
);
176 pipe_surface_reference(&cbsurf
, NULL
);
180 /* The texture will always be dirty if some layers aren't flushed.
181 * I don't think this case can occur though. */
183 first_layer
== 0 && last_layer
== max_layer
&&
184 first_sample
== 0 && last_sample
== max_sample
) {
185 texture
->dirty_level_mask
&= ~(1 << level
);
190 static void si_blit_decompress_depth_in_place(struct r600_context
*rctx
,
191 struct r600_texture
*texture
,
192 unsigned first_level
, unsigned last_level
,
193 unsigned first_layer
, unsigned last_layer
)
195 struct pipe_surface
*zsurf
, surf_tmpl
= {{0}};
196 unsigned layer
, max_layer
, checked_last_layer
, level
;
198 surf_tmpl
.format
= texture
->resource
.b
.b
.format
;
200 for (level
= first_level
; level
<= last_level
; level
++) {
201 if (!(texture
->dirty_level_mask
& (1 << level
)))
204 surf_tmpl
.u
.tex
.level
= level
;
206 /* The smaller the mipmap level, the less layers there are
207 * as far as 3D textures are concerned. */
208 max_layer
= util_max_layer(&texture
->resource
.b
.b
, level
);
209 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
211 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
212 surf_tmpl
.u
.tex
.first_layer
= layer
;
213 surf_tmpl
.u
.tex
.last_layer
= layer
;
215 zsurf
= rctx
->context
.create_surface(&rctx
->context
, &texture
->resource
.b
.b
, &surf_tmpl
);
217 r600_blitter_begin(&rctx
->context
, R600_DECOMPRESS
);
218 util_blitter_custom_depth_stencil(rctx
->blitter
, zsurf
, NULL
, ~0,
219 rctx
->custom_dsa_flush_inplace
,
221 r600_blitter_end(&rctx
->context
);
223 pipe_surface_reference(&zsurf
, NULL
);
226 /* The texture will always be dirty if some layers aren't flushed.
227 * I don't think this case occurs often though. */
228 if (first_layer
== 0 && last_layer
== max_layer
) {
229 texture
->dirty_level_mask
&= ~(1 << level
);
234 void si_flush_depth_textures(struct r600_context
*rctx
,
235 struct r600_textures_info
*textures
)
239 for (i
= 0; i
< textures
->n_views
; ++i
) {
240 struct pipe_sampler_view
*view
;
241 struct r600_texture
*tex
;
243 view
= textures
->views
.views
[i
];
246 tex
= (struct r600_texture
*)view
->texture
;
247 if (!tex
->is_depth
|| tex
->is_flushing_texture
)
250 si_blit_decompress_depth_in_place(rctx
, tex
,
251 view
->u
.tex
.first_level
, view
->u
.tex
.last_level
,
252 0, util_max_layer(&tex
->resource
.b
.b
, view
->u
.tex
.first_level
));
256 static void r600_blit_decompress_color(struct pipe_context
*ctx
,
257 struct r600_texture
*rtex
,
258 unsigned first_level
, unsigned last_level
,
259 unsigned first_layer
, unsigned last_layer
)
261 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
262 unsigned layer
, level
, checked_last_layer
, max_layer
;
264 if (!rtex
->dirty_level_mask
)
267 for (level
= first_level
; level
<= last_level
; level
++) {
268 if (!(rtex
->dirty_level_mask
& (1 << level
)))
271 /* The smaller the mipmap level, the less layers there are
272 * as far as 3D textures are concerned. */
273 max_layer
= util_max_layer(&rtex
->resource
.b
.b
, level
);
274 checked_last_layer
= last_layer
< max_layer
? last_layer
: max_layer
;
276 for (layer
= first_layer
; layer
<= checked_last_layer
; layer
++) {
277 struct pipe_surface
*cbsurf
, surf_tmpl
;
279 surf_tmpl
.format
= rtex
->resource
.b
.b
.format
;
280 surf_tmpl
.u
.tex
.level
= level
;
281 surf_tmpl
.u
.tex
.first_layer
= layer
;
282 surf_tmpl
.u
.tex
.last_layer
= layer
;
283 cbsurf
= ctx
->create_surface(ctx
, &rtex
->resource
.b
.b
, &surf_tmpl
);
285 r600_blitter_begin(ctx
, R600_DECOMPRESS
);
286 util_blitter_custom_color(rctx
->blitter
, cbsurf
,
287 rctx
->custom_blend_decompress
);
288 r600_blitter_end(ctx
);
290 pipe_surface_reference(&cbsurf
, NULL
);
293 /* The texture will always be dirty if some layers aren't flushed.
294 * I don't think this case occurs often though. */
295 if (first_layer
== 0 && last_layer
== max_layer
) {
296 rtex
->dirty_level_mask
&= ~(1 << level
);
301 void r600_decompress_color_textures(struct r600_context
*rctx
,
302 struct r600_textures_info
*textures
)
305 unsigned mask
= textures
->compressed_colortex_mask
;
308 struct pipe_sampler_view
*view
;
309 struct r600_texture
*tex
;
311 i
= u_bit_scan(&mask
);
313 view
= textures
->views
.views
[i
];
316 tex
= (struct r600_texture
*)view
->texture
;
317 assert(tex
->cmask
.size
|| tex
->fmask
.size
);
319 r600_blit_decompress_color(&rctx
->context
, tex
,
320 view
->u
.tex
.first_level
, view
->u
.tex
.last_level
,
321 0, util_max_layer(&tex
->resource
.b
.b
, view
->u
.tex
.first_level
));
325 static void r600_clear(struct pipe_context
*ctx
, unsigned buffers
,
326 const union pipe_color_union
*color
,
327 double depth
, unsigned stencil
)
329 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
330 struct pipe_framebuffer_state
*fb
= &rctx
->framebuffer
;
332 r600_blitter_begin(ctx
, R600_CLEAR
);
333 util_blitter_clear(rctx
->blitter
, fb
->width
, fb
->height
,
334 buffers
, color
, depth
, stencil
);
335 r600_blitter_end(ctx
);
338 static void r600_clear_render_target(struct pipe_context
*ctx
,
339 struct pipe_surface
*dst
,
340 const union pipe_color_union
*color
,
341 unsigned dstx
, unsigned dsty
,
342 unsigned width
, unsigned height
)
344 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
346 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
347 util_blitter_clear_render_target(rctx
->blitter
, dst
, color
,
348 dstx
, dsty
, width
, height
);
349 r600_blitter_end(ctx
);
352 static void r600_clear_depth_stencil(struct pipe_context
*ctx
,
353 struct pipe_surface
*dst
,
354 unsigned clear_flags
,
357 unsigned dstx
, unsigned dsty
,
358 unsigned width
, unsigned height
)
360 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
362 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
363 util_blitter_clear_depth_stencil(rctx
->blitter
, dst
, clear_flags
, depth
, stencil
,
364 dstx
, dsty
, width
, height
);
365 r600_blitter_end(ctx
);
368 /* Helper for decompressing a portion of a color or depth resource before
369 * blitting if any decompression is needed.
370 * The driver doesn't decompress resources automatically while u_blitter is
372 static void r600_decompress_subresource(struct pipe_context
*ctx
,
373 struct pipe_resource
*tex
,
375 unsigned first_layer
, unsigned last_layer
)
377 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
378 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
380 if (rtex
->is_depth
&& !rtex
->is_flushing_texture
) {
381 si_blit_decompress_depth_in_place(rctx
, rtex
,
383 first_layer
, last_layer
);
384 } else if (rtex
->fmask
.size
|| rtex
->cmask
.size
) {
385 r600_blit_decompress_color(ctx
, rtex
, level
, level
,
386 first_layer
, last_layer
);
390 struct texture_orig_info
{
400 static void r600_compressed_to_blittable(struct pipe_resource
*tex
,
402 struct texture_orig_info
*orig
)
404 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
405 unsigned pixsize
= util_format_get_blocksize(rtex
->resource
.b
.b
.format
);
407 int new_height
, new_width
;
409 orig
->format
= tex
->format
;
410 orig
->width0
= tex
->width0
;
411 orig
->height0
= tex
->height0
;
412 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
413 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
414 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
415 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
418 new_format
= PIPE_FORMAT_R16G16B16A16_UINT
; /* 64-bit block */
420 new_format
= PIPE_FORMAT_R32G32B32A32_UINT
; /* 128-bit block */
422 new_width
= util_format_get_nblocksx(tex
->format
, orig
->width0
);
423 new_height
= util_format_get_nblocksy(tex
->format
, orig
->height0
);
425 tex
->width0
= new_width
;
426 tex
->height0
= new_height
;
427 tex
->format
= new_format
;
428 rtex
->surface
.level
[0].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix0_x
);
429 rtex
->surface
.level
[0].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix0_y
);
430 rtex
->surface
.level
[level
].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix_x
);
431 rtex
->surface
.level
[level
].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix_y
);
434 static void r600_change_format(struct pipe_resource
*tex
,
436 struct texture_orig_info
*orig
,
437 enum pipe_format format
)
439 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
441 orig
->format
= tex
->format
;
442 orig
->width0
= tex
->width0
;
443 orig
->height0
= tex
->height0
;
444 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
445 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
446 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
447 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
449 tex
->format
= format
;
452 static void r600_reset_blittable_to_orig(struct pipe_resource
*tex
,
454 struct texture_orig_info
*orig
)
456 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
458 tex
->format
= orig
->format
;
459 tex
->width0
= orig
->width0
;
460 tex
->height0
= orig
->height0
;
461 rtex
->surface
.level
[0].npix_x
= orig
->npix0_x
;
462 rtex
->surface
.level
[0].npix_y
= orig
->npix0_y
;
463 rtex
->surface
.level
[level
].npix_x
= orig
->npix_x
;
464 rtex
->surface
.level
[level
].npix_y
= orig
->npix_y
;
467 static void r600_resource_copy_region(struct pipe_context
*ctx
,
468 struct pipe_resource
*dst
,
470 unsigned dstx
, unsigned dsty
, unsigned dstz
,
471 struct pipe_resource
*src
,
473 const struct pipe_box
*src_box
)
475 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
476 struct texture_orig_info orig_info
[2];
477 struct pipe_box sbox
;
478 const struct pipe_box
*psbox
= src_box
;
479 boolean restore_orig
[2];
481 memset(orig_info
, 0, sizeof(orig_info
));
483 /* Fallback for buffers. */
484 if (dst
->target
== PIPE_BUFFER
&& src
->target
== PIPE_BUFFER
) {
485 util_resource_copy_region(ctx
, dst
, dst_level
, dstx
, dsty
, dstz
,
486 src
, src_level
, src_box
);
490 /* The driver doesn't decompress resources automatically while
491 * u_blitter is rendering. */
492 r600_decompress_subresource(ctx
, src
, src_level
,
493 src_box
->z
, src_box
->z
+ src_box
->depth
- 1);
495 restore_orig
[0] = restore_orig
[1] = FALSE
;
497 if (util_format_is_compressed(src
->format
) &&
498 util_format_is_compressed(dst
->format
)) {
499 r600_compressed_to_blittable(src
, src_level
, &orig_info
[0]);
500 restore_orig
[0] = TRUE
;
501 sbox
.x
= util_format_get_nblocksx(orig_info
[0].format
, src_box
->x
);
502 sbox
.y
= util_format_get_nblocksy(orig_info
[0].format
, src_box
->y
);
504 sbox
.width
= util_format_get_nblocksx(orig_info
[0].format
, src_box
->width
);
505 sbox
.height
= util_format_get_nblocksy(orig_info
[0].format
, src_box
->height
);
506 sbox
.depth
= src_box
->depth
;
509 r600_compressed_to_blittable(dst
, dst_level
, &orig_info
[1]);
510 restore_orig
[1] = TRUE
;
511 /* translate the dst box as well */
512 dstx
= util_format_get_nblocksx(orig_info
[1].format
, dstx
);
513 dsty
= util_format_get_nblocksy(orig_info
[1].format
, dsty
);
514 } else if (!util_blitter_is_copy_supported(rctx
->blitter
, dst
, src
,
516 unsigned blocksize
= util_format_get_blocksize(src
->format
);
520 r600_change_format(src
, src_level
, &orig_info
[0],
521 PIPE_FORMAT_R8_UNORM
);
522 r600_change_format(dst
, dst_level
, &orig_info
[1],
523 PIPE_FORMAT_R8_UNORM
);
526 r600_change_format(src
, src_level
, &orig_info
[0],
527 PIPE_FORMAT_R8G8_UNORM
);
528 r600_change_format(dst
, dst_level
, &orig_info
[1],
529 PIPE_FORMAT_R8G8_UNORM
);
532 r600_change_format(src
, src_level
, &orig_info
[0],
533 PIPE_FORMAT_R8G8B8A8_UNORM
);
534 r600_change_format(dst
, dst_level
, &orig_info
[1],
535 PIPE_FORMAT_R8G8B8A8_UNORM
);
538 r600_change_format(src
, src_level
, &orig_info
[0],
539 PIPE_FORMAT_R16G16B16A16_UINT
);
540 r600_change_format(dst
, dst_level
, &orig_info
[1],
541 PIPE_FORMAT_R16G16B16A16_UINT
);
544 r600_change_format(src
, src_level
, &orig_info
[0],
545 PIPE_FORMAT_R32G32B32A32_UINT
);
546 r600_change_format(dst
, dst_level
, &orig_info
[1],
547 PIPE_FORMAT_R32G32B32A32_UINT
);
550 fprintf(stderr
, "Unhandled format %s with blocksize %u\n",
551 util_format_short_name(src
->format
), blocksize
);
554 restore_orig
[0] = TRUE
;
555 restore_orig
[1] = TRUE
;
558 r600_blitter_begin(ctx
, R600_COPY
);
559 util_blitter_copy_texture(rctx
->blitter
, dst
, dst_level
, dstx
, dsty
, dstz
,
560 src
, src_level
, psbox
, PIPE_MASK_RGBAZS
, TRUE
);
561 r600_blitter_end(ctx
);
564 r600_reset_blittable_to_orig(src
, src_level
, &orig_info
[0]);
567 r600_reset_blittable_to_orig(dst
, dst_level
, &orig_info
[1]);
570 static boolean
is_simple_msaa_resolve(const struct pipe_blit_info
*info
)
572 unsigned dst_width
= u_minify(info
->dst
.resource
->width0
, info
->dst
.level
);
573 unsigned dst_height
= u_minify(info
->dst
.resource
->height0
, info
->dst
.level
);
574 struct r600_texture
*dst
= (struct r600_texture
*)info
->dst
.resource
;
575 unsigned dst_tile_mode
= dst
->surface
.level
[info
->dst
.level
].mode
;
576 bool dst_is_scanout
= (dst
->surface
.flags
& RADEON_SURF_SCANOUT
) != 0;
578 return info
->dst
.resource
->format
== info
->src
.resource
->format
&&
579 info
->dst
.resource
->format
== info
->dst
.format
&&
580 info
->src
.resource
->format
== info
->src
.format
&&
581 !info
->scissor_enable
&&
582 info
->mask
== PIPE_MASK_RGBA
&&
583 dst_width
== info
->src
.resource
->width0
&&
584 dst_height
== info
->src
.resource
->height0
&&
585 info
->dst
.box
.x
== 0 &&
586 info
->dst
.box
.y
== 0 &&
587 info
->dst
.box
.width
== dst_width
&&
588 info
->dst
.box
.height
== dst_height
&&
589 info
->src
.box
.x
== 0 &&
590 info
->src
.box
.y
== 0 &&
591 info
->src
.box
.width
== dst_width
&&
592 info
->src
.box
.height
== dst_height
&&
593 /* Dst must be tiled. If it's not, we have to use a temporary
594 * resource which is tiled. */
595 dst_tile_mode
>= RADEON_SURF_MODE_1D
&&
599 /* For MSAA integer resolving to work, we change the format to NORM using this function. */
600 static enum pipe_format
int_to_norm_format(enum pipe_format format
)
603 #define REPLACE_FORMAT_SIGN(format,sign) \
604 case PIPE_FORMAT_##format##_##sign##INT: \
605 return PIPE_FORMAT_##format##_##sign##NORM
606 #define REPLACE_FORMAT(format) \
607 REPLACE_FORMAT_SIGN(format, U); \
608 REPLACE_FORMAT_SIGN(format, S)
610 REPLACE_FORMAT_SIGN(B10G10R10A2
, U
);
612 REPLACE_FORMAT(R8G8
);
613 REPLACE_FORMAT(R8G8B8X8
);
614 REPLACE_FORMAT(R8G8B8A8
);
618 REPLACE_FORMAT(L8A8
);
620 REPLACE_FORMAT(R16G16
);
621 REPLACE_FORMAT(R16G16B16X16
);
622 REPLACE_FORMAT(R16G16B16A16
);
626 REPLACE_FORMAT(L16A16
);
628 #undef REPLACE_FORMAT
629 #undef REPLACE_FORMAT_SIGN
635 static void si_msaa_color_resolve(struct pipe_context
*ctx
,
636 const struct pipe_blit_info
*info
)
638 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
639 struct pipe_screen
*screen
= ctx
->screen
;
640 struct pipe_resource
*tmp
, templ
;
641 struct pipe_blit_info blit
;
642 unsigned sample_mask
= ~0;
644 assert(info
->src
.level
== 0);
645 assert(info
->src
.box
.depth
== 1);
646 assert(info
->dst
.box
.depth
== 1);
648 if (is_simple_msaa_resolve(info
)) {
649 r600_blitter_begin(ctx
, R600_COLOR_RESOLVE
);
650 util_blitter_custom_resolve_color(rctx
->blitter
,
651 info
->dst
.resource
, info
->dst
.level
,
653 info
->src
.resource
, info
->src
.box
.z
,
654 sample_mask
, rctx
->custom_blend_resolve
,
655 int_to_norm_format(info
->dst
.format
));
656 r600_blitter_end(ctx
);
660 /* resolve into a temporary texture, then blit */
661 templ
.target
= PIPE_TEXTURE_2D
;
662 templ
.format
= info
->src
.resource
->format
;
663 templ
.width0
= info
->src
.resource
->width0
;
664 templ
.height0
= info
->src
.resource
->height0
;
666 templ
.array_size
= 1;
667 templ
.last_level
= 0;
668 templ
.nr_samples
= 0;
669 templ
.usage
= PIPE_USAGE_STATIC
;
670 templ
.bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
671 templ
.flags
= R600_RESOURCE_FLAG_FORCE_TILING
; /* dst must not have a linear layout */
673 tmp
= screen
->resource_create(screen
, &templ
);
676 r600_blitter_begin(ctx
, R600_COLOR_RESOLVE
);
677 util_blitter_custom_resolve_color(rctx
->blitter
,
679 info
->src
.resource
, info
->src
.box
.z
,
680 sample_mask
, rctx
->custom_blend_resolve
,
681 int_to_norm_format(tmp
->format
));
682 r600_blitter_end(ctx
);
686 blit
.src
.resource
= tmp
;
689 r600_blitter_begin(ctx
, R600_BLIT
);
690 util_blitter_blit(rctx
->blitter
, &blit
);
691 r600_blitter_end(ctx
);
693 pipe_resource_reference(&tmp
, NULL
);
696 static void si_blit(struct pipe_context
*ctx
,
697 const struct pipe_blit_info
*info
)
699 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
701 if (info
->src
.resource
->nr_samples
> 1 &&
702 info
->dst
.resource
->nr_samples
<= 1 &&
703 !util_format_is_depth_or_stencil(info
->src
.resource
->format
) &&
704 !util_format_is_pure_integer(info
->src
.resource
->format
)) {
705 si_msaa_color_resolve(ctx
, info
);
709 assert(util_blitter_is_blit_supported(rctx
->blitter
, info
));
711 /* The driver doesn't decompress resources automatically while
712 * u_blitter is rendering. */
713 r600_decompress_subresource(ctx
, info
->src
.resource
, info
->src
.level
,
715 info
->src
.box
.z
+ info
->src
.box
.depth
- 1);
717 r600_blitter_begin(ctx
, R600_BLIT
);
718 util_blitter_blit(rctx
->blitter
, info
);
719 r600_blitter_end(ctx
);
722 void si_init_blit_functions(struct r600_context
*rctx
)
724 rctx
->context
.clear
= r600_clear
;
725 rctx
->context
.clear_render_target
= r600_clear_render_target
;
726 rctx
->context
.clear_depth_stencil
= r600_clear_depth_stencil
;
727 rctx
->context
.resource_copy_region
= r600_resource_copy_region
;
728 rctx
->context
.blit
= si_blit
;