+static struct pipe_surface *
+i915_create_surface_custom(struct pipe_context *ctx,
+ struct pipe_resource *pt,
+ const struct pipe_surface *surf_tmpl,
+ unsigned width0,
+ unsigned height0);
+/*
+ * surface functions using the render engine
+ */
+
+static void
+i915_util_blitter_save_states(struct i915_context *i915)
+{
+ util_blitter_save_blend(i915->blitter, (void *)i915->blend);
+ util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil);
+ util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref);
+ util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer);
+ util_blitter_save_fragment_shader(i915->blitter, i915->fs);
+ util_blitter_save_vertex_shader(i915->blitter, i915->vs);
+ util_blitter_save_viewport(i915->blitter, &i915->viewport);
+ util_blitter_save_scissor(i915->blitter, &i915->scissor);
+ util_blitter_save_vertex_elements(i915->blitter, i915->velems);
+ util_blitter_save_vertex_buffer_slot(i915->blitter,
+ i915->vertex_buffers);
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ util_blitter_save_fragment_sampler_states(i915->blitter,
+ i915->num_samplers,
+ (void**)i915->fragment_sampler);
+ util_blitter_save_fragment_sampler_views(i915->blitter,
+ i915->num_fragment_sampler_views,
+ i915->fragment_sampler_views);
+}
+
+static void
+i915_surface_copy_render(struct pipe_context *pipe,
+ struct pipe_resource *dst, unsigned dst_level,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src, unsigned src_level,
+ const struct pipe_box *src_box)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ unsigned src_width0 = src->width0;
+ unsigned src_height0 = src->height0;
+ unsigned dst_width0 = dst->width0;
+ unsigned dst_height0 = dst->height0;
+ struct pipe_box dstbox;
+ struct pipe_sampler_view src_templ, *src_view;
+ struct pipe_surface dst_templ, *dst_view;
+ const struct util_format_description *desc;
+
+ /* Fallback for buffers. */
+ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER)
+ goto fallback;
+
+ /* Fallback for depth&stencil. XXX: see if we can use a proxy format */
+ desc = util_format_description(src->format);
+ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
+ goto fallback;
+
+ desc = util_format_description(dst->format);
+ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
+ goto fallback;
+
+ util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
+ util_blitter_default_src_texture(i915->blitter, &src_templ, src, src_level);
+
+ if (!util_blitter_is_copy_supported(i915->blitter, dst, src))
+ goto fallback;
+
+ i915_util_blitter_save_states(i915);
+
+ dst_view = i915_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0);
+ src_view = i915_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0);
+
+ u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height),
+ abs(src_box->depth), &dstbox);
+
+ util_blitter_blit_generic(i915->blitter, dst_view, &dstbox,
+ src_view, src_box, src_width0, src_height0,
+ PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
+ FALSE);
+ return;
+
+fallback:
+ util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
+ src, src_level, src_box);
+}
+
+static void
+i915_clear_render_target_render(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const union pipe_color_union *color,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ bool render_condition_enabled)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ struct pipe_framebuffer_state fb_state;
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 1;
+ fb_state.cbufs[0] = dst;
+ fb_state.zsbuf = NULL;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0,
+ dstx, dsty, width, height);
+
+ pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
+ util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
+ i915->blitter->saved_fb_state.nr_cbufs = ~0;
+}
+
+static void
+i915_clear_depth_stencil_render(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ bool render_condition_enabled)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ struct pipe_framebuffer_state fb_state;
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 0;
+ fb_state.zsbuf = dst;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL,
+ NULL, depth, stencil,
+ dstx, dsty, width, height);
+
+ pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
+ util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
+ i915->blitter->saved_fb_state.nr_cbufs = ~0;
+}
+
+/*
+ * surface functions using the blitter
+ */