summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2017-08-14 09:45:54 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2017-08-14 09:45:54 +0000
commit4c58069f5013f0a621503525f7d5193bfe9976b3 (patch)
treebd8f8a08b889e9a8b99c9de01ae12459d527ea6d /lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c
parent5caa025e6b62d0456faad86c89f239a14d1eaadb (diff)
Import Mesa 17.1.6
Diffstat (limited to 'lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c')
-rw-r--r--lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c161
1 files changed, 154 insertions, 7 deletions
diff --git a/lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c b/lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c
index 28b3c69ea..23f5946b1 100644
--- a/lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/lib/mesa/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -82,7 +82,11 @@ copy_region_vgpu10(struct svga_context *svga, struct pipe_resource *src_tex,
assert(ret == PIPE_OK);
}
+ /* Mark the texture subresource as defined. */
svga_define_texture_level(dtex, dst_face, dst_level);
+
+ /* Mark the texture subresource as rendered-to. */
+ svga_set_texture_rendered_to(dtex, dst_face, dst_level);
}
@@ -165,10 +169,10 @@ svga_resource_copy_region(struct pipe_context *pipe,
/* vgpu10 */
if (util_format_is_compressed(src_tex->format) ==
util_format_is_compressed(dst_tex->format) &&
- !util_format_is_depth_and_stencil(src_tex->format) &&
stex->handle != dtex->handle &&
svga_resource_type(src_tex->target) ==
- svga_resource_type(dst_tex->target)) {
+ svga_resource_type(dst_tex->target) &&
+ stex->b.b.nr_samples == dtex->b.b.nr_samples) {
copy_region_vgpu10(svga,
src_tex,
src_box->x, src_box->y, src_z,
@@ -246,7 +250,7 @@ can_blit_via_copy_region_vgpu10(struct svga_context *svga,
stex = svga_texture(blit_info->src.resource);
dtex = svga_texture(blit_info->dst.resource);
- // can't copy within one resource
+ /* can't copy within one resource */
if (stex->handle == dtex->handle)
return false;
@@ -260,11 +264,19 @@ can_blit_via_copy_region_vgpu10(struct svga_context *svga,
blit_info->src.box.height != blit_info->dst.box.height)
return false;
- /* depth/stencil copies not supported at this time */
- if (blit_info->mask != PIPE_MASK_RGBA)
+ /* check that sample counts are the same */
+ if (stex->b.b.nr_samples != dtex->b.b.nr_samples)
return false;
- if (blit_info->alpha_blend || blit_info->render_condition_enable ||
+ /* For depth+stencil formats, copy with mask != PIPE_MASK_ZS is not
+ * supported
+ */
+ if (util_format_is_depth_and_stencil(blit_info->src.format) &&
+ blit_info->mask != (PIPE_MASK_ZS))
+ return false;
+
+ if (blit_info->alpha_blend ||
+ (svga->render_condition && blit_info->render_condition_enable) ||
blit_info->scissor_enable)
return false;
@@ -274,12 +286,43 @@ can_blit_via_copy_region_vgpu10(struct svga_context *svga,
}
+/**
+ * A helper function to determine if the specified view format
+ * is compatible with the surface format.
+ * It is compatible if the view format is the same as the surface format,
+ * or the associated svga format for the surface is a typeless format, or
+ * the view format is an adjusted format for BGRX/BGRA resource.
+ */
+static bool
+is_view_format_compatible(enum pipe_format surf_fmt,
+ SVGA3dSurfaceFormat surf_svga_fmt,
+ enum pipe_format view_fmt)
+{
+ if (surf_fmt == view_fmt || svga_format_is_typeless(surf_svga_fmt))
+ return true;
+
+ if ((surf_fmt == PIPE_FORMAT_B8G8R8X8_UNORM &&
+ view_fmt == PIPE_FORMAT_B8G8R8A8_UNORM) ||
+ (surf_fmt == PIPE_FORMAT_B8G8R8A8_UNORM &&
+ view_fmt == PIPE_FORMAT_B8G8R8X8_UNORM))
+ return true;
+
+ return false;
+}
+
+
static void
svga_blit(struct pipe_context *pipe,
const struct pipe_blit_info *blit_info)
{
struct svga_context *svga = svga_context(pipe);
struct pipe_blit_info blit = *blit_info;
+ struct pipe_resource *src = blit.src.resource;
+ struct pipe_resource *dst = blit.dst.resource;
+ struct pipe_resource *newSrc = NULL;
+ struct pipe_resource *newDst = NULL;
+ bool can_create_src_view;
+ bool can_create_dst_view;
if (!svga_have_vgpu10(svga) &&
blit.src.resource->nr_samples > 1 &&
@@ -321,8 +364,21 @@ svga_blit(struct pipe_context *pipe,
return; /* done */
}
+ /* Check if we can create shader resource view and
+ * render target view for the quad blitter to work
+ */
+ can_create_src_view =
+ is_view_format_compatible(src->format, svga_texture(src)->key.format,
+ blit.src.format);
+
+ can_create_dst_view =
+ is_view_format_compatible(dst->format, svga_texture(dst)->key.format,
+ blit.dst.format);
+
if ((blit.mask & PIPE_MASK_S) ||
- !util_blitter_is_blit_supported(svga->blitter, blit_info)) {
+ ((!can_create_dst_view || !can_create_src_view)
+ && !svga_have_vgpu10(svga)) ||
+ !util_blitter_is_blit_supported(svga->blitter, &blit)) {
debug_printf("svga: blit unsupported %s -> %s\n",
util_format_short_name(blit.src.resource->format),
util_format_short_name(blit.dst.resource->format));
@@ -355,7 +411,98 @@ svga_blit(struct pipe_context *pipe,
svga->curr.sampler_views[PIPE_SHADER_FRAGMENT]);
/*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query,
svga->render_cond_cond, svga->render_cond_mode);*/
+
+ if (!can_create_src_view) {
+ struct pipe_resource template;
+ unsigned src_face, src_z;
+
+ /**
+ * If the source blit format is not compatible with the source resource
+ * format, we will not be able to create a shader resource view.
+ * In order to avoid falling back to software blit, we'll create
+ * a new resource in the blit format, and use DXCopyResource to
+ * copy from the original format to the new format. The new
+ * resource will be used for the blit in util_blitter_blit().
+ */
+ template = *src;
+ template.format = blit.src.format;
+ newSrc = svga_texture_create(svga->pipe.screen, &template);
+ if (newSrc == NULL) {
+ debug_printf("svga_blit: fails to create temporary src\n");
+ return;
+ }
+
+ /* Copy from original resource to the temporary resource */
+ adjust_z_layer(blit.src.resource->target, blit.src.box.z,
+ &src_face, &src_z);
+
+ copy_region_vgpu10(svga,
+ blit.src.resource,
+ blit.src.box.x, blit.src.box.y, src_z,
+ blit.src.level, src_face,
+ newSrc,
+ blit.src.box.x, blit.src.box.y, src_z,
+ blit.src.level, src_face,
+ blit.src.box.width, blit.src.box.height,
+ blit.src.box.depth);
+
+ blit.src.resource = newSrc;
+ }
+
+ if (!can_create_dst_view) {
+ struct pipe_resource template;
+
+ /**
+ * If the destination blit format is not compatible with the destination
+ * resource format, we will not be able to create a render target view.
+ * In order to avoid falling back to software blit, we'll create
+ * a new resource in the blit format, and use DXPredCopyRegion
+ * after the blit to copy from the blit format back to the resource
+ * format.
+ */
+ template = *dst;
+ template.format = blit.dst.format;
+ newDst = svga_texture_create(svga->pipe.screen, &template);
+ if (newDst == NULL) {
+ debug_printf("svga_blit: fails to create temporary dst\n");
+ return;
+ }
+
+ blit.dst.resource = newDst;
+ }
+
util_blitter_blit(svga->blitter, &blit);
+
+ if (blit.dst.resource != dst) {
+ unsigned dst_face, dst_z;
+
+ adjust_z_layer(blit.dst.resource->target, blit.dst.box.z,
+ &dst_face, &dst_z);
+
+ /**
+ * A temporary resource was created for the blit, we need to
+ * copy from the temporary resource back to the original destination.
+ */
+ copy_region_vgpu10(svga,
+ blit.dst.resource,
+ blit.dst.box.x, blit.dst.box.y, dst_z,
+ blit.dst.level, dst_face,
+ dst,
+ blit.dst.box.x, blit.dst.box.y, dst_z,
+ blit.dst.level, dst_face,
+ blit.dst.box.width, blit.dst.box.height,
+ blit.dst.box.depth);
+
+ /* unreference the temporary resource */
+ pipe_resource_reference(&newDst, NULL);
+ blit.dst.resource = dst;
+ }
+
+ if (blit.src.resource != src) {
+ /* unreference the temporary resource */
+ pipe_resource_reference(&newSrc, NULL);
+ blit.src.resource = src;
+ }
}