summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c126
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h31
-rw-r--r--src/gallium/auxiliary/util/u_clear.h27
-rw-r--r--src/gallium/auxiliary/util/u_surface.c52
-rw-r--r--src/gallium/auxiliary/util/u_surface.h10
5 files changed, 151 insertions, 95 deletions
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index bcd5686470..183ffe5670 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -26,8 +26,8 @@
/**
* @file
- * Blitter utility to facilitate acceleration of the clear, resource_copy_region,
- * and resource_fill_region functions.
+ * Blitter utility to facilitate acceleration of the clear, clear_render_target, clear_depth_stencil
+ * resource_copy_region functions.
*
* @author Marek Olšák
*/
@@ -88,6 +88,7 @@ struct blitter_context_priv
void *dsa_write_depth_stencil;
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
+ void *dsa_keep_depth_write_stencil;
void *velem_state;
@@ -161,8 +162,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
dsa.stencil[0].writemask = 0xff;
ctx->dsa_write_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
- /* The DSA state objects which write depth and stencil are created
- * on-demand. */
+
+
+ dsa.depth.enabled = 0;
+ dsa.depth.writemask = 0;
+ ctx->dsa_keep_depth_write_stencil =
+ pipe->create_depth_stencil_alpha_state(pipe, &dsa);
/* sampler state */
sampler_state = &ctx->template_sampler_state;
@@ -234,6 +239,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
+ pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col);
@@ -596,11 +602,19 @@ void util_blitter_clear(struct blitter_context *blitter,
else
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
- if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->set_stencil_ref(pipe, &sr);
}
+ else if (clear_buffers & PIPE_CLEAR_DEPTH) {
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
+ }
+ else if (clear_buffers & PIPE_CLEAR_STENCIL) {
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
+ pipe->set_stencil_ref(pipe, &sr);
+ }
else
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
@@ -757,48 +771,21 @@ void util_blitter_copy_region(struct blitter_context *blitter,
pipe_surface_reference(&dstsurf, NULL);
}
-/* Fill a region of a surface with a constant value. */
-void util_blitter_fill_region(struct blitter_context *blitter,
- struct pipe_resource *dst,
- struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- unsigned width, unsigned height,
- unsigned value)
+/* Clear a region of a color surface to a constant value. */
+void util_blitter_clear_render_target(struct blitter_context *blitter,
+ struct pipe_surface *dstsurf,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *dstsurf;
struct pipe_framebuffer_state fb_state;
- float rgba[4];
- ubyte ub_rgba[4] = {0};
- union util_color color;
- int i;
- assert(dst);
- if (!dst)
+ assert(dstsurf->texture);
+ if (!dstsurf->texture)
return;
- /* check if we can render to the surface */
- if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
- !screen->is_format_supported(screen, dst->format, dst->target,
- dst->nr_samples,
- PIPE_BIND_RENDER_TARGET, 0)) {
- util_resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz,
- width, height, value);
- return;
- }
-
- dstsurf = screen->get_tex_surface(screen, dst, subdst.face, subdst.level,
- dstz, PIPE_BIND_RENDER_TARGET);
-
- /* unpack the color */
- color.ui = value;
- util_unpack_color_ub(dst->format, &color,
- ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
- for (i = 0; i < 4; i++)
- rgba[i] = ubyte_to_float(ub_rgba[i]);
-
/* check the saved state */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
@@ -823,6 +810,63 @@ void util_blitter_fill_region(struct blitter_context *blitter,
blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, 0);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
+}
- pipe_surface_reference(&dstsurf, NULL);
+/* Clear a region of a depth stencil surface. */
+void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
+ struct pipe_surface *dstsurf,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_framebuffer_state fb_state;
+ struct pipe_stencil_ref sr = { { 0 } };
+
+ assert(dstsurf->texture);
+ if (!dstsurf->texture)
+ return;
+
+ /* check the saved state */
+ blitter_check_saved_CSOs(ctx);
+ assert(blitter->saved_fb_state.nr_cbufs != ~0);
+
+ /* bind CSOs */
+ pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+ if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
+ pipe->set_stencil_ref(pipe, &sr);
+ }
+ else if (clear_flags & PIPE_CLEAR_DEPTH) {
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
+ }
+ else if (clear_flags & PIPE_CLEAR_STENCIL) {
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
+ pipe->set_stencil_ref(pipe, &sr);
+ }
+ else
+ /* hmm that should be illegal probably, or make it a no-op somewhere */
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+
+ pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
+ pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
+
+ /* set a framebuffer state */
+ fb_state.width = dstsurf->width;
+ fb_state.height = dstsurf->height;
+ fb_state.nr_cbufs = 0;
+ fb_state.cbufs[0] = 0;
+ fb_state.zsbuf = dstsurf;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, depth);
+ blitter_draw_quad(ctx);
+ blitter_restore_CSOs(ctx);
}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index ef1e6b3449..10143a5e0f 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -123,22 +123,33 @@ void util_blitter_copy_region(struct blitter_context *blitter,
boolean ignore_stencil);
/**
- * Fill a region of a surface with a constant value.
- *
- * If the surface cannot be rendered to or it's a depth-stencil format,
- * a software fallback path is taken.
+ * Clear a region of a (color) surface to a constant value.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - framebuffer state
*/
-void util_blitter_fill_region(struct blitter_context *blitter,
- struct pipe_resource *dst,
- struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- unsigned width, unsigned height,
- unsigned value);
+void util_blitter_clear_render_target(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height);
+/**
+ * Clear a region of a depth-stencil surface, both stencil and depth
+ * or only one of them if this is a combined depth-stencil surface.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - framebuffer state
+ */
+void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height);
/* The functions below should be used to save currently bound constant state
* objects inside a driver. The objects are automatically restored at the end
diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h
index 31f7fb2169..ad69df3f89 100644
--- a/src/gallium/auxiliary/util/u_clear.h
+++ b/src/gallium/auxiliary/util/u_clear.h
@@ -31,9 +31,6 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "util/u_pack_color.h"
-#include "util/u_rect.h"
-#include "util/u_surface.h"
/**
@@ -46,25 +43,17 @@ util_clear(struct pipe_context *pipe,
const float *rgba, double depth, unsigned stencil)
{
if (buffers & PIPE_CLEAR_COLOR) {
- struct pipe_surface *ps = framebuffer->cbufs[0];
- struct pipe_subresource subdst;
- union util_color uc;
-
- subdst.face = ps->face;
- subdst.level = ps->level;
- util_pack_color(rgba, ps->format, &uc);
- pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
- ps->width, ps->height, uc.ui);
+ unsigned i;
+ for (i = 0; i < framebuffer->nr_cbufs; i++) {
+ struct pipe_surface *ps = framebuffer->cbufs[i];
+ pipe->clear_render_target(pipe, ps, rgba, 0, 0, ps->width, ps->height);
+ }
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
struct pipe_surface *ps = framebuffer->zsbuf;
- struct pipe_subresource subdst;
-
- subdst.face = ps->face;
- subdst.level = ps->level;
- pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
- ps->width, ps->height,
- util_pack_z_stencil(ps->format, depth, stencil));
+ pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL,
+ depth, stencil,
+ 0, 0, ps->width, ps->height);
}
}
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 9adf22c471..9dd1002f5f 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -40,6 +40,7 @@
#include "util/u_inlines.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
+#include "util/u_pack_color.h"
/**
@@ -195,26 +196,33 @@ util_resource_copy_region(struct pipe_context *pipe,
/**
- * Fallback for pipe->resource_fill_region() function.
+ * Fallback for pipe->clear_render_target() function.
+ * XXX this looks too hackish to be really useful.
+ * cpp > 4 looks like a gross hack at best...
+ * and we're missing the equivalent clear_depth_stencil fallback.
+ * Plus can't use these transfer fallbacks when clearing
+ * multisampled surfaces for instance.
*/
void
-util_resource_fill_region(struct pipe_context *pipe,
- struct pipe_resource *dst,
- struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- unsigned width, unsigned height, unsigned value)
+util_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct pipe_transfer *dst_trans;
void *dst_map;
+ union util_color uc;
- assert(dst);
- if (!dst)
+ assert(dst->texture);
+ if (!dst->texture)
return;
+ util_pack_color(rgba, dst->texture->format, &uc);
dst_trans = pipe_get_transfer(pipe,
- dst,
- subdst.face,
- subdst.level,
- dstz,
+ dst->texture,
+ dst->face,
+ dst->level,
+ dst->zslice,
PIPE_TRANSFER_WRITE,
dstx, dsty, width, height);
@@ -225,22 +233,26 @@ util_resource_fill_region(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
- switch (util_format_get_blocksize(dst->format)) {
+ switch (util_format_get_blocksize(dst->texture->format)) {
case 1:
case 2:
case 4:
- util_fill_rect(dst_map, dst->format,
- dst_trans->stride,
- 0, 0, width, height, value);
+ util_pack_color(rgba, dst->texture->format, &uc);
+ util_fill_rect(dst_map, dst->texture->format,
+ dst_trans->stride,
+ 0, 0, width, height, uc.ui);
break;
case 8:
{
/* expand the 4-byte clear value to an 8-byte value */
+ /* should probably not convert back from ubyte but not
+ sure what this code really achieved since it doesn't even
+ check for format type... */
ushort *row = (ushort *) dst_map;
- ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
- ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
- ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
- ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+ ushort val0 = UBYTE_TO_USHORT((uc.ui >> 0) & 0xff);
+ ushort val1 = UBYTE_TO_USHORT((uc.ui >> 8) & 0xff);
+ ushort val2 = UBYTE_TO_USHORT((uc.ui >> 16) & 0xff);
+ ushort val3 = UBYTE_TO_USHORT((uc.ui >> 24) & 0xff);
unsigned i, j;
val0 = (val0 << 8) | val0;
val1 = (val1 << 8) | val1;
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index ccde738ca4..d8fb9f1d6f 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -57,11 +57,11 @@ util_resource_copy_region(struct pipe_context *pipe,
unsigned w, unsigned h);
extern void
-util_resource_fill_region(struct pipe_context *pipe,
- struct pipe_resource *dst,
- struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- unsigned width, unsigned height, unsigned value);
+util_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height);