- return;
- }
-
- if (dst_format == dst->format) {
- dst_surface = dst;
- } else {
- struct pipe_surface templ = *dst;
- templ.format = dst_format;
- dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
- }
-
- /* 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_surface->texture &&
- dst_surface->u.tex.level == src_level &&
- dst_surface->u.tex.first_layer == srcZ0) ||
- (src_tex->target != PIPE_TEXTURE_2D &&
- src_tex->target != PIPE_TEXTURE_2D &&
- src_tex->target != PIPE_TEXTURE_RECT))
- {
- struct pipe_resource texTemp;
- struct pipe_resource *tex;
- struct pipe_sampler_view sv_templ;
- struct pipe_box src_box;
- 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 = ctx->internal_target;
- texTemp.format = src_format;
- texTemp.last_level = 0;
- texTemp.width0 = srcW;
- texTemp.height0 = srcH;
- texTemp.depth0 = 1;
- texTemp.array_size = 1;
- texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
-
- tex = screen->resource_create(screen, &texTemp);
- if (!tex)
- return;
-
- src_box.x = srcLeft;
- src_box.y = srcTop;
- src_box.z = srcZ0;
- src_box.width = srcW;
- src_box.height = srcH;
- src_box.depth = 1;
- /* load temp texture */
- pipe->resource_copy_region(pipe,
- tex, 0, 0, 0, 0, /* dest */
- src_tex, src_level, &src_box);
-
- normalized = tex->target != PIPE_TEXTURE_RECT;
- if(normalized) {
- s0 = 0.0f;
- s1 = 1.0f;
- t0 = 0.0f;
- t1 = 1.0f;
- }
- else {
- s0 = 0;
- s1 = srcW;
- t0 = 0;
- t1 = srcH;
- }
-
- 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_format);
- sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
-
- if (!sampler_view) {
- return;
- }
-
- s0 = srcX0;
- s1 = srcX1;
- t0 = srcY0;
- t1 = srcY1;
- normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT;
- if(normalized)
- {
- s0 /= (float)(u_minify(sampler_view->texture->width0, src_level));
- s1 /= (float)(u_minify(sampler_view->texture->width0, src_level));
- t0 /= (float)(u_minify(sampler_view->texture->height0, src_level));
- t1 /= (float)(u_minify(sampler_view->texture->height0, src_level));
- }
- }
-
- dst_is_depth = util_format_is_depth_or_stencil(dst_format);
-
- assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target,
- sampler_view->texture->nr_samples,
- PIPE_BIND_SAMPLER_VIEW));
- assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
- dst_surface->texture->nr_samples,
- dst_is_depth ? PIPE_BIND_DEPTH_STENCIL :
- PIPE_BIND_RENDER_TARGET));
- /* 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_stream_outputs(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_geometry_shader(ctx->cso);
- cso_save_clip(ctx->cso);
- cso_save_vertex_elements(ctx->cso);
- cso_save_vertex_buffers(ctx->cso);
-
- /* set misc state we care about */
- cso_set_blend(ctx->cso, &ctx->blend);
- cso_set_depth_stencil_alpha(ctx->cso,
- dst_is_depth ? &ctx->depthstencil_write :
- &ctx->depthstencil_keep);
- cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
- cso_set_clip(ctx->cso, &ctx->clip);
- cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
- cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
-
- /* sampler */
- ctx->sampler.normalized_coords = normalized;
- ctx->sampler.min_img_filter = filter;
- ctx->sampler.mag_img_filter = filter;
- ctx->sampler.min_lod = src_level;
- ctx->sampler.max_lod = src_level;
- cso_single_sampler(ctx->cso, 0, &ctx->sampler);
- cso_single_sampler_done(ctx->cso);
-
- /* viewport */
- ctx->viewport.scale[0] = 0.5f * dst_surface->width;
- ctx->viewport.scale[1] = 0.5f * dst_surface->height;
- ctx->viewport.scale[2] = 0.5f;
- ctx->viewport.scale[3] = 1.0f;
- ctx->viewport.translate[0] = 0.5f * dst_surface->width;
- ctx->viewport.translate[1] = 0.5f * dst_surface->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);
-
- /* shaders */
- if (dst_is_depth) {
- set_depth_fragment_shader(ctx);
- } else {
- set_fragment_shader(ctx, writemask);
- }
- set_vertex_shader(ctx);
- cso_set_geometry_shader_handle(ctx->cso, NULL);
-
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst_surface->width;
- fb.height = dst_surface->height;
- if (dst_is_depth) {
- fb.zsbuf = dst_surface;
- } else {
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst_surface;
- }
- cso_set_framebuffer(ctx->cso, &fb);
-
- /* draw quad */
- offset = setup_vertex_data_tex(ctx,
- (float) dstX0 / dst_surface->width * 2.0f - 1.0f,
- (float) dstY0 / dst_surface->height * 2.0f - 1.0f,
- (float) dstX1 / dst_surface->width * 2.0f - 1.0f,
- (float) dstY1 / dst_surface->height * 2.0f - 1.0f,
- s0, t0,
- s1, t1,
- z);
-
- if (ctx->vbuf) {
- util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */