Beispiel #1
0
static void
i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
{
   struct i915_context *i915 = i915_context(pipe);
   struct pipe_blit_info info = *blit_info;

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("i915: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(i915->blitter, &info)) {
      debug_printf("i915: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   i915_util_blitter_save_states(i915);

   util_blitter_blit(i915->blitter, &info);
}
Beispiel #2
0
static bool
vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info)
{
        struct vc4_context *vc4 = vc4_context(ctx);

        if (!util_blitter_is_blit_supported(vc4->blitter, info)) {
                fprintf(stderr, "blit unsupported %s -> %s\n",
                    util_format_short_name(info->src.resource->format),
                    util_format_short_name(info->dst.resource->format));
                return false;
        }

        /* Enable the scissor, so we get a minimal set of tiles rendered. */
        if (!info->scissor_enable) {
                info->scissor_enable = true;
                info->scissor.minx = info->dst.box.x;
                info->scissor.miny = info->dst.box.y;
                info->scissor.maxx = info->dst.box.x + info->dst.box.width;
                info->scissor.maxy = info->dst.box.y + info->dst.box.height;
        }

        vc4_blitter_save(vc4);
        util_blitter_blit(vc4->blitter, info);

        return true;
}
Beispiel #3
0
static void si_blit(struct pipe_context *ctx,
                      const struct pipe_blit_info *info)
{
	struct r600_context *rctx = (struct r600_context*)ctx;
	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)info->src.resource;

	assert(util_blitter_is_blit_supported(rctx->blitter, info));

	if (info->src.resource->nr_samples > 1 &&
	    info->dst.resource->nr_samples <= 1 &&
	    !util_format_is_depth_or_stencil(info->src.resource->format) &&
	    !util_format_is_pure_integer(info->src.resource->format)) {
		debug_printf("radeonsi: color resolve is unimplemented\n");
		return;
	}

	if (rsrc->is_depth && !rsrc->is_flushing_texture) {
		si_blit_decompress_depth_in_place(rctx, rsrc,
						  info->src.level, info->src.level,
						  info->src.box.z,
						  info->src.box.z + info->src.box.depth - 1);
	}

	r600_blitter_begin(ctx, R600_BLIT);
	util_blitter_blit(rctx->blitter, info);
	r600_blitter_end(ctx);
}
Beispiel #4
0
static void r600_blit(struct pipe_context *ctx,
                      const struct pipe_blit_info *info)
{
	struct r600_context *rctx = (struct r600_context*)ctx;

	if (do_hardware_msaa_resolve(ctx, info)) {
		return;
	}

	assert(util_blitter_is_blit_supported(rctx->blitter, info));

	/* The driver doesn't decompress resources automatically while
	 * u_blitter is rendering. */
	if (!r600_decompress_subresource(ctx, info->src.resource, info->src.level,
					 info->src.box.z,
					 info->src.box.z + info->src.box.depth - 1)) {
		return; /* error */
	}

	if (rctx->screen->b.debug_flags & DBG_FORCE_DMA &&
	    util_try_blit_via_copy_region(ctx, info))
		return;

	r600_blitter_begin(ctx, R600_BLIT |
			   (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND));
	util_blitter_blit(rctx->blitter, info);
	r600_blitter_end(ctx);
}
static bool
render_blit(struct pipe_context *ctx, struct pipe_blit_info *info)
{
    struct vc4_context *vc4 = vc4_context(ctx);

    if (!util_blitter_is_blit_supported(vc4->blitter, info)) {
        fprintf(stderr, "blit unsupported %s -> %s",
                util_format_short_name(info->src.resource->format),
                util_format_short_name(info->dst.resource->format));
        return false;
    }

    util_blitter_save_vertex_buffer_slot(vc4->blitter, vc4->vertexbuf.vb);
    util_blitter_save_vertex_elements(vc4->blitter, vc4->vtx);
    util_blitter_save_vertex_shader(vc4->blitter, vc4->prog.bind_vs);
    util_blitter_save_rasterizer(vc4->blitter, vc4->rasterizer);
    util_blitter_save_viewport(vc4->blitter, &vc4->viewport);
    util_blitter_save_scissor(vc4->blitter, &vc4->scissor);
    util_blitter_save_fragment_shader(vc4->blitter, vc4->prog.bind_fs);
    util_blitter_save_blend(vc4->blitter, vc4->blend);
    util_blitter_save_depth_stencil_alpha(vc4->blitter, vc4->zsa);
    util_blitter_save_stencil_ref(vc4->blitter, &vc4->stencil_ref);
    util_blitter_save_sample_mask(vc4->blitter, vc4->sample_mask);
    util_blitter_save_framebuffer(vc4->blitter, &vc4->framebuffer);
    util_blitter_save_fragment_sampler_states(vc4->blitter,
            vc4->fragtex.num_samplers,
            (void **)vc4->fragtex.samplers);
    util_blitter_save_fragment_sampler_views(vc4->blitter,
            vc4->fragtex.num_textures, vc4->fragtex.textures);

    util_blitter_blit(vc4->blitter, info);

    return true;
}
Beispiel #6
0
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 info = *blit_info;

   if (info.src.resource->nr_samples > 1 &&
       info.dst.resource->nr_samples <= 1 &&
       !util_format_is_depth_or_stencil(info.src.resource->format) &&
       !util_format_is_pure_integer(info.src.resource->format)) {
      debug_printf("svga: color resolve unimplemented\n");
      return;
   }

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("svga: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(svga->blitter, &info)) {
      debug_printf("svga: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   /* XXX turn off occlusion and streamout queries */

   util_blitter_save_vertex_buffers(svga->blitter,
                                    svga->curr.num_vertex_buffers,
                                    svga->curr.vb);
   util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems);
   util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs);
   /*util_blitter_save_geometry_shader(svga->blitter, svga->curr.gs);*/
   /*util_blitter_save_so_targets(svga->blitter, svga->num_so_targets,
                     (struct pipe_stream_output_target**)svga->so_targets);*/
   util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast);
   util_blitter_save_viewport(svga->blitter, &svga->curr.viewport);
   util_blitter_save_scissor(svga->blitter, &svga->curr.scissor);
   util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs);
   util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend);
   util_blitter_save_depth_stencil_alpha(svga->blitter,
                                         (void*)svga->curr.depth);
   util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref);
   /*util_blitter_save_sample_mask(svga->blitter, svga->sample_mask);*/
   util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer);
   util_blitter_save_fragment_sampler_states(svga->blitter,
                     svga->curr.num_samplers,
                     (void**)svga->curr.sampler);
   util_blitter_save_fragment_sampler_views(svga->blitter,
                     svga->curr.num_sampler_views,
                     svga->curr.sampler_views);
   /*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query,
                                      svga->render_cond_mode);*/
   util_blitter_blit(svga->blitter, &info);
}
Beispiel #7
0
/**
 * Optimal hardware path for blitting pixels.
 * Scaling, format conversion, up- and downsampling (resolve) are allowed.
 */
