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_tessctrl_shader(svga->blitter, svga->curr.tcs);
+ util_blitter_save_tesseval_shader(svga->blitter, svga->curr.tes);
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_viewport(svga->blitter, &svga->curr.viewport[0]);
+ util_blitter_save_scissor(svga->blitter, &svga->curr.scissor[0]);
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,
fb->width, fb->height,
1, /* num_layers */
clear_buffers, color,
- depth, stencil);
+ depth, stencil,
+ util_framebuffer_get_num_samples(fb) > 1);
}
* Clear the given surface to the specified value.
* No masking, no scissor (clear entire buffer).
*/
-void
-svga_clear(struct pipe_context *pipe, unsigned buffers,
+static void
+svga_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scissor_state *scissor_state,
const union pipe_color_union *color,
double depth, unsigned stencil)
{
/* flush any queued prims (don't want them to appear after the clear!) */
svga_hwtnl_flush_retry(svga);
- ret = try_clear( svga, buffers, color, depth, stencil );
-
- if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
- /* Flush command buffer and retry:
- */
- svga_context_flush( svga, NULL );
-
- ret = try_clear( svga, buffers, color, depth, stencil );
- }
+ SVGA_RETRY_OOM(svga, ret, try_clear( svga, buffers, color, depth, stencil));
/*
* Mark target surfaces as dirty
{
struct svga_context *svga = svga_context(pipe);
struct svga_surface *svga_surface_dst;
- enum pipe_error ret;
struct pipe_surface tmpl;
struct pipe_surface *surface;
stencil = 0;
}
else {
- desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
- desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+ util_format_unpack_z_float(surface->format, &depth, data, 1);
+ util_format_unpack_s_8uint(surface->format, &stencil, data, 1);
}
if (util_format_has_depth(desc)) {
struct pipe_surface *dsv =
svga_validate_surface_view(svga, svga_surface_dst);
- if (!dsv)
+ if (!dsv) {
+ pipe_surface_reference(&surface, NULL);
return;
+ }
if (box->x == 0 && box->y == 0 && box->width == surface->width &&
box->height == surface->height) {
/* clearing whole surface, use direct VGPU10 command */
- ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv,
- clear_flags,
- stencil, depth);
- if (ret != PIPE_OK) {
- /* flush and try again */
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv,
- clear_flags,
- stencil, depth);
- assert(ret == PIPE_OK);
- }
+ SVGA_RETRY(svga, SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv,
+ clear_flags,
+ stencil, depth));
}
else {
/* To clear subtexture use software fallback */
color.f[0] = color.f[1] = color.f[2] = color.f[3] = 0;
}
else {
- if (util_format_is_pure_sint(surface->format)) {
- /* signed integer */
- desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1);
- }
- else if (util_format_is_pure_uint(surface->format)) {
- /* unsigned integer */
- desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1);
- }
- else {
- /* floating point */
- desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1);
- }
+ util_format_unpack_rgba(surface->format, &color, data, 1);
}
/* Setup render target view */
struct pipe_surface *rtv =
svga_validate_surface_view(svga, svga_surface_dst);
- if (!rtv)
+ if (!rtv) {
+ pipe_surface_reference(&surface, NULL);
return;
+ }
if (box->x == 0 && box->y == 0 && box->width == surface->width &&
box->height == surface->height) {
}
else {
/* clearing whole surface using VGPU10 command */
- ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv,
- color.f);
- if (ret != PIPE_OK) {
- svga_context_flush(svga,NULL);
- ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv,
- color.f);
- assert(ret == PIPE_OK);
- }
+ SVGA_RETRY(svga, SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv,
+ color.f));
}
}
else {
pipe->screen->is_format_supported(pipe->screen, rtv->format,
rtv->texture->target,
rtv->texture->nr_samples,
+ rtv->texture->nr_storage_samples,
PIPE_BIND_RENDER_TARGET)) {
/* clear with quad drawing */
util_blitter_save_framebuffer(svga->blitter,
}
}
}
+ pipe_surface_reference(&surface, NULL);
}
+/**
+ * \brief Clear the whole render target using vgpu10 functionality
+ *
+ * \param svga[in] The svga context
+ * \param dst[in] The surface to clear
+ * \param color[in] Clear color
+ * \return PIPE_OK if all well, PIPE_ERROR_OUT_OF_MEMORY if ran out of
+ * command submission resources.
+ */
+static enum pipe_error
+svga_try_clear_render_target(struct svga_context *svga,
+ struct pipe_surface *dst,
+ const union pipe_color_union *color)
+{
+ struct pipe_surface *rtv =
+ svga_validate_surface_view(svga, svga_surface(dst));
+
+ if (!rtv)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ return SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, color->f);
+ }
+
+/**
+ * \brief Clear part of render target using gallium blitter utilities
+ *
+ * \param svga[in] The svga context
+ * \param dst[in] The surface to clear
+ * \param color[in] Clear color
+ * \param dstx[in] Clear region left
+ * \param dsty[in] Clear region top
+ * \param width[in] Clear region width
+ * \param height[in] Clear region height
+ */
+static void
+svga_blitter_clear_render_target(struct svga_context *svga,
+ struct pipe_surface *dst,
+ const union pipe_color_union *color,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ begin_blit(svga);
+ util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer);
+
+ util_blitter_clear_render_target(svga->blitter, dst, color,
+ dstx, dsty, width, height);
+}
+
+
+/**
+ * \brief Clear render target pipe callback
+ *
+ * \param pipe[in] The pipe context
+ * \param dst[in] The surface to clear
+ * \param color[in] Clear color
+ * \param dstx[in] Clear region left
+ * \param dsty[in] Clear region top
+ * \param width[in] Clear region width
+ * \param height[in] Clear region height
+ * \param render_condition_enabled[in] Whether to use conditional rendering
+ * to clear (if elsewhere enabled).
+ */
+static void
+svga_clear_render_target(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 svga_context *svga = svga_context( pipe );
+
+ svga_toggle_render_condition(svga, render_condition_enabled, FALSE);
+ if (!svga_have_vgpu10(svga) || dstx != 0 || dsty != 0 ||
+ width != dst->width || height != dst->height) {
+ svga_blitter_clear_render_target(svga, dst, color, dstx, dsty, width,
+ height);
+ } else {
+ enum pipe_error ret;
+
+ SVGA_RETRY_OOM(svga, ret, svga_try_clear_render_target(svga, dst,
+ color));
+ assert (ret == PIPE_OK);
+ }
+ svga_toggle_render_condition(svga, render_condition_enabled, TRUE);
+}
void svga_init_clear_functions(struct svga_context *svga)
{
+ svga->pipe.clear_render_target = svga_clear_render_target;
svga->pipe.clear_texture = svga_clear_texture;
+ svga->pipe.clear = svga_clear;
}