summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2010-06-03 17:46:14 +0200
committerRoland Scheidegger <[email protected]>2010-06-03 17:46:14 +0200
commit992382762a74fd834926fd2c3cd9e14a186e2dd5 (patch)
treec4572bb01331b71931b3570b36a7acfc38f79a68 /src/gallium/drivers
parent05863c487756c1c9dc823cf639f77cad4111bd23 (diff)
parenta6e5c6c000df8655de3b41d5809547bb41c88c23 (diff)
Merge branch 'gallium-newclear'
Conflicts: src/gallium/state_trackers/python/p_context.i
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_surface.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.c3
-rw-r--r--src/gallium/drivers/i915/i915_blit.c4
-rw-r--r--src/gallium/drivers/i915/i915_blit.h1
-rw-r--r--src/gallium/drivers/i915/i915_clear.c2
-rw-r--r--src/gallium/drivers/i915/i915_screen.c9
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c1
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c1
-rw-r--r--src/gallium/drivers/i915/i915_surface.c83
-rw-r--r--src/gallium/drivers/i965/brw_pipe_clear.c74
-rw-r--r--src/gallium/drivers/i965/brw_resource.c1
-rw-r--r--src/gallium/drivers/i965/brw_screen.c3
-rw-r--r--src/gallium/drivers/identity/id_context.c76
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c33
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c83
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c30
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_surface.c38
-rw-r--r--src/gallium/drivers/r300/r300_blit.c38
-rw-r--r--src/gallium/drivers/r300/r300_screen.c3
-rw-r--r--src/gallium/drivers/rbug/rbug_context.c76
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_surface.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_blit.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_clear.c8
-rw-r--r--src/gallium/drivers/svga/svga_screen.c3
-rw-r--r--src/gallium/drivers/trace/tr_context.c78
35 files changed, 494 insertions, 196 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c
index 8000eee88a3..777454479b1 100644
--- a/src/gallium/drivers/cell/ppu/cell_surface.c
+++ b/src/gallium/drivers/cell/ppu/cell_surface.c
@@ -34,5 +34,4 @@ void
cell_init_surface_functions(struct cell_context *cell)
{
cell->pipe.resource_copy_region = util_resource_copy_region;
- cell->pipe.resource_fill_region = util_resource_fill_region;
}
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 2246c1468ca..9c9c1bdc452 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -146,6 +146,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.draw_arrays = failover_draw_arrays;
failover->pipe.draw_elements = failover_draw_elements;
failover->pipe.clear = hw->clear;
+ failover->pipe.clear_render_target = hw->clear_render_target;
+ failover->pipe.clear_depth_stencil = hw->clear_depth_stencil;
/* No software occlusion fallback (or other optional functionality)
* at this point - if the hardware doesn't support it, don't
@@ -157,7 +159,6 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover_init_state_functions( failover );
failover->pipe.resource_copy_region = hw->resource_copy_region;
- failover->pipe.resource_fill_region = hw->resource_fill_region;
#if 0
failover->pipe.texture_create = hw->texture_create;
diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c
index 6717e46e1b4..c5b5979bf98 100644
--- a/src/gallium/drivers/i915/i915_blit.c
+++ b/src/gallium/drivers/i915/i915_blit.c
@@ -36,6 +36,7 @@
void
i915_fill_blit(struct i915_context *i915,
unsigned cpp,
+ unsigned rgba_mask,
unsigned short dst_pitch,
struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
@@ -62,8 +63,7 @@ i915_fill_blit(struct i915_context *i915,
case 4:
BR13 = (((int) dst_pitch) & 0xffff) |
(0xF0 << 16) | (1 << 24) | (1 << 25);
- CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ CMD = (XY_COLOR_BLT_CMD | rgba_mask);
break;
default:
return;
diff --git a/src/gallium/drivers/i915/i915_blit.h b/src/gallium/drivers/i915/i915_blit.h
index 43f8e7c9aad..d82d2f258e1 100644
--- a/src/gallium/drivers/i915/i915_blit.h
+++ b/src/gallium/drivers/i915/i915_blit.h
@@ -44,6 +44,7 @@ extern void i915_copy_blit(struct i915_context *i915,
extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp,
+ unsigned rgba_mask,
unsigned short dst_pitch,
struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 0d0859f8f33..6d824a507aa 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -40,7 +40,7 @@
*/
void
i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
- double depth, unsigned stencil)
+ double depth, unsigned stencil)
{
util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth,
stencil);
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 62b064ccf81..f82426520cd 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -129,6 +129,9 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ /* disable for now */
+ return 0;
default:
return 0;
}
@@ -181,6 +184,9 @@ i915_is_format_supported(struct pipe_screen *screen,
PIPE_FORMAT_L8A8_UNORM,
PIPE_FORMAT_UYVY,
PIPE_FORMAT_YUYV,
+ /* XXX why not?
+ PIPE_FORMAT_Z16_UNORM, */
+ PIPE_FORMAT_Z24X8_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_FORMAT_NONE /* list terminator */
};
@@ -190,6 +196,9 @@ i915_is_format_supported(struct pipe_screen *screen,
PIPE_FORMAT_NONE /* list terminator */
};
static const enum pipe_format depth_supported[] = {
+ /* XXX why not?
+ PIPE_FORMAT_Z16_UNORM, */
+ PIPE_FORMAT_Z24X8_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_FORMAT_NONE /* list terminator */
};
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 4d069fffa85..22082fece82 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -51,6 +51,7 @@ static unsigned translate_format( enum pipe_format format )
static unsigned translate_depth_format( enum pipe_format zformat )
{
switch (zformat) {
+ case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return DEPTH_FRMT_24_FIXED_8_OTHER;
case PIPE_FORMAT_Z16_UNORM:
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index 73e61b66240..77b9bccbb74 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -222,6 +222,7 @@ translate_texture_format(enum pipe_format pipeFormat)
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
#endif
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ case PIPE_FORMAT_Z24X8_UNORM:
return (MAPSURF_32BIT | MT_32BIT_xI824);
default:
debug_printf("i915: translate_texture_format() bad image format %x\n",
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index 41b1fed36d0..7869be8f682 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -28,12 +28,14 @@
#include "i915_surface.h"
#include "i915_resource.h"
#include "i915_blit.h"
+#include "i915_reg.h"
#include "i915_screen.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_pack_color.h"
/* Assumes all values are within bounds -- no checking at this level -
@@ -41,11 +43,11 @@
*/
static void
i915_surface_copy(struct pipe_context *pipe,
- struct pipe_resource *dst, struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- struct pipe_resource *src, struct pipe_subresource subsrc,
- unsigned srcx, unsigned srcy, unsigned srcz,
- unsigned width, unsigned height)
+ struct pipe_resource *dst, struct pipe_subresource subdst,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src, struct pipe_subresource subsrc,
+ unsigned srcx, unsigned srcy, unsigned srcz,
+ unsigned width, unsigned height)
{
struct i915_texture *dst_tex = i915_texture(dst);
struct i915_texture *src_tex = i915_texture(src);
@@ -93,39 +95,67 @@ i915_surface_copy(struct pipe_context *pipe,
static void
-i915_surface_fill(struct pipe_context *pipe,
- struct pipe_resource *dst, struct pipe_subresource subdst,
- unsigned dstx, unsigned dsty, unsigned dstz,
- unsigned width, unsigned height, unsigned value)
+i915_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
- struct i915_texture *tex = i915_texture(dst);
+ struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
- unsigned dst_offset; /* in bytes */
-
- if (dst->target == PIPE_TEXTURE_CUBE) {
- dst_offset = tex->image_offset[subdst.level][subdst.face];
- }
- else if (dst->target == PIPE_TEXTURE_3D) {
- dst_offset = tex->image_offset[subdst.level][dstz];
- }
- else {
- dst_offset = tex->image_offset[subdst.level][0];
- assert(subdst.face == 0);
- assert(dstz == 0);
- }
+ union util_color uc;
assert(util_format_get_blockwidth(pt->format) == 1);
assert(util_format_get_blockheight(pt->format) == 1);
+ util_pack_color(rgba, dst->format, &uc);
i915_fill_blit( i915_context(pipe),
util_format_get_blocksize(pt->format),
+ XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB,
(unsigned short) tex->stride,
- tex->buffer, dst_offset,
+ tex->buffer, dst->offset,
(short) dstx, (short) dsty,
(short) width, (short) height,
- value );
+ uc.ui );
}
+static void
+i915_clear_depth_stencil(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct i915_texture *tex = i915_texture(dst->texture);
+ struct pipe_resource *pt = &tex->b.b;
+ unsigned packedds;
+ unsigned mask = 0;
+
+ assert(util_format_get_blockwidth(pt->format) == 1);
+ assert(util_format_get_blockheight(pt->format) == 1);
+
+ packedds = util_pack_z_stencil(dst->format, depth, stencil);
+
+ if (clear_flags & PIPE_CLEAR_DEPTH)
+ mask |= XY_COLOR_BLT_WRITE_RGB;
+ /* XXX presumably this does read-modify-write
+ (otherwise this won't work anyway). Hence will only want to
+ do it if really have stencil and it isn't cleared */
+ if (!((clear_flags & PIPE_CLEAR_STENCIL) ||
+ (dst->format != PIPE_FORMAT_Z24_UNORM_S8_USCALED)))
+ mask |= XY_COLOR_BLT_WRITE_ALPHA;
+
+ i915_fill_blit( i915_context(pipe),
+ util_format_get_blocksize(pt->format),
+ mask,
+ (unsigned short) tex->stride,
+ tex->buffer, dst->offset,
+ (short) dstx, (short) dsty,
+ (short) width, (short) height,
+ packedds );
+}
/*
* Screen surface functions
@@ -179,7 +209,8 @@ void
i915_init_surface_functions(struct i915_context *i915)
{
i915->base.resource_copy_region = i915_surface_copy;
- i915->base.resource_fill_region = i915_surface_fill;
+ i915->base.clear_render_target = i915_clear_render_target;
+ i915->base.clear_depth_stencil = i915_clear_depth_stencil;
}
/* No good reason for these to be in the screen.
diff --git a/src/gallium/drivers/i965/brw_pipe_clear.c b/src/gallium/drivers/i965/brw_pipe_clear.c
index abf507991e2..d5cff338a66 100644
--- a/src/gallium/drivers/i965/brw_pipe_clear.c
+++ b/src/gallium/drivers/i965/brw_pipe_clear.c
@@ -26,6 +26,7 @@
**************************************************************************/
#include "util/u_pack_color.h"
+#include "util/u_math.h"
#include "pipe/p_state.h"
@@ -42,12 +43,12 @@
* Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
* since that might include software renderbuffers or renderbuffers
* which we're clearing with triangles.
- * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear
*/
static enum pipe_error
try_clear( struct brw_context *brw,
struct brw_surface *surface,
- unsigned value )
+ unsigned value,
+ unsigned rgba_mask)
{
uint32_t BR13, CMD;
int x1 = 0;
@@ -67,12 +68,11 @@ try_clear( struct brw_context *brw,
x1, y1, x2 - x1, y2 - y1);
BR13 = 0xf0 << 16;
- CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA;
+ CMD = XY_COLOR_BLT_CMD | rgba_mask;
/* Setup the blit command */
if (cpp == 4) {
BR13 |= BR13_8888;
- CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
else {
assert(cpp == 2);
@@ -121,24 +121,36 @@ static void color_clear(struct brw_context *brw,
if (bsurface->cpp == 2)
value.ui |= value.ui << 16;
- ret = try_clear( brw, bsurface, value.ui );
+ ret = try_clear( brw, bsurface, value.ui,
+ XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA );
if (ret != 0) {
brw_context_flush( brw );
- ret = try_clear( brw, bsurface, value.ui );
+ ret = try_clear( brw, bsurface, value.ui,
+ XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA );
assert( ret == 0 );
}
}
-static void zstencil_clear(struct brw_context *brw,
+static void zstencil_clear(struct brw_context *brw,
struct brw_surface *bsurface,
+ unsigned clear_flags,
double depth,
unsigned stencil )
{
enum pipe_error ret;
unsigned value;
+ unsigned mask = 0;
+ union fi tmp;
+
+ if (clear_flags & PIPE_CLEAR_DEPTH)
+ mask |= XY_BLT_WRITE_RGB;
switch (bsurface->base.format) {
+ case PIPE_FORMAT_Z32_FLOAT:
+ tmp.f = (float)depth;
+ value = tmp.ui;
+ break;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
value = ((unsigned)(depth * MASK24) & MASK24);
@@ -152,24 +164,31 @@ static void zstencil_clear(struct brw_context *brw,
}
switch (bsurface->base.format) {
+ case PIPE_FORMAT_Z32_FLOAT:
+ mask |= XY_BLT_WRITE_ALPHA;
+ break;
case PIPE_FORMAT_Z24X8_UNORM:
+ value = value | (stencil << 24);
+ mask |= XY_BLT_WRITE_ALPHA;
+ break;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
value = value | (stencil << 24);
+ if (clear_flags & PIPE_CLEAR_STENCIL)
+ mask |= XY_BLT_WRITE_ALPHA;
break;
-
case PIPE_FORMAT_Z16_UNORM:
value = value | (value << 16);
+ mask |= XY_BLT_WRITE_ALPHA;
break;
-
default:
break;
}
- ret = try_clear( brw, bsurface, value );
+ ret = try_clear( brw, bsurface, value, mask );
if (ret != 0) {
brw_context_flush( brw );
- ret = try_clear( brw, bsurface, value );
+ ret = try_clear( brw, bsurface, value, mask );
assert( ret == 0 );
}
}
@@ -201,15 +220,48 @@ static void brw_clear(struct pipe_context *pipe,
if (brw->curr.fb.zsbuf) {
zstencil_clear( brw,
brw_surface(brw->curr.fb.zsbuf),
+ buffers & PIPE_CLEAR_DEPTHSTENCIL,
depth, stencil );
}
}
}
+/* XXX should respect region */
+static void brw_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct brw_context *brw = brw_context( pipe );
+
+ color_clear( brw,
+ brw_surface(dst),
+ rgba );
+}
+
+/* XXX should respect region */
+static void brw_clear_depth_stencil(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct brw_context *brw = brw_context( pipe );
+
+ zstencil_clear( brw,
+ brw_surface(dst),
+ clear_flags,
+ depth, stencil );
+}
void brw_pipe_clear_init( struct brw_context *brw )
{
brw->base.clear = brw_clear;
+ brw->base.clear_render_target = brw_clear_render_target;
+ brw->base.clear_depth_stencil = brw_clear_depth_stencil;
}
diff --git a/src/gallium/drivers/i965/brw_resource.c b/src/gallium/drivers/i965/brw_resource.c
index 1efdb1e0b4d..3b61ffbd035 100644
--- a/src/gallium/drivers/i965/brw_resource.c
+++ b/src/gallium/drivers/i965/brw_resource.c
@@ -39,7 +39,6 @@ brw_init_resource_functions(struct brw_context *brw )
brw->base.transfer_destroy = u_transfer_destroy_vtbl;
brw->base.transfer_inline_write = u_transfer_inline_write_vtbl;
brw->base.resource_copy_region = util_resource_copy_region;
- brw->base.resource_fill_region = util_resource_fill_region;
}
void
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 5a45687b090..50a446db917 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -188,6 +188,9 @@ brw_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ /* disable for now */
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 9813170fb18..898e0b3af83 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -649,33 +649,6 @@ identity_resource_copy_region(struct pipe_context *_pipe,
}
static void
-identity_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)
-{
- struct identity_context *id_pipe = identity_context(_pipe);
- struct identity_resource *id_resource_dst = identity_resource(_dst);
- struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_resource *dst = id_resource_dst->resource;
-
- pipe->resource_fill_region(pipe,
- dst,
- subdst,
- dstx,
- dsty,
- dstz,
- width,
- height,
- value);
-}
-
-static void
identity_clear(struct pipe_context *_pipe,
unsigned buffers,
const float *rgba,
@@ -693,6 +666,52 @@ identity_clear(struct pipe_context *_pipe,
}
static void
+identity_clear_render_target(struct pipe_context *_pipe,
+ struct pipe_surface *_dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct identity_surface *id_surface_dst = identity_surface(_dst);
+ struct pipe_context *pipe = id_pipe->pipe;
+ struct pipe_surface *dst = id_surface_dst->surface;
+
+ pipe->clear_render_target(pipe,
+ dst,
+ rgba,
+ dstx,
+ dsty,
+ width,
+ height);
+}
+static void
+identity_clear_depth_stencil(struct pipe_context *_pipe,
+ struct pipe_surface *_dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct identity_surface *id_surface_dst = identity_surface(_dst);
+ struct pipe_context *pipe = id_pipe->pipe;
+ struct pipe_surface *dst = id_surface_dst->surface;
+
+ pipe->clear_depth_stencil(pipe,
+ dst,
+ clear_flags,
+ depth,
+ stencil,
+ dstx,
+ dsty,
+ width,
+ height);
+
+}
+
+static void
identity_flush(struct pipe_context *_pipe,
unsigned flags,
struct pipe_fence_handle **fence)
@@ -913,8 +932,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.resource_copy_region = identity_resource_copy_region;
- id_pipe->base.resource_fill_region = identity_resource_fill_region;
id_pipe->base.clear = identity_clear;
+ id_pipe->base.clear_render_target = identity_clear_render_target;
+ id_pipe->base.clear_depth_stencil = identity_clear_depth_stencil;
id_pipe->base.flush = identity_flush;
id_pipe->base.is_resource_referenced = identity_is_resource_referenced;
id_pipe->base.create_sampler_view = identity_context_create_sampler_view;
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 386387b3a53..50e44dcb2b3 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -172,7 +172,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
if (zsbuf) {
struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
- if (scene->has_depth_clear)
+ if (scene->has_depthstencil_clear)
usage = LP_TEX_USAGE_WRITE_ALL;
else
usage = LP_TEX_USAGE_READ_WRITE;
@@ -264,6 +264,9 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
struct lp_rasterizer *rast = task->rast;
+ const struct lp_rast_clearzs *clearzs = arg.clear_zstencil;
+ unsigned clear_value = clearzs->clearzs_value;
+ unsigned clear_mask = clearzs->clearzs_mask;
const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
const unsigned block_size = rast->zsbuf.blocksize;
@@ -271,7 +274,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
uint8_t *dst;
unsigned i, j;
- LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
+ LP_DBG(DEBUG_RAST, "%s 0x%x%x\n", __FUNCTION__, clear_value, clear_mask);
/*
* Clear the aera of the swizzled depth/depth buffer matching this tile, in
@@ -287,22 +290,34 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
switch (block_size) {
case 1:
- memset(dst, (uint8_t) arg.clear_zstencil, height * width);
+ memset(dst, (uint8_t) clear_value, height * width);
break;
case 2:
for (i = 0; i < height; i++) {
uint16_t *row = (uint16_t *)dst;
for (j = 0; j < width; j++)
- *row++ = (uint16_t) arg.clear_zstencil;
+ *row++ = (uint16_t) clear_value;
dst += dst_stride;
}
break;
case 4:
- for (i = 0; i < height; i++) {
- uint32_t *row = (uint32_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = arg.clear_zstencil;
- dst += dst_stride;
+ if (clear_mask == 0xffffffff) {
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = clear_value;
+ dst += dst_stride;
+ }
+ }
+ else {
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++) {
+ uint32_t tmp = ~clear_mask & *row;
+ *row++ = (clear_value & clear_mask) | tmp;
+ }
+ dst += dst_stride;
+ }
}
break;
default:
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index ff0e3cfc73b..80ca68f5a2f 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -88,6 +88,11 @@ struct lp_rast_shader_inputs {
PIPE_ALIGN_VAR(16) int step[3][16];
};
+struct lp_rast_clearzs {
+ unsigned clearzs_value;
+ unsigned clearzs_mask;
+};
+
/**
* Rasterization information for a triangle known to be in this bin,
@@ -151,7 +156,7 @@ union lp_rast_cmd_arg {
const struct lp_rast_triangle *triangle;
const struct lp_rast_state *set_state;
uint8_t clear_color[4];
- unsigned clear_zstencil;
+ const struct lp_rast_clearzs *clear_zstencil;
struct lp_fence *fence;
struct llvmpipe_query *query_obj;
};
@@ -193,6 +198,14 @@ lp_rast_arg_fence( struct lp_fence *fence )
static INLINE union lp_rast_cmd_arg
+lp_rast_arg_clearzs( const struct lp_rast_clearzs *clearzs )
+{
+ union lp_rast_cmd_arg arg;
+ arg.clear_zstencil = clearzs;
+ return arg;
+}
+
+static INLINE union lp_rast_cmd_arg
lp_rast_arg_null( void )
{
union lp_rast_cmd_arg arg;
@@ -201,7 +214,6 @@ lp_rast_arg_null( void )
}
-
/**
* Binnable Commands.
* These get put into bins by the setup code and are called when
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 59e4c18ad05..845c175cf2e 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -201,7 +201,7 @@ lp_scene_reset(struct lp_scene *scene )
scene->scene_size = 0;
scene->has_color_clear = FALSE;
- scene->has_depth_clear = FALSE;
+ scene->has_depthstencil_clear = FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index 22d619fdbc3..4e55d431746 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -125,7 +125,7 @@ struct lp_scene {
unsigned scene_size;
boolean has_color_clear;
- boolean has_depth_clear;
+ boolean has_depthstencil_clear;
/**
* Number of active tiles in each dimension.
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 98ac11d76a4..2fc5d6ecff6 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -162,6 +162,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_VS_PREDS:
case PIPE_CAP_MAX_FS_PREDS:
return LP_MAX_TGSI_PREDS;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 1;
default:
assert(0);
return 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index bdb40a2d4b8..8556dc87b44 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -143,6 +143,7 @@ static void reset_context( struct lp_setup_context *setup )
/* Reset some state:
*/
setup->clear.flags = 0;
+ setup->clear.clearzs.clearzs_mask = 0;
/* Have an explicit "start-binning" call and get rid of this
* pointer twiddling?
@@ -172,10 +173,15 @@ static void
begin_binning( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ boolean need_zsload = FALSE;
+ if (setup->fb.zsbuf &&
+ ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
+ util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
+ need_zsload = TRUE;
LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
(setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
- (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load");
+ need_zsload ? "clear": "load");
if (setup->fb.nr_cbufs) {
if (setup->clear.flags & PIPE_CLEAR_COLOR) {
@@ -188,10 +194,11 @@ begin_binning( struct lp_setup_context *setup )
if (setup->fb.zsbuf) {
if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
- lp_scene_bin_everywhere( scene,
- lp_rast_clear_zstencil,
- setup->clear.zstencil );
- scene->has_depth_clear = TRUE;
+ if (!need_zsload)
+ scene->has_depthstencil_clear = TRUE;
+ lp_scene_bin_everywhere( scene,
+ lp_rast_clear_zstencil,
+ lp_rast_arg_clearzs(&setup->clear.clearzs) );
}
}
@@ -306,6 +313,8 @@ lp_setup_clear( struct lp_setup_context *setup,
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
unsigned i;
+ boolean full_zs_clear = TRUE;
+ uint32_t mask = 0;
LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
@@ -316,10 +325,53 @@ lp_setup_clear( struct lp_setup_context *setup,
}
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
- setup->clear.zstencil.clear_zstencil =
- util_pack_z_stencil(setup->fb.zsbuf->format,
- depth,
- stencil);
+ if (setup->fb.zsbuf &&
+ ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
+ util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
+ full_zs_clear = FALSE;
+
+ if (full_zs_clear) {
+ setup->clear.clearzs.clearzs_value =
+ util_pack_z_stencil(setup->fb.zsbuf->format,
+ depth,
+ stencil);
+ setup->clear.clearzs.clearzs_mask = 0xffffffff;
+ }
+ else {
+ /* hmm */
+ uint32_t tmpval;
+ if (flags & PIPE_CLEAR_DEPTH) {
+ tmpval = util_pack_z(setup->fb.zsbuf->format,
+ depth);
+ switch (setup->fb.zsbuf->format) {
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ mask = 0xffffff;
+ break;
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ mask = 0xffffff00;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ else {
+ switch (setup->fb.zsbuf->format) {
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ mask = 0xff000000;
+ tmpval = stencil << 24;
+ break;
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ mask = 0xff;
+ tmpval = stencil;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ setup->clear.clearzs.clearzs_mask |= mask;
+ setup->clear.clearzs.clearzs_value =
+ (setup->clear.clearzs.clearzs_value & ~mask) | (tmpval & mask);
+ }
}
if (setup->state == SETUP_ACTIVE) {
@@ -336,11 +388,16 @@ lp_setup_clear( struct lp_setup_context *setup,
scene->has_color_clear = TRUE;
}
- if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
- lp_scene_bin_everywhere( scene,
+ if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
+ if (full_zs_clear)
+ scene->has_depthstencil_clear = TRUE;
+ else
+ setup->clear.clearzs.clearzs_mask = mask;
+ lp_scene_bin_everywhere( scene,
lp_rast_clear_zstencil,
- setup->clear.zstencil );
- scene->has_depth_clear = TRUE;
+ lp_rast_arg_clearzs(&setup->clear.clearzs) );
+
+
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 584764ce8ac..c8b8a2480b0 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -97,7 +97,7 @@ struct lp_setup_context
struct {
unsigned flags;
union lp_rast_cmd_arg color; /**< lp_rast_clear_color() cmd */
- union lp_rast_cmd_arg zstencil; /**< lp_rast_clear_zstencil() cmd */
+ struct lp_rast_clearzs clearzs; /**< lp_rast_clear_zstencil() cmd */
} clear;
enum setup_state {
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 85687ada1c4..4f409f9b638 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -153,5 +153,4 @@ void
llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
{
lp->pipe.resource_copy_region = lp_resource_copy;
- lp->pipe.resource_fill_region = util_resource_fill_region;
}
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index 5447904e9ca..ee7cf281f4a 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -51,13 +51,15 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
mode |= 0x3c;
}
- if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ if (buffers & PIPE_CLEAR_DEPTH) {
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
OUT_RING (chan, fui(depth));
+ mode |= NV50TCL_CLEAR_BUFFERS_Z;
+ }
+ if (buffers & PIPE_CLEAR_STENCIL) {
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
OUT_RING (chan, stencil & 0xff);
-
- mode |= 0x03;
+ mode |= NV50TCL_CLEAR_BUFFERS_S;
}
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 2c0caada366..21908bcd3c2 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -150,6 +150,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 40b8d255335..5535610e0a2 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -27,6 +27,7 @@
#include "nv50_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
+#include "util/u_pack_color.h"
#include "util/u_tile.h"
#include "util/u_format.h"
@@ -221,50 +222,49 @@ nv50_surface_copy(struct pipe_context *pipe,
nv50_miptree_surface_del(ps_dst);
}
+/* XXX this should probably look more along the lines of nv50_clear */
static void
-nv50_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest,
- struct pipe_subresource subdst,
- unsigned destx, unsigned desty, unsigned destz,
- unsigned width, unsigned height, unsigned value)
+nv50_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct pipe_surface *ps;
struct nv50_screen *screen = nv50->screen;
struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
int format, ret;
+ union util_color uc;
+ util_pack_color(rgba, dst->format, &uc);
- format = nv50_format(dest->format);
+ format = nv50_format(dst->format);
if (format < 0)
return;
- ps = nv50_miptree_surface_new(pipe->screen, dest, subdst.face,
- subdst.level, destz, 0 /* bind flags */);
-
WAIT_RING (chan, 32);
- ret = nv50_surface_set(screen, ps, 1);
+ ret = nv50_surface_set(screen, dst, 1);
if (ret)
return;
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_SHAPE, 3);
OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES);
OUT_RING (chan, format);
- OUT_RING (chan, value);
+ OUT_RING (chan, uc.ui);
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_POINT32_X(0), 4);
- OUT_RING (chan, destx);
- OUT_RING (chan, desty);
+ OUT_RING (chan, dstx);
+ OUT_RING (chan, dsty);
OUT_RING (chan, width);
OUT_RING (chan, height);
- nv50_miptree_surface_del(ps);
}
void
nv50_init_surface_functions(struct nv50_context *nv50)
{
nv50->pipe.resource_copy_region = nv50_surface_copy;
- nv50->pipe.resource_fill_region = nv50_surface_fill;
+ nv50->pipe.clear_render_target = nv50_clear_render_target;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 7e534a0c738..a78d2411a05 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -80,6 +80,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/nvfx/nvfx_surface.c b/src/gallium/drivers/nvfx/nvfx_surface.c
index fc3a670d400..44e1af2e6a2 100644
--- a/src/gallium/drivers/nvfx/nvfx_surface.c
+++ b/src/gallium/drivers/nvfx/nvfx_surface.c
@@ -30,6 +30,7 @@
#include "nvfx_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
+#include "util/u_pack_color.h"
static void
nvfx_surface_copy(struct pipe_context *pipe,
@@ -55,26 +56,41 @@ nvfx_surface_copy(struct pipe_context *pipe,
}
static void
-nvfx_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest,
- struct pipe_subresource subdst,
- unsigned destx, unsigned desty, unsigned destz,
- unsigned width, unsigned height, unsigned value)
+nvfx_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
- struct pipe_surface *ps;
struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
+ union util_color uc;
+ util_pack_color(rgba, dst->format, &uc);
+
+ eng2d->fill(eng2d, dst, dstx, dsty, width, height, uc.ui);
+}
- ps = nvfx_miptree_surface_new(pipe->screen, dest, subdst.face,
- subdst.level, destz, 0 /* bind flags */);
-
- eng2d->fill(eng2d, ps, destx, desty, width, height, value);
+static void
+nvfx_clear_depth_stencil(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
- nvfx_miptree_surface_del(ps);
+ eng2d->fill(eng2d, dst, dstx, dsty, width, height,
+ util_pack_z_stencil(dst->format, depth, stencil));
}
+
void
nvfx_init_surface_functions(struct nvfx_context *nvfx)
{
nvfx->pipe.resource_copy_region = nvfx_surface_copy;
- nvfx->pipe.resource_fill_region = nvfx_surface_fill;
+ nvfx->pipe.clear_render_target = nvfx_clear_render_target;
+ nvfx->pipe.clear_depth_stencil = nvfx_clear_depth_stencil;
}
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 66ca4e0c180..49ec51fd132 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -188,26 +188,44 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
}
}
-/* Fill a region of a surface with a constant value. */
-static void r300_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)
+/* Clear a region of a color surface to a constant value. */
+static void r300_clear_render_target(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct r300_context *r300 = r300_context(pipe);
+
+ r300_blitter_save_states(r300);
+ util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
+
+ util_blitter_clear_render_target(r300->blitter, dst, rgba,
+ dstx, dsty, width, height);
+}
+
+/* Clear a region of a depth stencil surface. */
+static void r300_clear_depth_stencil(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct r300_context *r300 = r300_context(pipe);
r300_blitter_save_states(r300);
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
- util_blitter_fill_region(r300->blitter, dst, subdst,
- dstx, dsty, dstz, width, height, value);
+ util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil,
+ dstx, dsty, width, height);
}
void r300_init_blit_functions(struct r300_context *r300)
{
r300->context.clear = r300_clear;
+ r300->context.clear_render_target = r300_clear_render_target;
+ r300->context.clear_depth_stencil = r300_clear_depth_stencil;
r300->context.resource_copy_region = r300_resource_copy_region;
- r300->context.resource_fill_region = r300_resource_fill_region;
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 0be11ad017f..e7db074be62 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -147,6 +147,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
return 256;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 1;
+
/* Fragment coordinate conventions. */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
index bb7d13bfcd2..164d811ab48 100644
--- a/src/gallium/drivers/rbug/rbug_context.c
+++ b/src/gallium/drivers/rbug/rbug_context.c
@@ -800,33 +800,6 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
}
static void
-rbug_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)
-{
- struct rbug_context *rb_pipe = rbug_context(_pipe);
- struct rbug_resource *rb_resource_dst = rbug_resource(_dst);
- struct pipe_context *pipe = rb_pipe->pipe;
- struct pipe_resource *dst = rb_resource_dst->resource;
-
- pipe->resource_fill_region(pipe,
- dst,
- subdst,
- dstx,
- dsty,
- dstz,
- width,
- height,
- value);
-}
-
-static void
rbug_clear(struct pipe_context *_pipe,
unsigned buffers,
const float *rgba,
@@ -844,6 +817,52 @@ rbug_clear(struct pipe_context *_pipe,
}
static void
+rbug_clear_render_target(struct pipe_context *_pipe,
+ struct pipe_surface *_dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
+ struct pipe_context *pipe = rb_pipe->pipe;
+ struct pipe_surface *dst = rb_surface_dst->surface;
+
+ pipe->clear_render_target(pipe,
+ dst,
+ rgba,
+ dstx,
+ dsty,
+ width,
+ height);
+}
+
+static void
+rbug_clear_depth_stencil(struct pipe_context *_pipe,
+ struct pipe_surface *_dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
+ struct pipe_context *pipe = rb_pipe->pipe;
+ struct pipe_surface *dst = rb_surface_dst->surface;
+
+ pipe->clear_depth_stencil(pipe,
+ dst,
+ clear_flags,
+ depth,
+ stencil,
+ dstx,
+ dsty,
+ width,
+ height);
+}
+
+static void
rbug_flush(struct pipe_context *_pipe,
unsigned flags,
struct pipe_fence_handle **fence)
@@ -1075,8 +1094,9 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
- rb_pipe->base.resource_fill_region = rbug_resource_fill_region;
rb_pipe->base.clear = rbug_clear;
+ rb_pipe->base.clear_render_target = rbug_clear_render_target;
+ rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
rb_pipe->base.flush = rbug_flush;
rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced;
rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index bad57028526..cb59040395b 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -143,6 +143,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_FS_PREDS:
return TGSI_EXEC_NUM_PREDS;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index 0296c26ad26..99433f7d1d0 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -33,5 +33,4 @@ void
sp_init_surface_functions(struct softpipe_context *sp)
{
sp->pipe.resource_copy_region = util_resource_copy_region;
- sp->pipe.resource_fill_region = util_resource_fill_region;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
index 2dd99b46316..e742fec4a28 100644
--- a/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -108,5 +108,4 @@ void
svga_init_blit_functions(struct svga_context *svga)
{
svga->pipe.resource_copy_region = svga_surface_copy;
- svga->pipe.resource_fill_region = util_resource_fill_region;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index cbff95c9179..41f239c1a85 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -61,9 +61,11 @@ try_clear(struct svga_context *svga,
}
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
- flags |= SVGA3D_CLEAR_DEPTH;
+ if (buffers & PIPE_CLEAR_DEPTH)
+ flags |= SVGA3D_CLEAR_DEPTH;
- if (svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM)
+ if ((svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM) &&
+ (buffers & PIPE_CLEAR_STENCIL))
flags |= SVGA3D_CLEAR_STENCIL;
rect.w = MAX2(rect.w, fb->zsbuf->width);
@@ -100,7 +102,7 @@ svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
{
struct svga_context *svga = svga_context( pipe );
int ret;
-
+
if (buffers & PIPE_CLEAR_COLOR)
SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
svga_surface(svga->curr.framebuffer.cbufs[0])->handle);
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 3de04d05f8c..54d9faeb72a 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -230,6 +230,9 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_VS_PREDS:
return svgascreen->use_vs30 ? 1 : 0;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 1;
+
default:
return 0;
}
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 344a50b4620..9ca916fe7b4 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1085,61 +1085,88 @@ trace_context_resource_copy_region(struct pipe_context *_pipe,
static INLINE void
-trace_context_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)
+trace_context_clear(struct pipe_context *_pipe,
+ unsigned buffers,
+ const float *rgba,
+ double depth,
+ unsigned stencil)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
- dst = trace_resource_unwrap(tr_ctx, dst);
+ trace_dump_call_begin("pipe_context", "clear");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(uint, buffers);
+ trace_dump_arg_array(float, rgba, 4);
+ trace_dump_arg(float, depth);
+ trace_dump_arg(uint, stencil);
+
+ pipe->clear(pipe, buffers, rgba, depth, stencil);
+
+ trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_clear_render_target(struct pipe_context *_pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
- trace_dump_call_begin("pipe_context", "resource_fill_region");
+ dst = trace_surface_unwrap(tr_ctx, dst);
+
+ trace_dump_call_begin("pipe_context", "clear_render_target");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, dst);
- trace_dump_arg_struct(subresource, subdst);
+ trace_dump_arg_array(float, rgba, 4);
trace_dump_arg(uint, dstx);
trace_dump_arg(uint, dsty);
- trace_dump_arg(uint, dstz);
trace_dump_arg(uint, width);
trace_dump_arg(uint, height);
- trace_dump_arg(uint, value);
- pipe->resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz,
- width, height, value);
+ pipe->clear_render_target(pipe, dst, rgba, dstx, dsty, width, height);
trace_dump_call_end();
}
-
static INLINE void
-trace_context_clear(struct pipe_context *_pipe,
- unsigned buffers,
- const float *rgba,
- double depth,
- unsigned stencil)
+trace_context_clear_depth_stencil(struct pipe_context *_pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
- trace_dump_call_begin("pipe_context", "clear");
+ dst = trace_surface_unwrap(tr_ctx, dst);
+
+ trace_dump_call_begin("pipe_context", "clear_depth_stencil");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, buffers);
- trace_dump_arg_array(float, rgba, 4);
+ trace_dump_arg(ptr, dst);
+ trace_dump_arg(uint, clear_flags);
trace_dump_arg(float, depth);
trace_dump_arg(uint, stencil);
+ trace_dump_arg(uint, dstx);
+ trace_dump_arg(uint, dsty);
+ trace_dump_arg(uint, width);
+ trace_dump_arg(uint, height);
- pipe->clear(pipe, buffers, rgba, depth, stencil);
+ pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
+ dstx, dsty, width, height);
trace_dump_call_end();
}
-
static INLINE void
trace_context_flush(struct pipe_context *_pipe,
unsigned flags,
@@ -1451,8 +1478,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
tr_ctx->base.resource_copy_region = trace_context_resource_copy_region;
- tr_ctx->base.resource_fill_region = trace_context_resource_fill_region;
tr_ctx->base.clear = trace_context_clear;
+ tr_ctx->base.clear_render_target = trace_context_clear_render_target;
+ tr_ctx->base.clear_depth_stencil = trace_context_clear_depth_stencil;
tr_ctx->base.flush = trace_context_flush;
tr_ctx->base.is_resource_referenced = trace_is_resource_referenced;