diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h new file mode 100644 index 00000000000..7c16b32cf9f --- /dev/null +++ b/src/gallium/auxiliary/util/u_clear.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Michel Dänzer + */ + + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "util/u_pack_color.h" + + +/** + * Clear the given buffers to the specified values. + * No masking, no scissor (clear entire buffer). + */ +static INLINE void +util_clear(struct pipe_context *pipe, + struct pipe_framebuffer_state *framebuffer, unsigned buffers, + const float *rgba, double depth, unsigned stencil) +{ + if (buffers & PIPE_CLEAR_COLOR) { + struct pipe_surface *ps = framebuffer->cbufs[0]; + unsigned color; + + util_pack_color(rgba, ps->format, &color); + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + } + + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + struct pipe_surface *ps = framebuffer->zsbuf; + + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); + } +} diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index e05d0322532..4ec7aee192b 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -448,17 +448,19 @@ util_pack_z(enum pipe_format format, double z) static INLINE uint util_pack_z_stencil(enum pipe_format format, double z, uint s) { + unsigned packed = util_pack_z(format, z); + switch (format) { case PIPE_FORMAT_S8Z24_UNORM: - return util_pack_z(format, z) | s << 24; + packed |= s << 24; + break; case PIPE_FORMAT_Z24S8_UNORM: - return util_pack_z(format, z) | s; + packed |= s; default: - debug_print_format("gallium: unhandled format in util_pack_z_stencil()", - format); - assert(0); - return 0; + break; } + + return packed; } diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c index cde69daacc0..90530f2826f 100644 --- a/src/gallium/drivers/i915simple/i915_clear.c +++ b/src/gallium/drivers/i915simple/i915_clear.c @@ -25,23 +25,24 @@ * **************************************************************************/ -/* Author: +/* Authors: * Brian Paul */ -#include "pipe/p_defines.h" +#include "util/u_clear.h" #include "i915_context.h" #include "i915_state.h" /** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). */ void -i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 3cdabe45f9d..b6983ba86e7 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -314,8 +314,8 @@ void i915_emit_hardware_state(struct i915_context *i915 ); /*********************************************************************** * i915_clear.c: */ -void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); /*********************************************************************** diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c index be7e09cf4b0..a39a2b5f525 100644 --- a/src/gallium/drivers/nv10/nv10_clear.c +++ b/src/gallium/drivers/nv10/nv10_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv10_context.h" void -nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index f3b56de25a7..f1e003c9537 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -118,8 +118,9 @@ extern void nv10_init_surface_functions(struct nv10_context *nv10); extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); + /* nv10_draw.c */ extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c index 81b6f3e78ac..2b4490fa5e1 100644 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ b/src/gallium/drivers/nv20/nv20_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv20_context.h" void -nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h index 8ad926db20a..fc932f1f90e 100644 --- a/src/gallium/drivers/nv20/nv20_context.h +++ b/src/gallium/drivers/nv20/nv20_context.h @@ -118,8 +118,8 @@ extern void nv20_init_surface_functions(struct nv20_context *nv20); extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv20_clear.c */ -extern void nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv20_draw.c */ extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c index 71f413588ee..c4ba9266647 100644 --- a/src/gallium/drivers/nv30/nv30_clear.c +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv30_context.h" void -nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, &nv30_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index b9337697008..4229c0a0e14 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -206,7 +206,7 @@ extern boolean nv30_draw_elements(struct pipe_context *pipe, unsigned count); /* nv30_clear.c */ -extern void nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c index 2c4e8f01fda..ddf13addf3b 100644 --- a/src/gallium/drivers/nv40/nv40_clear.c +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv40_context.h" void -nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, &nv40_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index adcfbdd85a8..97bc83292d4 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -227,7 +227,7 @@ extern boolean nv40_draw_elements(struct pipe_context *pipe, unsigned count); /* nv40_clear.c */ -extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 313e435e7a5..7b67a754397 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -184,8 +184,8 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ -extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv50_program.c */ extern void nv50_vertprog_validate(struct nv50_context *nv50); diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index a60c6c4c16f..f72c6c63e76 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -2,6 +2,7 @@ * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. + * Copyright 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -27,6 +28,7 @@ /* Author: * Brian Paul + * Michel Dänzer */ @@ -40,34 +42,15 @@ /** - * Convert packed pixel from one format to another. - */ -static unsigned -convert_color(enum pipe_format srcFormat, unsigned srcColor, - enum pipe_format dstFormat) -{ - ubyte r, g, b, a; - unsigned dstColor; - - util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a); - util_pack_color_ub(r, g, b, a, dstFormat, &dstColor); - - return dstColor; -} - - - -/** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). - * Note: when clearing a color buffer, the clearValue is always - * encoded as PIPE_FORMAT_A8R8G8B8_UNORM. */ void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned cv; uint i; if (softpipe->no_rast) @@ -77,29 +60,29 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, softpipe_update_derived(softpipe); /* not needed?? */ #endif - if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { - sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); -#if TILE_CLEAR_OPTIMIZATION - return; -#endif - } + if (buffers & PIPE_CLEAR_COLOR) { + for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { + struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { - if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { - unsigned cv; - if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) { - cv = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue, - ps->format); - } - else { - cv = clearValue; - } + util_pack_color(rgba, ps->format, &cv); sp_tile_cache_clear(softpipe->cbuf_cache[i], cv); + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); +#endif } } + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; + + cv = util_pack_z_stencil(ps->format, depth, stencil); + sp_tile_cache_clear(softpipe->zsbuf_cache, cv); + #if !TILE_CLEAR_OPTIMIZATION - /* non-cached surface */ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); #endif + } } diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h index a8ed1c4ecc4..2e450672f58 100644 --- a/src/gallium/drivers/softpipe/sp_clear.h +++ b/src/gallium/drivers/softpipe/sp_clear.h @@ -36,8 +36,8 @@ struct pipe_context; extern void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); #endif /* SP_CLEAR_H */ diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index b69ed2cb526..6e86a5dfddf 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -973,21 +973,26 @@ trace_context_surface_fill(struct pipe_context *_pipe, static INLINE void trace_context_clear(struct pipe_context *_pipe, - struct pipe_surface *surface, - unsigned clearValue) + unsigned surfaces, + const float *rgba, + double depth, + unsigned stencil) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - surface = trace_surface_unwrap(tr_ctx, surface); - trace_dump_call_begin("pipe_context", "clear"); trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, surface); - trace_dump_arg(uint, clearValue); + trace_dump_arg(uint, surfaces); + trace_dump_arg(float, rgba[0]); + trace_dump_arg(float, rgba[1]); + trace_dump_arg(float, rgba[2]); + trace_dump_arg(float, rgba[3]); + trace_dump_arg(float, depth); + trace_dump_arg(uint, stencil); - pipe->clear(pipe, surface, clearValue);; + pipe->clear(pipe, surfaces, rgba, depth, stencil); trace_dump_call_end(); } diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 2452bf3522b..29095dcdc3b 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -205,12 +205,20 @@ struct pipe_context { unsigned dstx, unsigned dsty, unsigned width, unsigned height, unsigned value); - - void (*clear)(struct pipe_context *pipe, - struct pipe_surface *ps, - unsigned clearValue); /*@}*/ + /** + * Clear the specified set of currently bound buffers to specified values. + * + * buffers is a bitfield of PIPE_CLEAR_* values. + * + * rgba is a pointer to an array of one float for each of r, g, b, a. + */ + void (*clear)(struct pipe_context *pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil); /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8e4f253359a..81defa445bf 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -185,6 +185,15 @@ enum pipe_texture_target { #define PIPE_SURFACE_LAYOUT_LINEAR 0 +/** + * Clear buffer bits + */ +/** All color buffers currently bound */ +#define PIPE_CLEAR_COLOR (1 << 0) +/** Depth/stencil combined */ +#define PIPE_CLEAR_DEPTHSTENCIL (1 << 1) + + /** * Transfer object usage flags */ diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c index b61b49a2f8a..16d4f1e32c9 100644 --- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -98,7 +98,8 @@ static int vlResizeFrameBuffer ); /* Clear to black, in case video doesn't fill the entire window */ - pipe->clear(pipe, basic_csc->framebuffer.cbufs[0], 0); + pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer); + pipe->clear(pipe, PIPE_CLEAR_COLOR, 0, 0.0f, 0); return 0; } diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index a0bf063d814..9a3003a56c4 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -308,45 +308,10 @@ error1: pipe_surface_reference(&_dst, NULL); } - void surface_clear(struct st_surface *surface, unsigned value = 0) + void clear(unsigned buffers, const float *rgba, double depth = 0.0f, + unsigned stencil = 0) { - unsigned i; - struct pipe_surface *_surface = NULL; - - if(!surface) - SWIG_exception(SWIG_TypeError, "surface must not be null"); - - for(i = 0; i < $self->framebuffer.nr_cbufs; ++i) { - struct pipe_surface *cbuf = $self->framebuffer.cbufs[i]; - if(cbuf) { - if(cbuf->texture == surface->texture && - cbuf->face == surface->face && - cbuf->level == surface->level && - cbuf->zslice == surface->zslice) { - _surface = cbuf; - break; - } - } - } - - if(!_surface) { - struct pipe_surface *zsbuf = $self->framebuffer.zsbuf; - if(zsbuf) { - if(zsbuf->texture == surface->texture && - zsbuf->face == surface->face && - zsbuf->level == surface->level && - zsbuf->zslice == surface->zslice) { - _surface = zsbuf; - } - } - } - - if(!_surface) - SWIG_exception(SWIG_ValueError, "surface not bound"); - - $self->pipe->clear($self->pipe, _surface, value); - fail: - return; + $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil); } }; diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 510adcc2425..d02099389fb 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -531,8 +531,8 @@ class Context(Object): self.dirty = False return None - def clear(self, surface, value): - self.real.surface_clear(surface, value) + def clear(self, buffers, rgba, depth, stencil): + self.real.clear(buffers, rgba, depth, stencil) def _present(self): self.real.flush() diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index 4c84d121c49..4b9659861df 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -150,8 +150,12 @@ def test(dev): fb.set_cbuf(0, cbuf) fb.set_zsbuf(zbuf) ctx.set_framebuffer(fb) - ctx.surface_clear(cbuf, 0x00000000) - ctx.surface_clear(zbuf, 0xffffffff) + rgba = FloatArray(4); + rgba[0] = 0.0 + rgba[1] = 0.0 + rgba[2] = 0.0 + rgba[3] = 0.0 + ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff) # vertex shader vs = Shader(''' diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py index 434ac9b3fc8..472769f2592 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py @@ -122,7 +122,12 @@ def test(dev, name): fb.nr_cbufs = 1 fb.set_cbuf(0, cbuf) ctx.set_framebuffer(fb) - ctx.surface_clear(cbuf, 0x80808080) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) # vertex shader vs = Shader(file('vert-' + name + '.sh', 'rt').read()) diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py index 580bf65c13b..0b76932b6ed 100755 --- a/src/gallium/state_trackers/python/tests/texture_render.py +++ b/src/gallium/state_trackers/python/tests/texture_render.py @@ -161,7 +161,12 @@ class TextureTest(TestCase): fb.nr_cbufs = 1 fb.set_cbuf(0, dst_surface) ctx.set_framebuffer(fb) - ctx.surface_clear(dst_surface, 0x00000000) + rgba = FloatArray(4); + rgba[0] = 0.0 + rgba[1] = 0.0 + rgba[2] = 0.0 + rgba[3] = 0.0 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) del fb # vertex shader diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py index f5f49f6e515..a382424667c 100755 --- a/src/gallium/state_trackers/python/tests/texture_sample.py +++ b/src/gallium/state_trackers/python/tests/texture_sample.py @@ -206,7 +206,12 @@ class TextureTest(TestCase): fb.nr_cbufs = 1 fb.set_cbuf(0, cbuf) ctx.set_framebuffer(fb) - ctx.surface_clear(cbuf, 0x00000000) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) del fb # vertex shader diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index bec32db0502..5bdc6a13309 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -2,6 +2,7 @@ * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. + * Copyright 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -29,6 +30,7 @@ * Authors: * Keith Whitwell * Brian Paul + * Michel Dänzer */ #include "main/glheader.h" @@ -373,101 +375,6 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) -static void -clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ - struct st_renderbuffer *strb = st_renderbuffer(rb); - - if (!strb->surface) - return; - - if (check_clear_color_with_quad( ctx, rb )) { - /* masking or scissoring */ - clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE); - } - else { - /* clear whole buffer w/out masking */ - uint clearValue; - /* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM - * at this time! - */ - util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue); - ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); - } -} - - -static void -clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ - struct st_renderbuffer *strb = st_renderbuffer(rb); - - if (!strb->surface) - return; - - if (check_clear_depth_with_quad(ctx, rb)) { - /* scissoring or we have a combined depth/stencil buffer */ - clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE); - } - else { - /* simple clear of whole buffer */ - uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear); - ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); - } -} - - -static void -clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ - struct st_renderbuffer *strb = st_renderbuffer(rb); - - if (!strb->surface) - return; - - if (check_clear_stencil_with_quad(ctx, rb)) { - /* masking or scissoring or combined depth/stencil buffer */ - clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE); - } - else { - /* simple clear of whole buffer */ - GLuint clearValue = ctx->Stencil.Clear; - - switch (strb->surface->format) { - case PIPE_FORMAT_S8Z24_UNORM: - clearValue <<= 24; - break; - default: - ; /* no-op, stencil value is in least significant bits */ - } - - ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); - } -} - - -static void -clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ - struct st_renderbuffer *strb = st_renderbuffer(rb); - - if (!strb->surface) - return; - - if (check_clear_depth_stencil_with_quad(ctx, rb)) { - /* masking or scissoring */ - clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE); - } - else { - /* clear whole buffer w/out masking */ - GLuint clearValue = util_pack_z_stencil(strb->surface->format, - ctx->Depth.Clear, - ctx->Stencil.Clear); - ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); - } -} - - void st_flush_clear( struct st_context *st ) { /* Release vertex buffer to avoid synchronous rendering if we were @@ -493,51 +400,89 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - GLbitfield cmask = mask & BUFFER_BITS_COLOR; + GLbitfield quad_buffers = 0; + GLbitfield clear_buffers = 0; + GLuint i; - /* This makes sure the softpipe has the latest scissor, etc values */ + /* This makes sure the pipe has the latest scissor, etc values */ st_validate_state( st ); - /* - * XXX TO-DO: - * If we're going to use clear_with_quad() for any reason, use it to - * clear as many other buffers as possible. - * As it is now, we sometimes call clear_with_quad() three times to clear - * color/depth/stencil individually... - */ + if (mask & BUFFER_BITS_COLOR) { + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - if (cmask) { - GLuint b; - for (b = 0; cmask; b++) { - if (cmask & (1 << b)) { + if (mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; - assert(rb); - clear_color_buffer(ctx, rb); - cmask &= ~(1 << b); /* turn off bit */ - } - assert(b < BUFFER_COUNT); - } - } + struct st_renderbuffer *strb; - if (mask & BUFFER_BIT_ACCUM) { - st_clear_accum_buffer(ctx, - ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); + assert(rb); + + strb = st_renderbuffer(rb); + + if (!strb->surface) + continue; + + if (check_clear_color_with_quad( ctx, rb )) + quad_buffers |= PIPE_CLEAR_COLOR; + else + clear_buffers |= PIPE_CLEAR_COLOR; + } + } } if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) { /* clearing combined depth + stencil */ - clear_depth_stencil_buffer(ctx, depthRb); + struct st_renderbuffer *strb = st_renderbuffer(depthRb); + + if (strb->surface) { + if (check_clear_depth_stencil_with_quad(ctx, depthRb)) + quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + else + clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + } } else { /* separate depth/stencil clears */ if (mask & BUFFER_BIT_DEPTH) { - clear_depth_buffer(ctx, depthRb); + struct st_renderbuffer *strb = st_renderbuffer(depthRb); + + if (strb->surface) { + if (check_clear_depth_with_quad(ctx, depthRb)) + quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + else + clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + } } if (mask & BUFFER_BIT_STENCIL) { - clear_stencil_buffer(ctx, stencilRb); + struct st_renderbuffer *strb = st_renderbuffer(stencilRb); + + if (strb->surface) { + if (check_clear_stencil_with_quad(ctx, stencilRb)) + quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + else + clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + } } } + + /* + * If we're going to use clear_with_quad() for any reason, use it for + * everything possible. + */ + if (quad_buffers) { + quad_buffers |= clear_buffers; + clear_with_quad(ctx, + quad_buffers & PIPE_CLEAR_COLOR, + mask & BUFFER_BIT_DEPTH, + mask & BUFFER_BIT_STENCIL); + } else if (clear_buffers) + ctx->st->pipe->clear(ctx->st->pipe, clear_buffers, ctx->Color.ClearColor, + ctx->Depth.Clear, ctx->Stencil.Clear); + + if (mask & BUFFER_BIT_ACCUM) + st_clear_accum_buffer(ctx, + ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); }