1 /**********************************************************
2 * Copyright 2008-2017 VMware, Inc. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 **********************************************************/
26 #include "svga_context.h"
27 #include "svga_debug.h"
29 #include "svga_format.h"
30 #include "svga_resource_buffer.h"
31 #include "svga_resource_texture.h"
32 #include "svga_surface.h"
34 //#include "util/u_blit_sw.h"
35 #include "util/u_format.h"
36 #include "util/u_surface.h"
38 #define FILE_DEBUG_FLAG DEBUG_BLIT
42 * Build a struct pipe_blit_info object from the arguments used by the
43 * pipe::resource_copy_region() function.
46 build_blit_info(struct pipe_resource
*dst_tex
,
51 struct pipe_resource
*src_tex
,
53 const struct pipe_box
*src_box
,
54 struct pipe_blit_info
*blit
)
56 memset(blit
, 0, sizeof(*blit
));
58 blit
->src
.format
= src_tex
->format
;
59 blit
->dst
.format
= dst_tex
->format
;
61 blit
->mask
= util_format_get_mask(blit
->dst
.format
);
62 blit
->filter
= PIPE_TEX_FILTER_NEAREST
;
63 blit
->src
.resource
= src_tex
;
64 blit
->src
.level
= src_level
;
65 blit
->dst
.resource
= dst_tex
;
66 blit
->dst
.level
= dst_level
;
67 blit
->src
.box
= *src_box
;
68 u_box_3d(dst_x
, dst_y
, dst_z
, src_box
->width
, src_box
->height
,
69 src_box
->depth
, &blit
->dst
.box
);
74 * Copy when src texture and dst texture are same with IntraSurfaceCopy
78 intra_surface_copy(struct svga_context
*svga
, struct pipe_resource
*tex
,
79 unsigned src_x
, unsigned src_y
, unsigned src_z
,
80 unsigned level
, unsigned face
,
81 unsigned dst_x
, unsigned dst_y
, unsigned dst_z
,
82 unsigned width
, unsigned height
, unsigned depth
)
86 struct svga_texture
*stex
;
88 stex
= svga_texture(tex
);
100 ret
= SVGA3D_vgpu10_IntraSurfaceCopy(svga
->swc
,
101 stex
->handle
, level
, face
, &box
);
102 if (ret
!= PIPE_OK
) {
103 svga_context_flush(svga
, NULL
);
104 ret
= SVGA3D_vgpu10_IntraSurfaceCopy(svga
->swc
,
105 stex
->handle
, level
, face
, &box
);
106 assert(ret
== PIPE_OK
);
109 /* Mark the texture subresource as rendered-to. */
110 svga_set_texture_rendered_to(stex
, face
, level
);
114 * Copy an image between textures with the vgpu10 CopyRegion command.
117 copy_region_vgpu10(struct svga_context
*svga
, struct pipe_resource
*src_tex
,
118 unsigned src_x
, unsigned src_y
, unsigned src_z
,
119 unsigned src_level
, unsigned src_face
,
120 struct pipe_resource
*dst_tex
,
121 unsigned dst_x
, unsigned dst_y
, unsigned dst_z
,
122 unsigned dst_level
, unsigned dst_face
,
123 unsigned width
, unsigned height
, unsigned depth
)
126 uint32 srcSubResource
, dstSubResource
;
127 struct svga_texture
*dtex
, *stex
;
130 stex
= svga_texture(src_tex
);
131 dtex
= svga_texture(dst_tex
);
133 svga_surfaces_flush(svga
);
145 srcSubResource
= src_face
* (src_tex
->last_level
+ 1) + src_level
;
146 dstSubResource
= dst_face
* (dst_tex
->last_level
+ 1) + dst_level
;
148 ret
= SVGA3D_vgpu10_PredCopyRegion(svga
->swc
,
149 dtex
->handle
, dstSubResource
,
150 stex
->handle
, srcSubResource
, &box
);
151 if (ret
!= PIPE_OK
) {
152 svga_context_flush(svga
, NULL
);
153 ret
= SVGA3D_vgpu10_PredCopyRegion(svga
->swc
,
154 dtex
->handle
, dstSubResource
,
155 stex
->handle
, srcSubResource
, &box
);
156 assert(ret
== PIPE_OK
);
159 /* Mark the texture subresource as defined. */
160 svga_define_texture_level(dtex
, dst_face
, dst_level
);
162 /* Mark the texture subresource as rendered-to. */
163 svga_set_texture_rendered_to(dtex
, dst_face
, dst_level
);
168 * Fallback to the copy region utility which uses map/memcpy for the copy
171 copy_region_fallback(struct svga_context
*svga
,
172 struct pipe_resource
*dst_tex
, unsigned dst_level
,
173 unsigned dstx
, unsigned dsty
, unsigned dstz
,
174 struct pipe_resource
*src_tex
, unsigned src_level
,
175 const struct pipe_box
*src_box
)
177 struct svga_winsys_screen
*sws
= svga_screen(svga
->pipe
.screen
)->sws
;
179 SVGA_STATS_TIME_PUSH(sws
, SVGA_STATS_TIME_COPYREGIONFALLBACK
);
180 util_resource_copy_region(&svga
->pipe
, dst_tex
, dst_level
, dstx
,
181 dsty
, dstz
, src_tex
, src_level
, src_box
);
182 SVGA_STATS_TIME_POP(sws
);
188 has_face_index_in_z(enum pipe_texture_target target
)
190 if (target
== PIPE_TEXTURE_CUBE
||
191 target
== PIPE_TEXTURE_2D_ARRAY
||
192 target
== PIPE_TEXTURE_1D_ARRAY
)
200 * For some texture types, we need to move the z (slice) coordinate
201 * to the layer value. For example, to select the z=3 slice of a 2D ARRAY
202 * texture, we need to use layer=3 and set z=0.
205 adjust_z_layer(enum pipe_texture_target target
,
206 int z_in
, unsigned *layer_out
, unsigned *z_out
)
208 if (target
== PIPE_TEXTURE_CUBE
||
209 target
== PIPE_TEXTURE_2D_ARRAY
||
210 target
== PIPE_TEXTURE_1D_ARRAY
) {
222 * Are the given SVGA3D formats compatible, in terms of vgpu10's
223 * PredCopyRegion() command?
226 formats_compatible(const struct svga_screen
*ss
,
227 SVGA3dSurfaceFormat src_svga_fmt
,
228 SVGA3dSurfaceFormat dst_svga_fmt
)
230 src_svga_fmt
= svga_typeless_format(src_svga_fmt
);
231 dst_svga_fmt
= svga_typeless_format(dst_svga_fmt
);
233 return src_svga_fmt
== dst_svga_fmt
;
238 * Check whether the blending is enabled or not
241 is_blending_enabled(struct svga_context
*svga
,
242 const struct pipe_blit_info
*blit
)
244 bool blend_enable
= false;
246 if (svga
->curr
.blend
) {
247 if (svga
->curr
.blend
->independent_blend_enable
) {
248 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
; i
++) {
249 if (svga
->curr
.framebuffer
.cbufs
[i
]->texture
== blit
->dst
.resource
) {
250 if (svga
->curr
.blend
->rt
[i
].blend_enable
) {
258 if (svga
->curr
.blend
->rt
[0].blend_enable
)
267 * If GL_FRAMEBUFFER_SRGB is enabled, then output colorspace is
268 * expected to be sRGB if blending is not enabled.
269 * If GL_FRAMEBUFFER_SRGB is disabled, then we can use
270 * copy_region_vgpu10()
271 * Following table basically tells when copy_region_vgpu10 can be
272 * used if GL_FRAMEBUFFER_SRGB is enabled.
273 * ______________________________________________________________
274 * | src fmt | dst_fmt | blending |Can use |
275 * | | | |copy_region |
276 * ______________________________________________________________
277 * | linear | linear | N | Y |
278 * | linear | linear | Y | Y |
279 * | linear | sRGB | N | N |
280 * | linear | sRGB | Y | Y |
281 * | sRGB | linear | N | N |
282 * | sRGB | linear | Y | N |
283 * | sRGB | sRGB | N | Y |
284 * | sRGB | sRGB | Y | N |
285 * ______________________________________________________________
289 check_blending_and_srgb_cond(struct svga_context
*svga
,
290 const struct pipe_blit_info
*blit
)
292 enum pipe_format sFmt
= blit
->src
.format
;
293 enum pipe_format dFmt
= blit
->dst
.format
;
295 if (is_blending_enabled(svga
, blit
)) {
296 if (!util_format_is_srgb(blit
->src
.format
))
300 if (util_format_is_srgb(sFmt
) && util_format_is_srgb(dFmt
))
302 else if (!util_format_is_srgb(sFmt
)){
303 if (!util_format_is_srgb(dFmt
))
307 * State tracker converts all sRGB src blit format
308 * to linear if GL_FRAMEBUFFER_SRGB is disabled.
309 * So if src resource format is sRGB and
310 * blit format is linear then it means,
311 * GL_FRAMEBUFFER_SRGB is disabled. In this case also
312 * we can use copy_region_vgpu10().
315 if (util_format_is_srgb(blit
->src
.resource
->format
))
324 * Do common checks for svga surface copy.
327 can_blit_via_svga_copy_region(struct svga_context
*svga
,
328 const struct pipe_blit_info
*blit_info
)
330 struct pipe_blit_info local_blit
= *blit_info
;
332 /* First basic checks to catch incompatibilities in new or locally unchecked
333 * struct pipe_blit_info members but bypass the format check here.
334 * Also since util_can_blit_via_copy_region() requires a dimension match,
335 * PIPE_FILTER_LINEAR should be equal to PIPE_FILTER_NEAREST.
337 local_blit
.dst
.format
= local_blit
.src
.format
;
338 if (local_blit
.filter
== PIPE_TEX_FILTER_LINEAR
)
339 local_blit
.filter
= PIPE_TEX_FILTER_NEAREST
;
340 if (!util_can_blit_via_copy_region(&local_blit
, TRUE
))
343 /* For depth+stencil formats, copy with mask != PIPE_MASK_ZS is not
346 if (util_format_is_depth_and_stencil(blit_info
->src
.format
) &&
347 blit_info
->mask
!= (PIPE_MASK_ZS
))
350 return check_blending_and_srgb_cond(svga
, blit_info
);
355 can_blit_via_intra_surface_copy(struct svga_context
*svga
,
356 const struct pipe_blit_info
*blit_info
)
358 struct svga_texture
*dtex
, *stex
;
359 struct svga_winsys_screen
*sws
= svga_screen(svga
->pipe
.screen
)->sws
;
361 if (!svga_have_vgpu10(svga
))
364 if (!sws
->have_intra_surface_copy
)
367 stex
= svga_texture(blit_info
->src
.resource
);
368 dtex
= svga_texture(blit_info
->dst
.resource
);
370 if (stex
->handle
!= dtex
->handle
)
373 if (blit_info
->src
.level
!= blit_info
->dst
.level
)
376 if (has_face_index_in_z(blit_info
->src
.resource
->target
)){
377 if (blit_info
->src
.box
.z
!= blit_info
->dst
.box
.z
)
381 /* check that the blit src/dst regions are same size, no flipping, etc. */
382 if (blit_info
->src
.box
.width
!= blit_info
->dst
.box
.width
||
383 blit_info
->src
.box
.height
!= blit_info
->dst
.box
.height
)
386 /* For depth+stencil formats, copy with mask != PIPE_MASK_ZS is not
389 if (util_format_is_depth_and_stencil(blit_info
->src
.format
) &&
390 blit_info
->mask
!= (PIPE_MASK_ZS
))
393 if (blit_info
->alpha_blend
||
394 (svga
->render_condition
&& blit_info
->render_condition_enable
) ||
395 blit_info
->scissor_enable
)
398 return !(is_blending_enabled(svga
, blit_info
) &&
399 util_format_is_srgb(blit_info
->src
.resource
->format
));
404 * The state tracker implements some resource copies with blits (for
405 * GL_ARB_copy_image). This function checks if we should really do the blit
406 * with a VGPU10 CopyRegion command or software fallback (for incompatible
410 can_blit_via_copy_region_vgpu10(struct svga_context
*svga
,
411 const struct pipe_blit_info
*blit_info
)
413 struct svga_texture
*dtex
, *stex
;
415 /* can't copy between different resource types */
416 if (svga_resource_type(blit_info
->src
.resource
->target
) !=
417 svga_resource_type(blit_info
->dst
.resource
->target
))
420 stex
= svga_texture(blit_info
->src
.resource
);
421 dtex
= svga_texture(blit_info
->dst
.resource
);
423 if (!svga_have_vgpu10(svga
))
426 if (stex
->handle
== dtex
->handle
)
429 return formats_compatible(svga_screen(svga
->pipe
.screen
),
436 * Check whether we can blit using the surface_copy command.
439 can_blit_via_surface_copy(struct svga_context
*svga
,
440 const struct pipe_blit_info
*blit_info
)
442 struct svga_texture
*dtex
, *stex
;
444 /* Mimic the format tests in util_can_blit_via_copy_region(), but
445 * skip the other tests that have already been performed.
447 if (blit_info
->src
.format
!= blit_info
->dst
.format
) {
448 const struct util_format_description
*src_desc
, *dst_desc
;
450 src_desc
= util_format_description(blit_info
->src
.resource
->format
);
451 dst_desc
= util_format_description(blit_info
->dst
.resource
->format
);
453 if (blit_info
->src
.resource
->format
!= blit_info
->src
.format
||
454 blit_info
->dst
.resource
->format
!= blit_info
->dst
.format
||
455 !util_is_format_compatible(src_desc
, dst_desc
))
459 if (svga
->render_condition
&& blit_info
->render_condition_enable
)
462 /* can't copy between different resource types */
463 if (svga_resource_type(blit_info
->src
.resource
->target
) !=
464 svga_resource_type(blit_info
->dst
.resource
->target
))
467 stex
= svga_texture(blit_info
->src
.resource
);
468 dtex
= svga_texture(blit_info
->dst
.resource
);
470 if (stex
->handle
== dtex
->handle
)
474 * This is what we've been using before, but it can probably be
475 * relaxed. The device checks are less stringent.
477 return (stex
->b
.b
.format
== dtex
->b
.b
.format
);
482 * Try region copy using one of the region copy commands
485 try_copy_region(struct svga_context
*svga
,
486 const struct pipe_blit_info
*blit
)
488 unsigned src_face
, src_z
, dst_face
, dst_z
;
490 if (!can_blit_via_svga_copy_region(svga
, blit
))
493 adjust_z_layer(blit
->src
.resource
->target
, blit
->src
.box
.z
,
496 adjust_z_layer(blit
->dst
.resource
->target
, blit
->dst
.box
.z
,
499 if (can_blit_via_copy_region_vgpu10(svga
, blit
)) {
500 svga_toggle_render_condition(svga
, blit
->render_condition_enable
, FALSE
);
502 copy_region_vgpu10(svga
,
504 blit
->src
.box
.x
, blit
->src
.box
.y
, src_z
,
505 blit
->src
.level
, src_face
,
507 blit
->dst
.box
.x
, blit
->dst
.box
.y
, dst_z
,
508 blit
->dst
.level
, dst_face
,
509 blit
->src
.box
.width
, blit
->src
.box
.height
,
510 blit
->src
.box
.depth
);
512 svga_toggle_render_condition(svga
, blit
->render_condition_enable
, TRUE
);
517 if (can_blit_via_surface_copy(svga
, blit
)) {
518 struct svga_texture
*stex
= svga_texture(blit
->src
.resource
);
519 struct svga_texture
*dtex
= svga_texture(blit
->dst
.resource
);
521 svga_surfaces_flush(svga
);
523 svga_texture_copy_handle(svga
,
525 blit
->src
.box
.x
, blit
->src
.box
.y
, src_z
,
526 blit
->src
.level
, src_face
,
528 blit
->dst
.box
.x
, blit
->dst
.box
.y
, dst_z
,
529 blit
->dst
.level
, dst_face
,
530 blit
->src
.box
.width
, blit
->src
.box
.height
,
531 blit
->src
.box
.depth
);
533 svga_define_texture_level(dtex
, dst_face
, blit
->dst
.level
);
534 svga_set_texture_rendered_to(dtex
, dst_face
, blit
->dst
.level
);
538 if (can_blit_via_intra_surface_copy(svga
, blit
)) {
539 intra_surface_copy(svga
,
541 blit
->src
.box
.x
, blit
->src
.box
.y
, src_z
,
542 blit
->src
.level
, src_face
,
543 blit
->dst
.box
.x
, blit
->dst
.box
.y
, dst_z
,
544 blit
->src
.box
.width
, blit
->src
.box
.height
,
545 blit
->src
.box
.depth
);
554 * A helper function to determine if the specified view format
555 * is compatible with the surface format.
556 * It is compatible if the view format is the same as the surface format,
557 * or the associated svga format for the surface is a typeless format, or
558 * the view format is an adjusted format for BGRX/BGRA resource.
561 is_view_format_compatible(enum pipe_format surf_fmt
,
562 SVGA3dSurfaceFormat surf_svga_fmt
,
563 enum pipe_format view_fmt
)
565 if (surf_fmt
== view_fmt
|| svga_format_is_typeless(surf_svga_fmt
))
568 if ((surf_fmt
== PIPE_FORMAT_B8G8R8X8_UNORM
&&
569 view_fmt
== PIPE_FORMAT_B8G8R8A8_UNORM
) ||
570 (surf_fmt
== PIPE_FORMAT_B8G8R8A8_UNORM
&&
571 view_fmt
== PIPE_FORMAT_B8G8R8X8_UNORM
))
579 * Try issuing a quad blit.
582 try_blit(struct svga_context
*svga
, const struct pipe_blit_info
*blit_info
)
584 struct svga_winsys_screen
*sws
= svga_screen(svga
->pipe
.screen
)->sws
;
585 struct pipe_resource
*src
= blit_info
->src
.resource
;
586 struct pipe_resource
*dst
= blit_info
->dst
.resource
;
587 struct pipe_resource
*newSrc
= NULL
;
588 struct pipe_resource
*newDst
= NULL
;
589 bool can_create_src_view
;
590 bool can_create_dst_view
;
592 struct pipe_blit_info blit
= *blit_info
;
594 SVGA_STATS_TIME_PUSH(sws
, SVGA_STATS_TIME_BLITBLITTER
);
597 * If format is srgb and blend is enabled then color values need
598 * to be converted into linear format.
600 if (is_blending_enabled(svga
, &blit
))
601 blit
.src
.format
= util_format_linear(blit
.src
.format
);
603 /* Check if we can create shader resource view and
604 * render target view for the quad blitter to work
606 can_create_src_view
=
607 is_view_format_compatible(src
->format
, svga_texture(src
)->key
.format
,
610 can_create_dst_view
=
611 is_view_format_compatible(dst
->format
, svga_texture(dst
)->key
.format
,
614 if ((blit
.mask
& PIPE_MASK_S
) ||
615 ((!can_create_dst_view
|| !can_create_src_view
)
616 && !svga_have_vgpu10(svga
))) {
617 /* Can't do stencil blits with textured quad blitter */
618 debug_warn_once("using software stencil blit");
623 if (!util_blitter_is_blit_supported(svga
->blitter
, &blit
)) {
624 debug_printf("svga: blit unsupported %s -> %s\n",
625 util_format_short_name(blit
.src
.resource
->format
),
626 util_format_short_name(blit
.dst
.resource
->format
));
631 /* XXX turn off occlusion and streamout queries */
633 util_blitter_save_vertex_buffer_slot(svga
->blitter
, svga
->curr
.vb
);
634 util_blitter_save_vertex_elements(svga
->blitter
, (void*)svga
->curr
.velems
);
635 util_blitter_save_vertex_shader(svga
->blitter
, svga
->curr
.vs
);
636 util_blitter_save_geometry_shader(svga
->blitter
, svga
->curr
.user_gs
);
637 util_blitter_save_so_targets(svga
->blitter
, svga
->num_so_targets
,
638 (struct pipe_stream_output_target
**)svga
->so_targets
);
639 util_blitter_save_rasterizer(svga
->blitter
, (void*)svga
->curr
.rast
);
640 util_blitter_save_viewport(svga
->blitter
, &svga
->curr
.viewport
);
641 util_blitter_save_scissor(svga
->blitter
, &svga
->curr
.scissor
);
642 util_blitter_save_fragment_shader(svga
->blitter
, svga
->curr
.fs
);
643 util_blitter_save_blend(svga
->blitter
, (void*)svga
->curr
.blend
);
644 util_blitter_save_depth_stencil_alpha(svga
->blitter
,
645 (void*)svga
->curr
.depth
);
646 util_blitter_save_stencil_ref(svga
->blitter
, &svga
->curr
.stencil_ref
);
647 util_blitter_save_sample_mask(svga
->blitter
, svga
->curr
.sample_mask
);
648 util_blitter_save_framebuffer(svga
->blitter
, &svga
->curr
.framebuffer
);
649 util_blitter_save_fragment_sampler_states(svga
->blitter
,
650 svga
->curr
.num_samplers
[PIPE_SHADER_FRAGMENT
],
651 (void**)svga
->curr
.sampler
[PIPE_SHADER_FRAGMENT
]);
652 util_blitter_save_fragment_sampler_views(svga
->blitter
,
653 svga
->curr
.num_sampler_views
[PIPE_SHADER_FRAGMENT
],
654 svga
->curr
.sampler_views
[PIPE_SHADER_FRAGMENT
]);
656 if (!can_create_src_view
) {
657 struct pipe_resource
template;
658 struct pipe_blit_info copy_region_blit
;
661 * If the source blit format is not compatible with the source resource
662 * format, we will not be able to create a shader resource view.
663 * In order to avoid falling back to software blit, we'll create
664 * a new resource in the blit format, and use DXCopyResource to
665 * copy from the original format to the new format. The new
666 * resource will be used for the blit in util_blitter_blit().
669 template.format
= blit
.src
.format
;
670 newSrc
= svga_texture_create(svga
->pipe
.screen
, &template);
671 if (newSrc
== NULL
) {
672 debug_printf("svga_blit: fails to create temporary src\n");
677 /* increment the mksStats for blitter with extra copy */
678 SVGA_STATS_COUNT_INC(sws
, SVGA_STATS_COUNT_BLITBLITTERCOPY
);
679 build_blit_info(newSrc
,
680 blit
.src
.level
, blit
.src
.box
.x
,
681 blit
.src
.box
.y
, blit
.src
.box
.z
,
683 blit
.src
.level
, &blit
.src
.box
,
685 if (!try_copy_region(svga
, ©_region_blit
)) {
686 debug_printf("svga: Source blit format conversion failed.\n");
691 blit
.src
.resource
= newSrc
;
694 if (!can_create_dst_view
) {
695 struct pipe_resource
template;
698 * If the destination blit format is not compatible with the destination
699 * resource format, we will not be able to create a render target view.
700 * In order to avoid falling back to software blit, we'll create
701 * a new resource in the blit format, and use DXPredCopyRegion
702 * after the blit to copy from the blit format back to the resource
706 template.format
= blit
.dst
.format
;
707 newDst
= svga_texture_create(svga
->pipe
.screen
, &template);
708 if (newDst
== NULL
) {
709 debug_printf("svga_blit: fails to create temporary dst\n");
714 blit
.dst
.resource
= newDst
;
717 svga_toggle_render_condition(svga
, blit
.render_condition_enable
, FALSE
);
719 util_blitter_blit(svga
->blitter
, &blit
);
721 svga_toggle_render_condition(svga
, blit
.render_condition_enable
, TRUE
);
723 if (blit
.dst
.resource
!= dst
) {
724 struct pipe_blit_info copy_region_blit
;
726 /* increment the mksStats for blitter with extra copy */
727 SVGA_STATS_COUNT_INC(sws
, SVGA_STATS_COUNT_BLITBLITTERCOPY
);
730 * A temporary resource was created for the blit, we need to
731 * copy from the temporary resource back to the original destination.
734 blit
.dst
.level
, blit
.dst
.box
.x
,
735 blit
.dst
.box
.y
, blit
.dst
.box
.z
,
737 blit
.dst
.level
, &blit
.dst
.box
,
739 if (!try_copy_region(svga
, ©_region_blit
)) {
740 debug_printf("svga: Destination blit format conversion failed.\n");
747 /* unreference the temporary resources if needed */
748 pipe_resource_reference(&newDst
, NULL
);
749 pipe_resource_reference(&newSrc
, NULL
);
751 SVGA_STATS_TIME_POP(sws
); /* SVGA_STATS_TIME_BLITBLITTER */
759 * Try a cpu copy_region fallback.
762 try_cpu_copy_region(struct svga_context
*svga
,
763 const struct pipe_blit_info
*blit
)
765 if (util_can_blit_via_copy_region(blit
, TRUE
) ||
766 util_can_blit_via_copy_region(blit
, FALSE
)) {
768 if (svga
->render_condition
&& blit
->render_condition_enable
) {
769 debug_warning("CPU copy_region doesn't support "
770 "conditional rendering.\n");
774 copy_region_fallback(svga
, blit
->dst
.resource
,
776 blit
->dst
.box
.x
, blit
->dst
.box
.y
,
777 blit
->dst
.box
.z
, blit
->src
.resource
,
778 blit
->src
.level
, &blit
->src
.box
);
787 * The pipe::blit member.
790 svga_blit(struct pipe_context
*pipe
,
791 const struct pipe_blit_info
*blit
)
793 struct svga_context
*svga
= svga_context(pipe
);
794 struct svga_winsys_screen
*sws
= svga_screen(pipe
->screen
)->sws
;
796 if (!svga_have_vgpu10(svga
) &&
797 blit
->src
.resource
->nr_samples
> 1 &&
798 blit
->dst
.resource
->nr_samples
<= 1 &&
799 !util_format_is_depth_or_stencil(blit
->src
.resource
->format
) &&
800 !util_format_is_pure_integer(blit
->src
.resource
->format
)) {
801 debug_printf("svga: color resolve unimplemented\n");
805 SVGA_STATS_TIME_PUSH(sws
, SVGA_STATS_TIME_BLIT
);
807 if (try_copy_region(svga
, blit
))
810 if (try_blit(svga
, blit
))
813 if (!try_cpu_copy_region(svga
, blit
))
814 debug_printf("svga: Blit failed.\n");
817 SVGA_STATS_TIME_POP(sws
); /* SVGA_STATS_TIME_BLIT */
823 * The pipe::resource_copy_region member.
826 svga_resource_copy_region(struct pipe_context
*pipe
,
827 struct pipe_resource
*dst_tex
,
829 unsigned dstx
, unsigned dsty
, unsigned dstz
,
830 struct pipe_resource
*src_tex
,
832 const struct pipe_box
*src_box
)
834 struct svga_context
*svga
= svga_context(pipe
);
835 struct svga_winsys_screen
*sws
= svga_screen(svga
->pipe
.screen
)->sws
;
837 SVGA_STATS_TIME_PUSH(sws
, SVGA_STATS_TIME_COPYREGION
);
839 if (dst_tex
->target
== PIPE_BUFFER
&& src_tex
->target
== PIPE_BUFFER
) {
840 /* can't copy within the same buffer, unfortunately */
841 if (svga_have_vgpu10(svga
) && src_tex
!= dst_tex
) {
843 struct svga_winsys_surface
*src_surf
;
844 struct svga_winsys_surface
*dst_surf
;
845 struct svga_buffer
*dbuffer
= svga_buffer(dst_tex
);
846 struct svga_buffer
*sbuffer
= svga_buffer(src_tex
);
848 src_surf
= svga_buffer_handle(svga
, src_tex
, sbuffer
->bind_flags
);
849 dst_surf
= svga_buffer_handle(svga
, dst_tex
, dbuffer
->bind_flags
);
851 ret
= SVGA3D_vgpu10_BufferCopy(svga
->swc
, src_surf
, dst_surf
,
852 src_box
->x
, dstx
, src_box
->width
);
853 if (ret
!= PIPE_OK
) {
854 svga_context_flush(svga
, NULL
);
855 ret
= SVGA3D_vgpu10_BufferCopy(svga
->swc
, src_surf
, dst_surf
,
856 src_box
->x
, dstx
, src_box
->width
);
857 assert(ret
== PIPE_OK
);
860 dbuffer
->dirty
= TRUE
;
863 /* use map/memcpy fallback */
864 copy_region_fallback(svga
, dst_tex
, dst_level
, dstx
,
865 dsty
, dstz
, src_tex
, src_level
, src_box
);
868 struct pipe_blit_info blit
;
870 build_blit_info(dst_tex
, dst_level
, dstx
, dsty
, dstz
,
871 src_tex
, src_level
, src_box
, &blit
);
873 if (try_copy_region(svga
, &blit
))
876 /* Blits are format-converting which is not what we want, so perform a
877 * strict format-check.
878 * FIXME: Need to figure out why srgb blits (tf2) and
879 * 3D blits (piglit) are broken here. Perhaps we set up the
880 * struct pipe_blit_info incorrectly.
882 if (src_tex
->format
== dst_tex
->format
&&
883 !util_format_is_srgb(src_tex
->format
) &&
884 svga_resource_type(src_tex
->target
) != SVGA3D_RESOURCE_TEXTURE3D
&&
885 try_blit(svga
, &blit
))
888 copy_region_fallback(svga
, dst_tex
, dst_level
, dstx
, dsty
, dstz
,
889 src_tex
, src_level
, src_box
);
893 SVGA_STATS_TIME_POP(sws
);
899 * The pipe::flush_resource member.
902 svga_flush_resource(struct pipe_context
*pipe
,
903 struct pipe_resource
*resource
)
909 * Setup the pipe blit, resource_copy_region and flush_resource members.
912 svga_init_blit_functions(struct svga_context
*svga
)
914 svga
->pipe
.resource_copy_region
= svga_resource_copy_region
;
915 svga
->pipe
.blit
= svga_blit
;
916 svga
->pipe
.flush_resource
= svga_flush_resource
;