static void
fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
{
	struct fd_context *ctx = fd_context(pctx);
	struct pipe_blit_info info = *blit_info;

	if (info.src.resource->nr_samples > 1 &&
			info.dst.resource->nr_samples <= 1 &&
			!util_format_is_depth_or_stencil(info.src.resource->format) &&
			!util_format_is_pure_integer(info.src.resource->format)) {
		DBG("color resolve unimplemented");
		return;
	}

	if (util_try_blit_via_copy_region(pctx, &info)) {
		return; /* done */
	}

	if (info.mask & PIPE_MASK_S) {
		DBG("cannot blit stencil, skipping");
		info.mask &= ~PIPE_MASK_S;
	}

	if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
		DBG("blit unsupported %s -> %s",
				util_format_short_name(info.src.resource->format),
				util_format_short_name(info.dst.resource->format));
		return;
	}

	fd_blitter_pipe_begin(ctx);
	util_blitter_blit(ctx->blitter, &info);
	fd_blitter_pipe_end(ctx);
}
Beispiel #8
0
static void si_blit(struct pipe_context *ctx,
                      const struct pipe_blit_info *info)
{
	struct r600_context *rctx = (struct r600_context*)ctx;

	if (info->src.resource->nr_samples > 1 &&
	    info->dst.resource->nr_samples <= 1 &&
	    !util_format_is_depth_or_stencil(info->src.resource->format) &&
	    !util_format_is_pure_integer(info->src.resource->format)) {
		si_msaa_color_resolve(ctx, info);
		return;
	}

	assert(util_blitter_is_blit_supported(rctx->blitter, info));

	/* The driver doesn't decompress resources automatically while
	 * u_blitter is rendering. */
	r600_decompress_subresource(ctx, info->src.resource, info->src.level,
				    info->src.box.z,
				    info->src.box.z + info->src.box.depth - 1);

	r600_blitter_begin(ctx, R600_BLIT);
	util_blitter_blit(rctx->blitter, info);
	r600_blitter_end(ctx);
}
Beispiel #9
0
static void lp_blit(struct pipe_context *pipe,
                    const struct pipe_blit_info *blit_info)
{
   struct llvmpipe_context *lp = llvmpipe_context(pipe);
   struct pipe_blit_info info = *blit_info;

   if (info.src.resource->nr_samples > 1 &&
       info.dst.resource->nr_samples <= 1 &&
       !util_format_is_depth_or_stencil(info.src.resource->format) &&
       !util_format_is_pure_integer(info.src.resource->format)) {
      debug_printf("llvmpipe: color resolve unimplemented\n");
      return;
   }

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("llvmpipe: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(lp->blitter, &info)) {
      debug_printf("llvmpipe: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   /* XXX turn off occlusion and streamout queries */

   util_blitter_save_vertex_buffers(lp->blitter, lp->num_vertex_buffers,
                                    lp->vertex_buffer);
   util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
   util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
   util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
   /*util_blitter_save_so_targets(lp->blitter, lp->num_so_targets,
                     (struct pipe_stream_output_target**)lp->so_targets);*/
   util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer);
   util_blitter_save_viewport(lp->blitter, &lp->viewport);
   util_blitter_save_scissor(lp->blitter, &lp->scissor);
   util_blitter_save_fragment_shader(lp->blitter, lp->fs);
   util_blitter_save_blend(lp->blitter, (void*)lp->blend);
   util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil);
   util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref);
   /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/
   util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer);
   util_blitter_save_fragment_sampler_states(lp->blitter,
                     lp->num_samplers[PIPE_SHADER_FRAGMENT],
                     (void**)lp->samplers[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_fragment_sampler_views(lp->blitter,
                     lp->num_sampler_views[PIPE_SHADER_FRAGMENT],
                     lp->sampler_views[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_render_condition(lp->blitter, lp->render_cond_query,
                                      lp->render_cond_mode);
   util_blitter_blit(lp->blitter, &info);
}
Beispiel #10
0
void
nv30_blit(struct pipe_context *pipe,
          const struct pipe_blit_info *blit_info)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct pipe_blit_info info = *blit_info;

   if (info.src.resource->nr_samples > 1 &&
       info.dst.resource->nr_samples <= 1 &&
       !util_format_is_depth_or_stencil(info.src.resource->format) &&
       !util_format_is_pure_integer(info.src.resource->format)) {
      debug_printf("nv30: color resolve unimplemented\n");
      return;
   }

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("nv30: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(nv30->blitter, &info)) {
      debug_printf("nv30: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   /* XXX turn off occlusion queries */

   util_blitter_save_vertex_buffer_slot(nv30->blitter, nv30->vtxbuf);
   util_blitter_save_vertex_elements(nv30->blitter, nv30->vertex);
   util_blitter_save_vertex_shader(nv30->blitter, nv30->vertprog.program);
   util_blitter_save_rasterizer(nv30->blitter, nv30->rast);
   util_blitter_save_viewport(nv30->blitter, &nv30->viewport);
   util_blitter_save_scissor(nv30->blitter, &nv30->scissor);
   util_blitter_save_fragment_shader(nv30->blitter, nv30->fragprog.program);
   util_blitter_save_blend(nv30->blitter, nv30->blend);
   util_blitter_save_depth_stencil_alpha(nv30->blitter,
                                         nv30->zsa);
   util_blitter_save_stencil_ref(nv30->blitter, &nv30->stencil_ref);
   util_blitter_save_sample_mask(nv30->blitter, nv30->sample_mask);
   util_blitter_save_framebuffer(nv30->blitter, &nv30->framebuffer);
   util_blitter_save_fragment_sampler_states(nv30->blitter,
                     nv30->fragprog.num_samplers,
                     (void**)nv30->fragprog.samplers);
   util_blitter_save_fragment_sampler_views(nv30->blitter,
                     nv30->fragprog.num_textures, nv30->fragprog.textures);
   util_blitter_save_render_condition(nv30->blitter, nv30->render_cond_query,
                                      nv30->render_cond_mode);
   util_blitter_blit(nv30->blitter, &info);
}
Beispiel #11
0
static void sp_blit(struct pipe_context *pipe,
                    const struct pipe_blit_info *info)
{
   struct softpipe_context *sp = softpipe_context(pipe);

   if (info->render_condition_enable && !softpipe_check_render_cond(sp))
      return;

   if (info->src.resource->nr_samples > 1 &&
       info->dst.resource->nr_samples <= 1 &&
       !util_format_is_depth_or_stencil(info->src.resource->format) &&
       !util_format_is_pure_integer(info->src.resource->format)) {
      debug_printf("softpipe: color resolve unimplemented\n");
      return;
   }

   if (util_try_blit_via_copy_region(pipe, info)) {
      return; /* done */
   }

   if (!util_blitter_is_blit_supported(sp->blitter, info)) {
      debug_printf("softpipe: blit unsupported %s -> %s\n",
                   util_format_short_name(info->src.resource->format),
                   util_format_short_name(info->dst.resource->format));
      return;
   }

   /* XXX turn off occlusion and streamout queries */

   util_blitter_save_vertex_buffer_slot(sp->blitter, sp->vertex_buffer);
   util_blitter_save_vertex_elements(sp->blitter, sp->velems);
   util_blitter_save_vertex_shader(sp->blitter, sp->vs);
   util_blitter_save_geometry_shader(sp->blitter, sp->gs);
   util_blitter_save_so_targets(sp->blitter, sp->num_so_targets,
                     (struct pipe_stream_output_target**)sp->so_targets);
   util_blitter_save_rasterizer(sp->blitter, sp->rasterizer);
   util_blitter_save_viewport(sp->blitter, &sp->viewports[0]);
   util_blitter_save_scissor(sp->blitter, &sp->scissors[0]);
   util_blitter_save_fragment_shader(sp->blitter, sp->fs);
   util_blitter_save_blend(sp->blitter, sp->blend);
   util_blitter_save_depth_stencil_alpha(sp->blitter, sp->depth_stencil);
   util_blitter_save_stencil_ref(sp->blitter, &sp->stencil_ref);
   /*util_blitter_save_sample_mask(sp->blitter, sp->sample_mask);*/
   util_blitter_save_framebuffer(sp->blitter, &sp->framebuffer);
   util_blitter_save_fragment_sampler_states(sp->blitter,
                     sp->num_samplers[PIPE_SHADER_FRAGMENT],
                     (void**)sp->samplers[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_fragment_sampler_views(sp->blitter,
                     sp->num_sampler_views[PIPE_SHADER_FRAGMENT],
                     sp->sampler_views[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_render_condition(sp->blitter, sp->render_cond_query,
                                      sp->render_cond_cond, sp->render_cond_mode);
   util_blitter_blit(sp->blitter, info);
}
Beispiel #12
0
/* Optimal hardware path for blitting pixels.
 * Scaling, format conversion, up- and downsampling (resolve) are allowed.
 */
static void
fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
{
	struct fd_context *ctx = fd_context(pctx);
	struct pipe_blit_info info = *blit_info;

	if (info.src.resource->nr_samples > 1 &&
			info.dst.resource->nr_samples <= 1 &&
			!util_format_is_depth_or_stencil(info.src.resource->format) &&
			!util_format_is_pure_integer(info.src.resource->format)) {
		DBG("color resolve unimplemented");
		return;
	}

	if (util_try_blit_via_copy_region(pctx, &info)) {
		return; /* done */
	}

	if (info.mask & PIPE_MASK_S) {
		DBG("cannot blit stencil, skipping");
		info.mask &= ~PIPE_MASK_S;
	}

	if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
		DBG("blit unsupported %s -> %s",
				util_format_short_name(info.src.resource->format),
				util_format_short_name(info.dst.resource->format));
		return;
	}

	util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertexbuf.vb);
	util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx);
	util_blitter_save_vertex_shader(ctx->blitter, ctx->prog.vp);
	util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer);
	util_blitter_save_viewport(ctx->blitter, &ctx->viewport);
	util_blitter_save_scissor(ctx->blitter, &ctx->scissor);
	util_blitter_save_fragment_shader(ctx->blitter, ctx->prog.fp);
	util_blitter_save_blend(ctx->blitter, ctx->blend);
	util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->zsa);
	util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
	util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask);
	util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer.base);
	util_blitter_save_fragment_sampler_states(ctx->blitter,
			ctx->fragtex.num_samplers,
			(void **)ctx->fragtex.samplers);
	util_blitter_save_fragment_sampler_views(ctx->blitter,
			ctx->fragtex.num_textures, ctx->fragtex.textures);

	util_blitter_blit(ctx->blitter, &info);
}
Beispiel #13
0
bool
ilo_blitter_pipe_blit(struct ilo_blitter *blitter,
                      const struct pipe_blit_info *info)
{
   struct blitter_context *b = blitter->pipe_blitter;
   struct pipe_blit_info skip_stencil;

   if (util_try_blit_via_copy_region(&blitter->ilo->base, info))
      return true;

   if (!util_blitter_is_blit_supported(b, info)) {
      /* try without stencil */
      if (info->mask & PIPE_MASK_S) {
         skip_stencil = *info;
         skip_stencil.mask = info->mask & ~PIPE_MASK_S;

         if (util_blitter_is_blit_supported(blitter->pipe_blitter,
                                            &skip_stencil)) {
            ilo_warn("ignore stencil buffer blitting\n");
            info = &skip_stencil;
         }
      }

      if (info != &skip_stencil) {
         ilo_warn("failed to blit with pipe blitter\n");
         return false;
      }
   }

   ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_BLIT,
         info->scissor_enable);
   util_blitter_blit(b, info);
   ilo_blitter_pipe_end(blitter);

   return true;
}
Beispiel #14
0
static void si_blit(struct pipe_context *ctx,
		    const struct pipe_blit_info *info)
{
	struct si_context *sctx = (struct si_context*)ctx;

	if (do_hardware_msaa_resolve(ctx, info)) {
		return;
	}

	assert(util_blitter_is_blit_supported(sctx->blitter, info));

	/* The driver doesn't decompress resources automatically while
	 * u_blitter is rendering. */
	si_decompress_subresource(ctx, info->src.resource, info->src.level,
				  info->src.box.z,
				  info->src.box.z + info->src.box.depth - 1);

	si_blitter_begin(ctx, SI_BLIT);
	util_blitter_blit(sctx->blitter, info);
	si_blitter_end(ctx);
}
Beispiel #15
0
static void *vc4_get_yuv_vs(struct pipe_context *pctx)
{
   struct vc4_context *vc4 = vc4_context(pctx);
   struct pipe_screen *pscreen = pctx->screen;

   if (vc4->yuv_linear_blit_vs)
           return vc4->yuv_linear_blit_vs;

   const struct nir_shader_compiler_options *options =
           pscreen->get_compiler_options(pscreen,
                                         PIPE_SHADER_IR_NIR,
                                         PIPE_SHADER_VERTEX);

   nir_builder b;
   nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, options);
   b.shader->info.name = ralloc_strdup(b.shader, "linear_blit_vs");

   const struct glsl_type *vec4 = glsl_vec4_type();
   nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
                                              vec4, "pos");

   nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out,
                                               vec4, "gl_Position");
   pos_out->data.location = VARYING_SLOT_POS;

   nir_store_var(&b, pos_out, nir_load_var(&b, pos_in), 0xf);

   struct pipe_shader_state shader_tmpl = {
           .type = PIPE_SHADER_IR_NIR,
           .ir.nir = b.shader,
   };

   vc4->yuv_linear_blit_vs = pctx->create_vs_state(pctx, &shader_tmpl);

   return vc4->yuv_linear_blit_vs;
}

