-
- /* Create a temporary texture when src and dest alias or when src
- * is anything other than a 2d texture.
- * XXX should just use appropriate shader to access 1d / 3d slice / cube face,
- * much like the u_blitter code does (should be pretty trivial).
- *
- * This can still be improved upon.
- */
- if ((src_tex == dst->texture &&
- dst->face == srcsub.face &&
- dst->level == srcsub.level &&
- dst->zslice == srcZ0) ||
- src_tex->target != PIPE_TEXTURE_2D)
- {
- struct pipe_resource texTemp;
- struct pipe_resource *tex;
- struct pipe_sampler_view sv_templ;
- struct pipe_subresource texsub;
- const int srcLeft = MIN2(srcX0, srcX1);
- const int srcTop = MIN2(srcY0, srcY1);
-
- if (srcLeft != srcX0) {
- /* left-right flip */
- int tmp = dstX0;
- dstX0 = dstX1;
- dstX1 = tmp;
- }
-
- if (srcTop != srcY0) {
- /* up-down flip */
- int tmp = dstY0;
- dstY0 = dstY1;
- dstY1 = tmp;
- }
-
- /* create temp texture */
- memset(&texTemp, 0, sizeof(texTemp));
- texTemp.target = PIPE_TEXTURE_2D;
- texTemp.format = src_tex->format;
- texTemp.last_level = 0;
- texTemp.width0 = srcW;
- texTemp.height0 = srcH;
- texTemp.depth0 = 1;
- texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
-
- tex = screen->resource_create(screen, &texTemp);
- if (!tex)
- return;
-
- texsub.face = 0;
- texsub.level = 0;
- /* load temp texture */
- pipe->resource_copy_region(pipe,
- tex, texsub, 0, 0, 0, /* dest */
- src_tex, srcsub, srcLeft, srcTop, srcZ0, /* src */
- srcW, srcH); /* size */
-
- s0 = 0.0f;
- s1 = 1.0f;
- t0 = 0.0f;
- t1 = 1.0f;
-
- u_sampler_view_default_template(&sv_templ, tex, tex->format);
- sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ);
-
- if (!sampler_view) {
- pipe_resource_reference(&tex, NULL);
- return;
- }
- pipe_resource_reference(&tex, NULL);
- }
- else {
- u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
- sv_templ.first_level = sv_templ.last_level = srcsub.level;
- sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
-
- if (!sampler_view) {
- return;
- }
-
- s0 = srcX0 / (float)(u_minify(sampler_view->texture->width0, srcsub.level));
- s1 = srcX1 / (float)(u_minify(sampler_view->texture->width0, srcsub.level));
- t0 = srcY0 / (float)(u_minify(sampler_view->texture->height0, srcsub.level));
- t1 = srcY1 / (float)(u_minify(sampler_view->texture->height0, srcsub.level));
- }
-
-
- assert(screen->is_format_supported(screen, sampler_view->format, PIPE_TEXTURE_2D,
- sampler_view->texture->nr_samples,
- PIPE_BIND_SAMPLER_VIEW, 0));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- dst->texture->nr_samples,
- PIPE_BIND_RENDER_TARGET, 0));
-
- /* save state (restored below) */
- cso_save_blend(ctx->cso);
- cso_save_depth_stencil_alpha(ctx->cso);
- cso_save_rasterizer(ctx->cso);
- cso_save_samplers(ctx->cso);
- cso_save_fragment_sampler_views(ctx->cso);
- cso_save_viewport(ctx->cso);
- cso_save_framebuffer(ctx->cso);
- cso_save_fragment_shader(ctx->cso);
- cso_save_vertex_shader(ctx->cso);
- cso_save_clip(ctx->cso);
- cso_save_vertex_elements(ctx->cso);
-
- /* set misc state we care about */
- cso_set_blend(ctx->cso, &ctx->blend);
- cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
- cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
- cso_set_clip(ctx->cso, &ctx->clip);
- cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
-
- /* sampler */
- ctx->sampler.min_img_filter = filter;
- ctx->sampler.mag_img_filter = filter;
- /* we've limited this already with the sampler view but you never know... */
- ctx->sampler.min_lod = srcsub.level;
- ctx->sampler.max_lod = srcsub.level;
- cso_single_sampler(ctx->cso, 0, &ctx->sampler);
- cso_single_sampler_done(ctx->cso);
-
- /* viewport */
- ctx->viewport.scale[0] = 0.5f * dst->width;
- ctx->viewport.scale[1] = 0.5f * dst->height;
- ctx->viewport.scale[2] = 0.5f;
- ctx->viewport.scale[3] = 1.0f;
- ctx->viewport.translate[0] = 0.5f * dst->width;
- ctx->viewport.translate[1] = 0.5f * dst->height;
- ctx->viewport.translate[2] = 0.5f;
- ctx->viewport.translate[3] = 0.0f;
- cso_set_viewport(ctx->cso, &ctx->viewport);
-
- /* texture */
- cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view);
-
- if (ctx->fs[writemask] == NULL)
- ctx->fs[writemask] =
- util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
- writemask);
-
- /* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
-
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst->width;
- fb.height = dst->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst;
- cso_set_framebuffer(ctx->cso, &fb);
-
- /* draw quad */
- offset = setup_vertex_data_tex(ctx,
- (float) dstX0 / dst->width * 2.0f - 1.0f,
- (float) dstY0 / dst->height * 2.0f - 1.0f,
- (float) dstX1 / dst->width * 2.0f - 1.0f,
- (float) dstY1 / dst->height * 2.0f - 1.0f,
- s0, t0,
- s1, t1,
- z);
-
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- /* restore state we changed */
- cso_restore_blend(ctx->cso);
- cso_restore_depth_stencil_alpha(ctx->cso);
- cso_restore_rasterizer(ctx->cso);
- cso_restore_samplers(ctx->cso);
- cso_restore_fragment_sampler_views(ctx->cso);
- cso_restore_viewport(ctx->cso);
- cso_restore_framebuffer(ctx->cso);
- cso_restore_fragment_shader(ctx->cso);
- cso_restore_vertex_shader(ctx->cso);
- cso_restore_clip(ctx->cso);
- cso_restore_vertex_elements(ctx->cso);
-
- pipe_sampler_view_reference(&sampler_view, NULL);