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"
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 util_framebuffer_get_num_layers(fb
),
336 buffers
, color
, depth
, stencil
);
337 r600_blitter_end(ctx
);
340 static void r600_clear_render_target(struct pipe_context
*ctx
,
341 struct pipe_surface
*dst
,
342 const union pipe_color_union
*color
,
343 unsigned dstx
, unsigned dsty
,
344 unsigned width
, unsigned height
)
346 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
348 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
349 util_blitter_clear_render_target(rctx
->blitter
, dst
, color
,
350 dstx
, dsty
, width
, height
);
351 r600_blitter_end(ctx
);
354 static void r600_clear_depth_stencil(struct pipe_context
*ctx
,
355 struct pipe_surface
*dst
,
356 unsigned clear_flags
,
359 unsigned dstx
, unsigned dsty
,
360 unsigned width
, unsigned height
)
362 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
364 r600_blitter_begin(ctx
, R600_CLEAR_SURFACE
);
365 util_blitter_clear_depth_stencil(rctx
->blitter
, dst
, clear_flags
, depth
, stencil
,
366 dstx
, dsty
, width
, height
);
367 r600_blitter_end(ctx
);
370 /* Helper for decompressing a portion of a color or depth resource before
371 * blitting if any decompression is needed.
372 * The driver doesn't decompress resources automatically while u_blitter is
374 static void r600_decompress_subresource(struct pipe_context
*ctx
,
375 struct pipe_resource
*tex
,
377 unsigned first_layer
, unsigned last_layer
)
379 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
380 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
382 if (rtex
->is_depth
&& !rtex
->is_flushing_texture
) {
383 si_blit_decompress_depth_in_place(rctx
, rtex
,
385 first_layer
, last_layer
);
386 } else if (rtex
->fmask
.size
|| rtex
->cmask
.size
) {
387 r600_blit_decompress_color(ctx
, rtex
, level
, level
,
388 first_layer
, last_layer
);
392 struct texture_orig_info
{
402 static void r600_compressed_to_blittable(struct pipe_resource
*tex
,
404 struct texture_orig_info
*orig
)
406 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
407 unsigned pixsize
= util_format_get_blocksize(rtex
->resource
.b
.b
.format
);
409 int new_height
, new_width
;
411 orig
->format
= tex
->format
;
412 orig
->width0
= tex
->width0
;
413 orig
->height0
= tex
->height0
;
414 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
415 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
416 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
417 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
420 new_format
= PIPE_FORMAT_R16G16B16A16_UINT
; /* 64-bit block */
422 new_format
= PIPE_FORMAT_R32G32B32A32_UINT
; /* 128-bit block */
424 new_width
= util_format_get_nblocksx(tex
->format
, orig
->width0
);
425 new_height
= util_format_get_nblocksy(tex
->format
, orig
->height0
);
427 tex
->width0
= new_width
;
428 tex
->height0
= new_height
;
429 tex
->format
= new_format
;
430 rtex
->surface
.level
[0].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix0_x
);
431 rtex
->surface
.level
[0].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix0_y
);
432 rtex
->surface
.level
[level
].npix_x
= util_format_get_nblocksx(orig
->format
, orig
->npix_x
);
433 rtex
->surface
.level
[level
].npix_y
= util_format_get_nblocksy(orig
->format
, orig
->npix_y
);
435 /* By dividing the dimensions by 4, we effectively decrement
436 * last_level by 2, therefore the last 2 mipmap levels disappear and
437 * aren't blittable. Note that the last 3 mipmap levels (4x4, 2x2,
438 * 1x1) have equal slice sizes, which is an important assumption
441 * In order to make the last 2 mipmap levels blittable, we have to
442 * add the slice size of the last mipmap level to the texture
443 * address, so that even though the hw thinks it reads last_level-2,
444 * it will actually read last_level-1, and if we add the slice size*2,
445 * it will read last_level. That's how this workaround works.
447 if (level
> rtex
->resource
.b
.b
.last_level
-2)
448 rtex
->mipmap_shift
= level
- (rtex
->resource
.b
.b
.last_level
-2);
451 static void r600_change_format(struct pipe_resource
*tex
,
453 struct texture_orig_info
*orig
,
454 enum pipe_format format
)
456 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
458 orig
->format
= tex
->format
;
459 orig
->width0
= tex
->width0
;
460 orig
->height0
= tex
->height0
;
461 orig
->npix0_x
= rtex
->surface
.level
[0].npix_x
;
462 orig
->npix0_y
= rtex
->surface
.level
[0].npix_y
;
463 orig
->npix_x
= rtex
->surface
.level
[level
].npix_x
;
464 orig
->npix_y
= rtex
->surface
.level
[level
].npix_y
;
466 tex
->format
= format
;
469 static void r600_reset_blittable_to_orig(struct pipe_resource
*tex
,
471 struct texture_orig_info
*orig
)
473 struct r600_texture
*rtex
= (struct r600_texture
*)tex
;
475 tex
->format
= orig
->format
;
476 tex
->width0
= orig
->width0
;
477 tex
->height0
= orig
->height0
;
478 rtex
->surface
.level
[0].npix_x
= orig
->npix0_x
;
479 rtex
->surface
.level
[0].npix_y
= orig
->npix0_y
;
480 rtex
->surface
.level
[level
].npix_x
= orig
->npix_x
;
481 rtex
->surface
.level
[level
].npix_y
= orig
->npix_y
;
482 rtex
->mipmap_shift
= 0;
485 static void r600_resource_copy_region(struct pipe_context
*ctx
,
486 struct pipe_resource
*dst
,
488 unsigned dstx
, unsigned dsty
, unsigned dstz
,
489 struct pipe_resource
*src
,
491 const struct pipe_box
*src_box
)
493 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
494 struct texture_orig_info orig_info
[2];
495 struct pipe_box sbox
;
496 const struct pipe_box
*psbox
= src_box
;
497 boolean restore_orig
[2];
499 /* Fallback for buffers. */
500 if (dst
->target
== PIPE_BUFFER
&& src
->target
== PIPE_BUFFER
) {
501 si_copy_buffer(rctx
, dst
, src
, dstx
, src_box
->x
, src_box
->width
);
505 memset(orig_info
, 0, sizeof(orig_info
));
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
)) {
532 unsigned blocksize
= util_format_get_blocksize(src
->format
);
536 r600_change_format(src
, src_level
, &orig_info
[0],
537 PIPE_FORMAT_R8_UNORM
);
538 r600_change_format(dst
, dst_level
, &orig_info
[1],
539 PIPE_FORMAT_R8_UNORM
);
542 r600_change_format(src
, src_level
, &orig_info
[0],
543 PIPE_FORMAT_R8G8_UNORM
);
544 r600_change_format(dst
, dst_level
, &orig_info
[1],
545 PIPE_FORMAT_R8G8_UNORM
);
548 r600_change_format(src
, src_level
, &orig_info
[0],
549 PIPE_FORMAT_R8G8B8A8_UNORM
);
550 r600_change_format(dst
, dst_level
, &orig_info
[1],
551 PIPE_FORMAT_R8G8B8A8_UNORM
);
554 r600_change_format(src
, src_level
, &orig_info
[0],
555 PIPE_FORMAT_R16G16B16A16_UINT
);
556 r600_change_format(dst
, dst_level
, &orig_info
[1],
557 PIPE_FORMAT_R16G16B16A16_UINT
);
560 r600_change_format(src
, src_level
, &orig_info
[0],
561 PIPE_FORMAT_R32G32B32A32_UINT
);
562 r600_change_format(dst
, dst_level
, &orig_info
[1],
563 PIPE_FORMAT_R32G32B32A32_UINT
);
566 fprintf(stderr
, "Unhandled format %s with blocksize %u\n",
567 util_format_short_name(src
->format
), blocksize
);
570 restore_orig
[0] = TRUE
;
571 restore_orig
[1] = TRUE
;
574 r600_blitter_begin(ctx
, R600_COPY
);
575 util_blitter_copy_texture(rctx
->blitter
, dst
, dst_level
, dstx
, dsty
, dstz
,
576 src
, src_level
, psbox
);
577 r600_blitter_end(ctx
);
580 r600_reset_blittable_to_orig(src
, src_level
, &orig_info
[0]);
583 r600_reset_blittable_to_orig(dst
, dst_level
, &orig_info
[1]);
586 /* For MSAA integer resolving to work, we change the format to NORM using this function. */
587 static enum pipe_format
int_to_norm_format(enum pipe_format format
)
590 #define REPLACE_FORMAT_SIGN(format,sign) \
591 case PIPE_FORMAT_##format##_##sign##INT: \
592 return PIPE_FORMAT_##format##_##sign##NORM
593 #define REPLACE_FORMAT(format) \
594 REPLACE_FORMAT_SIGN(format, U); \
595 REPLACE_FORMAT_SIGN(format, S)
597 REPLACE_FORMAT_SIGN(B10G10R10A2
, U
);
599 REPLACE_FORMAT(R8G8
);
600 REPLACE_FORMAT(R8G8B8X8
);
601 REPLACE_FORMAT(R8G8B8A8
);
605 REPLACE_FORMAT(L8A8
);
607 REPLACE_FORMAT(R16G16
);
608 REPLACE_FORMAT(R16G16B16X16
);
609 REPLACE_FORMAT(R16G16B16A16
);
613 REPLACE_FORMAT(L16A16
);
615 #undef REPLACE_FORMAT
616 #undef REPLACE_FORMAT_SIGN
622 static bool do_hardware_msaa_resolve(struct pipe_context
*ctx
,
623 const struct pipe_blit_info
*info
)
625 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
626 struct r600_texture
*dst
= (struct r600_texture
*)info
->dst
.resource
;
627 unsigned dst_width
= u_minify(info
->dst
.resource
->width0
, info
->dst
.level
);
628 unsigned dst_height
= u_minify(info
->dst
.resource
->height0
, info
->dst
.level
);
629 enum pipe_format format
= int_to_norm_format(info
->dst
.format
);
630 unsigned sample_mask
= ~0;
632 if (info
->src
.resource
->nr_samples
> 1 &&
633 info
->dst
.resource
->nr_samples
<= 1 &&
634 util_max_layer(info
->src
.resource
, 0) == 0 &&
635 util_max_layer(info
->dst
.resource
, info
->dst
.level
) == 0 &&
636 info
->dst
.format
== info
->src
.format
&&
637 !util_format_is_pure_integer(format
) &&
638 !util_format_is_depth_or_stencil(format
) &&
639 !info
->scissor_enable
&&
640 (info
->mask
& PIPE_MASK_RGBA
) == PIPE_MASK_RGBA
&&
641 dst_width
== info
->src
.resource
->width0
&&
642 dst_height
== info
->src
.resource
->height0
&&
643 info
->dst
.box
.x
== 0 &&
644 info
->dst
.box
.y
== 0 &&
645 info
->dst
.box
.width
== dst_width
&&
646 info
->dst
.box
.height
== dst_height
&&
647 info
->dst
.box
.depth
== 1 &&
648 info
->src
.box
.x
== 0 &&
649 info
->src
.box
.y
== 0 &&
650 info
->src
.box
.width
== dst_width
&&
651 info
->src
.box
.height
== dst_height
&&
652 info
->src
.box
.depth
== 1 &&
653 dst
->surface
.level
[info
->dst
.level
].mode
>= RADEON_SURF_MODE_1D
&&
654 !(dst
->surface
.flags
& RADEON_SURF_SCANOUT
)) {
655 r600_blitter_begin(ctx
, R600_COLOR_RESOLVE
);
656 util_blitter_custom_resolve_color(rctx
->blitter
,
657 info
->dst
.resource
, info
->dst
.level
,
659 info
->src
.resource
, info
->src
.box
.z
,
660 sample_mask
, rctx
->custom_blend_resolve
,
662 r600_blitter_end(ctx
);
668 static void si_blit(struct pipe_context
*ctx
,
669 const struct pipe_blit_info
*info
)
671 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
673 if (do_hardware_msaa_resolve(ctx
, info
)) {
677 assert(util_blitter_is_blit_supported(rctx
->blitter
, info
));
679 /* The driver doesn't decompress resources automatically while
680 * u_blitter is rendering. */
681 r600_decompress_subresource(ctx
, info
->src
.resource
, info
->src
.level
,
683 info
->src
.box
.z
+ info
->src
.box
.depth
- 1);
685 r600_blitter_begin(ctx
, R600_BLIT
);
686 util_blitter_blit(rctx
->blitter
, info
);
687 r600_blitter_end(ctx
);
690 static void si_flush_resource(struct pipe_context
*ctx
,
691 struct pipe_resource
*resource
)
695 void si_init_blit_functions(struct r600_context
*rctx
)
697 rctx
->b
.b
.clear
= r600_clear
;
698 rctx
->b
.b
.clear_render_target
= r600_clear_render_target
;
699 rctx
->b
.b
.clear_depth_stencil
= r600_clear_depth_stencil
;
700 rctx
->b
.b
.resource_copy_region
= r600_resource_copy_region
;
701 rctx
->b
.b
.blit
= si_blit
;
702 rctx
->b
.b
.flush_resource
= si_flush_resource
;
703 rctx
->b
.blit_decompress_depth
= r600_blit_decompress_depth
;