static void *vc4_get_yuv_fs(struct pipe_context *pctx, int cpp)
{
   struct vc4_context *vc4 = vc4_context(pctx);
   struct pipe_screen *pscreen = pctx->screen;
   struct pipe_shader_state **cached_shader;
   const char *name;

   if (cpp == 1) {
           cached_shader = &vc4->yuv_linear_blit_fs_8bit;
           name = "linear_blit_8bit_fs";
   } else {
           cached_shader = &vc4->yuv_linear_blit_fs_16bit;
           name = "linear_blit_16bit_fs";
   }

   if (*cached_shader)
           return *cached_shader;

   const struct nir_shader_compiler_options *options =
           pscreen->get_compiler_options(pscreen,
                                         PIPE_SHADER_IR_NIR,
                                         PIPE_SHADER_FRAGMENT);

   nir_builder b;
   nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, options);
   b.shader->info.name = ralloc_strdup(b.shader, name);

   const struct glsl_type *vec4 = glsl_vec4_type();
   const struct glsl_type *glsl_int = glsl_int_type();

   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
                                                 vec4, "f_color");
   color_out->data.location = FRAG_RESULT_COLOR;

   nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
                                              vec4, "pos");
   pos_in->data.location = VARYING_SLOT_POS;
   nir_ssa_def *pos = nir_load_var(&b, pos_in);

   nir_ssa_def *one = nir_imm_int(&b, 1);
   nir_ssa_def *two = nir_imm_int(&b, 2);

   nir_ssa_def *x = nir_f2i32(&b, nir_channel(&b, pos, 0));
   nir_ssa_def *y = nir_f2i32(&b, nir_channel(&b, pos, 1));

   nir_variable *stride_in = nir_variable_create(b.shader, nir_var_uniform,
                                                 glsl_int, "stride");
   nir_ssa_def *stride = nir_load_var(&b, stride_in);

   nir_ssa_def *x_offset;
   nir_ssa_def *y_offset;
   if (cpp == 1) {
           nir_ssa_def *intra_utile_x_offset =
                   nir_ishl(&b, nir_iand(&b, x, one), two);
           nir_ssa_def *inter_utile_x_offset =
                   nir_ishl(&b, nir_iand(&b, x, nir_imm_int(&b, ~3)), one);

           x_offset = nir_iadd(&b,
                               intra_utile_x_offset,
                               inter_utile_x_offset);
           y_offset = nir_imul(&b,
                               nir_iadd(&b,
                                        nir_ishl(&b, y, one),
                                        nir_ushr(&b, nir_iand(&b, x, two), one)),
                               stride);
   } else {
           x_offset = nir_ishl(&b, x, two);
           y_offset = nir_imul(&b, y, stride);
   }

   nir_intrinsic_instr *load =
           nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_ubo);
   load->num_components = 1;
   nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, 32, NULL);
   load->src[0] = nir_src_for_ssa(one);
   load->src[1] = nir_src_for_ssa(nir_iadd(&b, x_offset, y_offset));
   nir_builder_instr_insert(&b, &load->instr);

   nir_store_var(&b, color_out,
                 nir_unpack_unorm_4x8(&b, &load->dest.ssa),
                 0xf);

   struct pipe_shader_state shader_tmpl = {
           .type = PIPE_SHADER_IR_NIR,
           .ir.nir = b.shader,
   };

   *cached_shader = pctx->create_fs_state(pctx, &shader_tmpl);

   return *cached_shader;
}

