aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/svga/svga_pipe_clear.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga/svga_pipe_clear.c')
-rw-r--r--src/gallium/drivers/svga/svga_pipe_clear.c135
1 files changed, 125 insertions, 10 deletions
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index c4edced9bae..bab61780610 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -34,6 +34,78 @@
#include "svga_surface.h"
+/**
+ * Clear the whole color buffer(s) by drawing a quad. For VGPU10 we use
+ * this when clearing integer render targets. We'll also clear the
+ * depth and/or stencil buffers if the clear_buffers mask specifies them.
+ */
+static void
+clear_buffers_with_quad(struct svga_context *svga,
+ unsigned clear_buffers,
+ const union pipe_color_union *color,
+ double depth, unsigned stencil)
+{
+ const struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
+
+ 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.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_clear(svga->blitter,
+ fb->width, fb->height,
+ 1, /* num_layers */
+ clear_buffers, color,
+ depth, stencil);
+}
+
+
+/**
+ * Check if any of the color buffers are integer buffers.
+ */
+static boolean
+is_integer_target(struct pipe_framebuffer_state *fb, unsigned buffers)
+{
+ unsigned i;
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ if ((buffers & (PIPE_CLEAR_COLOR0 << i)) &&
+ fb->cbufs[i] &&
+ util_format_is_pure_integer(fb->cbufs[i]->format)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ * Check if the integer values in the clear color can be represented
+ * by floats. If so, we can use the VGPU10 ClearRenderTargetView command.
+ * Otherwise, we need to clear with a quad.
+ */
+static boolean
+ints_fit_in_floats(const union pipe_color_union *color)
+{
+ const int max = 1 << 24;
+ return (color->i[0] <= max &&
+ color->i[1] <= max &&
+ color->i[2] <= max &&
+ color->i[3] <= max);
+}
+
+
static enum pipe_error
try_clear(struct svga_context *svga,
unsigned buffers,
@@ -52,7 +124,7 @@ try_clear(struct svga_context *svga,
if (ret != PIPE_OK)
return ret;
- if (svga->rebind.rendertargets) {
+ if (svga->rebind.flags.rendertargets) {
ret = svga_reemit_framebuffer_bindings(svga);
if (ret != PIPE_OK) {
return ret;
@@ -71,29 +143,72 @@ try_clear(struct svga_context *svga,
if (buffers & PIPE_CLEAR_DEPTH)
flags |= SVGA3D_CLEAR_DEPTH;
- if ((svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) &&
- (buffers & PIPE_CLEAR_STENCIL))
+ if (buffers & PIPE_CLEAR_STENCIL)
flags |= SVGA3D_CLEAR_STENCIL;
rect.w = MAX2(rect.w, fb->zsbuf->width);
rect.h = MAX2(rect.h, fb->zsbuf->height);
}
- if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
+ if (!svga_have_vgpu10(svga) &&
+ !svga_rects_equal(&rect, &svga->state.hw_clear.viewport)) {
restore_viewport = TRUE;
ret = SVGA3D_SetViewport(svga->swc, &rect);
if (ret != PIPE_OK)
return ret;
}
- ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui[0], (float) depth, stencil,
- rect.x, rect.y, rect.w, rect.h);
- if (ret != PIPE_OK)
- return ret;
+ if (svga_have_vgpu10(svga)) {
+ if (flags & SVGA3D_CLEAR_COLOR) {
+ unsigned i;
+
+ if (is_integer_target(fb, buffers) && !ints_fit_in_floats(color)) {
+ clear_buffers_with_quad(svga, buffers, color, depth, stencil);
+ /* We also cleared depth/stencil, so that's done */
+ flags &= ~(SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL);
+ }
+ else {
+ struct pipe_surface *rtv;
+
+ /* Issue VGPU10 Clear commands */
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ if ((fb->cbufs[i] == NULL) ||
+ !(buffers & (PIPE_CLEAR_COLOR0 << i)))
+ continue;
+
+ rtv = svga_validate_surface_view(svga,
+ svga_surface(fb->cbufs[i]));
+ if (rtv == NULL)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc,
+ rtv, color->f);
+ if (ret != PIPE_OK)
+ return ret;
+ }
+ }
+ }
+ if (flags & (SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL)) {
+ struct pipe_surface *dsv =
+ svga_validate_surface_view(svga, svga_surface(fb->zsbuf));
+ if (dsv == NULL)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, flags,
+ stencil, (float) depth);
+ if (ret != PIPE_OK)
+ return ret;
+ }
+ }
+ else {
+ ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui[0], (float) depth, stencil,
+ rect.x, rect.y, rect.w, rect.h);
+ if (ret != PIPE_OK)
+ return ret;
+ }
if (restore_viewport) {
- memcpy(&rect, &svga->state.hw_clear.viewport, sizeof rect);
- ret = SVGA3D_SetViewport(svga->swc, &rect);
+ ret = SVGA3D_SetViewport(svga->swc, &svga->state.hw_clear.viewport);
}
return ret;