static bool
vc4_yuv_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        struct vc4_resource *src = vc4_resource(info->src.resource);
        struct vc4_resource *dst = vc4_resource(info->dst.resource);
        bool ok;

        if (src->tiled)
                return false;
        if (src->base.format != PIPE_FORMAT_R8_UNORM &&
            src->base.format != PIPE_FORMAT_R8G8_UNORM)
                return false;

        /* YUV blits always turn raster-order to tiled */
        assert(dst->base.format == src->base.format);
        assert(dst->tiled);

        /* Always 1:1 and at the origin */
        assert(info->src.box.x == 0 && info->dst.box.x == 0);
        assert(info->src.box.y == 0 && info->dst.box.y == 0);
        assert(info->src.box.width == info->dst.box.width);
        assert(info->src.box.height == info->dst.box.height);

        if ((src->slices[info->src.level].offset & 3) ||
            (src->slices[info->src.level].stride & 3)) {
                perf_debug("YUV-blit src texture offset/stride misaligned: 0x%08x/%d\n",
                           src->slices[info->src.level].offset,
                           src->slices[info->src.level].stride);
                goto fallback;
        }

        vc4_blitter_save(vc4);

        /* Create a renderable surface mapping the T-tiled shadow buffer.
         */
        struct pipe_surface dst_tmpl;
        util_blitter_default_dst_texture(&dst_tmpl, info->dst.resource,
                                         info->dst.level, info->dst.box.z);
        dst_tmpl.format = PIPE_FORMAT_RGBA8888_UNORM;
        struct pipe_surface *dst_surf =
                pctx->create_surface(pctx, info->dst.resource, &dst_tmpl);
        if (!dst_surf) {
                fprintf(stderr, "Failed to create YUV dst surface\n");
                util_blitter_unset_running_flag(vc4->blitter);
                return false;
        }
        dst_surf->width /= 2;
        if (dst->cpp == 1)
                dst_surf->height /= 2;

        /* Set the constant buffer. */
        uint32_t stride = src->slices[info->src.level].stride;
        struct pipe_constant_buffer cb_uniforms = {
                .user_buffer = &stride,
                .buffer_size = sizeof(stride),
        };
        pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, &cb_uniforms);
        struct pipe_constant_buffer cb_src = {
                .buffer = info->src.resource,
                .buffer_offset = src->slices[info->src.level].offset,
                .buffer_size = (src->bo->size -
                                src->slices[info->src.level].offset),
        };
        pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, &cb_src);

        /* Unbind the textures, to make sure we don't try to recurse into the
         * shadow blit.
         */
        pctx->set_sampler_views(pctx, PIPE_SHADER_FRAGMENT, 0, 0, NULL);
        pctx->bind_sampler_states(pctx, PIPE_SHADER_FRAGMENT, 0, 0, NULL);

        util_blitter_custom_shader(vc4->blitter, dst_surf,
                                   vc4_get_yuv_vs(pctx),
                                   vc4_get_yuv_fs(pctx, src->cpp));

        util_blitter_restore_textures(vc4->blitter);
        util_blitter_restore_constant_buffer_state(vc4->blitter);
        /* Restore cb1 (util_blitter doesn't handle this one). */
        struct pipe_constant_buffer cb_disabled = { 0 };
        pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, &cb_disabled);

        pipe_surface_reference(&dst_surf, NULL);

        return true;

fallback:
        /* Do an immediate SW fallback, since the render blit path
         * would just recurse.
         */
        ok = util_try_blit_via_copy_region(pctx, info);
        assert(ok); (void)ok;

        return true;
}

static bool
vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info)
{
        struct vc4_context *vc4 = vc4_context(ctx);

        if (!util_blitter_is_blit_supported(vc4->blitter, info)) {
                fprintf(stderr, "blit unsupported %s -> %s\n",
                    util_format_short_name(info->src.resource->format),
                    util_format_short_name(info->dst.resource->format));
                return false;
        }

        /* Enable the scissor, so we get a minimal set of tiles rendered. */
        if (!info->scissor_enable) {
                info->scissor_enable = true;
                info->scissor.minx = info->dst.box.x;
                info->scissor.miny = info->dst.box.y;
                info->scissor.maxx = info->dst.box.x + info->dst.box.width;
                info->scissor.maxy = info->dst.box.y + info->dst.box.height;
        }

        vc4_blitter_save(vc4);
        util_blitter_blit(vc4->blitter, info);

        return true;
}

/* Optimal hardware path for blitting pixels.
 * Scaling, format conversion, up- and downsampling (resolve) are allowed.
 */
void
vc4_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
{
        struct pipe_blit_info info = *blit_info;

        if (vc4_yuv_blit(pctx, blit_info))
                return;

        if (vc4_tile_blit(pctx, blit_info))
                return;

        if (info.mask & PIPE_MASK_S) {
                if (util_try_blit_via_copy_region(pctx, &info))
                        return;

                info.mask &= ~PIPE_MASK_S;
                fprintf(stderr, "cannot blit stencil, skipping\n");
        }

        if (vc4_render_blit(pctx, &info))
                return;

        fprintf(stderr, "Unsupported blit\n");
}
/**
 * Try issuing a quad blit.
 */
static bool
try_blit(struct svga_context *svga, const struct pipe_blit_info *blit_info)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   struct pipe_resource *src = blit_info->src.resource;
   struct pipe_resource *dst = blit_info->dst.resource;
   struct pipe_resource *newSrc = NULL;
   struct pipe_resource *newDst = NULL;
   bool can_create_src_view;
   bool can_create_dst_view;
   bool ret = true;
   struct pipe_blit_info blit = *blit_info;

   SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_BLITBLITTER);

   /**
    * Avoid using util_blitter_blit() for these depth formats on non-vgpu10
    * devices because these depth formats only support comparison mode
    * and not ordinary sampling.
    */
   if (!svga_have_vgpu10(svga) && (blit.mask & PIPE_MASK_Z) &&
       (svga_texture(dst)->key.format == SVGA3D_Z_D16 ||
       svga_texture(dst)->key.format == SVGA3D_Z_D24X8 ||
       svga_texture(dst)->key.format == SVGA3D_Z_D24S8)) {
      ret = false;
      goto done;
  }

   /**
    * If format is srgb and blend is enabled then color values need
    * to be converted into linear format.
    */
   if (is_blending_enabled(svga, &blit)) {
      blit.src.format = util_format_linear(blit.src.format);
      blit.dst.format = util_format_linear(blit.dst.format);
   }

   /* 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) ||
       ((!can_create_dst_view || !can_create_src_view)
        && !svga_have_vgpu10(svga))) {
      /* Can't do stencil blits with textured quad blitter */
      debug_warn_once("using software stencil blit");
      ret = false;
      goto done;
   }

   if (!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));
      ret = false;
      goto done;
   }

   /* XXX turn off occlusion and streamout queries */

   util_blitter_save_vertex_buffer_slot(svga->blitter, svga->curr.vb);
   util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems);
   util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs);
   util_blitter_save_geometry_shader(svga->blitter, svga->curr.user_gs);
   util_blitter_save_so_targets(svga->blitter, svga->num_so_targets,
                     (struct pipe_stream_output_target**)svga->so_targets);
   util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast);
   util_blitter_save_viewport(svga->blitter, &svga->curr.viewport);
   util_blitter_save_scissor(svga->blitter, &svga->curr.scissor);
   util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs);
   util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend);
   util_blitter_save_depth_stencil_alpha(svga->blitter,
                                         (void*)svga->curr.depth);
   util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref);
   util_blitter_save_sample_mask(svga->blitter, svga->curr.sample_mask);
   util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer);
   util_blitter_save_fragment_sampler_states(svga->blitter,
                     svga->curr.num_samplers[PIPE_SHADER_FRAGMENT],
                     (void**)svga->curr.sampler[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_fragment_sampler_views(svga->blitter,
                     svga->curr.num_sampler_views[PIPE_SHADER_FRAGMENT],
                     svga->curr.sampler_views[PIPE_SHADER_FRAGMENT]);

   if (!can_create_src_view) {
      struct pipe_resource template;
      struct pipe_blit_info copy_region_blit;
Beispiel #17
0
static void
swr_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
{
   struct swr_context *ctx = swr_context(pipe);
   /* Make a copy of the const blit_info, so we can modify it */
   struct pipe_blit_info info = *blit_info;

   if (info.render_condition_enable && !swr_check_render_cond(pipe))
      return;

   if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1
       && !util_format_is_depth_or_stencil(info.src.resource->format)
       && !util_format_is_pure_integer(info.src.resource->format)) {
      debug_printf("swr_blit: color resolve : %d -> %d\n",
            info.src.resource->nr_samples, info.dst.resource->nr_samples);

      /* Resolve is done as part of the surface store. */
      swr_store_dirty_resource(pipe, info.src.resource, SWR_TILE_RESOLVED);

      struct pipe_resource *src_resource = info.src.resource;
      struct pipe_resource *resolve_target =
         swr_resource(src_resource)->resolve_target;

      /* The resolve target becomes the new source for the blit. */
      info.src.resource = resolve_target;
   }

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("swr: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
      debug_printf("swr: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   if (ctx->active_queries) {
      ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, FALSE);
      ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, FALSE);
   }

   util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffer);
   util_blitter_save_vertex_elements(ctx->blitter, (void *)ctx->velems);
   util_blitter_save_vertex_shader(ctx->blitter, (void *)ctx->vs);
   util_blitter_save_geometry_shader(ctx->blitter, (void*)ctx->gs);
   util_blitter_save_so_targets(
      ctx->blitter,
      ctx->num_so_targets,
      (struct pipe_stream_output_target **)ctx->so_targets);
   util_blitter_save_rasterizer(ctx->blitter, (void *)ctx->rasterizer);
   util_blitter_save_viewport(ctx->blitter, &ctx->viewport);
   util_blitter_save_scissor(ctx->blitter, &ctx->scissor);
   util_blitter_save_fragment_shader(ctx->blitter, ctx->fs);
   util_blitter_save_blend(ctx->blitter, (void *)ctx->blend);
   util_blitter_save_depth_stencil_alpha(ctx->blitter,
                                         (void *)ctx->depth_stencil);
   util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
   util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask);
   util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer);
   util_blitter_save_fragment_sampler_states(
      ctx->blitter,
      ctx->num_samplers[PIPE_SHADER_FRAGMENT],
      (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_fragment_sampler_views(
      ctx->blitter,
      ctx->num_sampler_views[PIPE_SHADER_FRAGMENT],
      ctx->sampler_views[PIPE_SHADER_FRAGMENT]);
   util_blitter_save_render_condition(ctx->blitter,
                                      ctx->render_cond_query,
                                      ctx->render_cond_cond,
                                      ctx->render_cond_mode);

   util_blitter_blit(ctx->blitter, &info);

   if (ctx->active_queries) {
      ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, TRUE);
      ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, TRUE);
   }
}