Merge commit 'origin/gallium-0.1' into gallium-tex-surfaces
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 9 May 2008 12:11:48 +0000 (13:11 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 9 May 2008 12:11:48 +0000 (13:11 +0100)
68 files changed:
bin/raw2png.py [new file with mode: 0755]
common.py
progs/tests/fbotest2.c
progs/xdemos/glthreads.c
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/draw/draw_pipe_aaline.c
src/gallium/auxiliary/draw/draw_pipe_pstipple.c
src/gallium/auxiliary/pipebuffer/Makefile
src/gallium/auxiliary/pipebuffer/SConscript
src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
src/gallium/auxiliary/pipebuffer/pb_validate.c [new file with mode: 0644]
src/gallium/auxiliary/pipebuffer/pb_validate.h [new file with mode: 0644]
src/gallium/auxiliary/util/p_debug.c
src/gallium/auxiliary/util/p_debug_mem.c
src/gallium/auxiliary/util/p_tile.c
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_draw_quad.c
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/auxiliary/util/u_hash_table.c
src/gallium/auxiliary/util/u_hash_table.h
src/gallium/auxiliary/util/u_pack_color.h
src/gallium/auxiliary/util/u_string.h
src/gallium/drivers/failover/fo_context.c
src/gallium/drivers/i915simple/i915_screen.c
src/gallium/drivers/i915simple/i915_surface.c
src/gallium/drivers/i915simple/i915_texture.c
src/gallium/drivers/i965simple/brw_surface.c
src/gallium/drivers/i965simple/brw_tex_layout.c
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_flush.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_screen.h [new file with mode: 0644]
src/gallium/drivers/softpipe/sp_surface.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/drivers/softpipe/sp_tile_cache.c
src/gallium/drivers/softpipe/sp_tile_cache.h
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_debug.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_inlines.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/pipe/p_state.h
src/gallium/include/pipe/p_util.h
src/gallium/include/pipe/p_winsys.h
src/gallium/winsys/dri/intel/intel_winsys_pipe.c
src/gallium/winsys/xlib/xm_winsys.c
src/gallium/winsys/xlib/xm_winsys_aub.c
src/mesa/shader/shader_api.c
src/mesa/state_tracker/st_atom.c
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_framebuffer.c
src/mesa/state_tracker/st_atom_pixeltransfer.c
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_fbo.h
src/mesa/state_tracker/st_cb_feedback.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_gen_mipmap.c
src/mesa/state_tracker/st_texture.c
src/mesa/state_tracker/st_texture.h

diff --git a/bin/raw2png.py b/bin/raw2png.py
new file mode 100755 (executable)
index 0000000..ce18079
--- /dev/null
@@ -0,0 +1,339 @@
+#!/usr/bin/env python
+##########################################################################
+# 
+# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+# 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.
+# 
+##########################################################################
+
+
+import os.path
+import sys
+import struct
+import Image # http://www.pythonware.com/products/pil/
+
+PIPE_FORMAT_LAYOUT_RGBAZS   = 0
+PIPE_FORMAT_LAYOUT_YCBCR    = 1
+PIPE_FORMAT_LAYOUT_DXT      = 2
+
+PIPE_FORMAT_COMP_R    = 0
+PIPE_FORMAT_COMP_G    = 1
+PIPE_FORMAT_COMP_B    = 2
+PIPE_FORMAT_COMP_A    = 3
+PIPE_FORMAT_COMP_0    = 4
+PIPE_FORMAT_COMP_1    = 5
+PIPE_FORMAT_COMP_Z    = 6
+PIPE_FORMAT_COMP_S    = 7
+
+PIPE_FORMAT_TYPE_UNKNOWN = 0
+PIPE_FORMAT_TYPE_FLOAT   = 1
+PIPE_FORMAT_TYPE_UNORM   = 2
+PIPE_FORMAT_TYPE_SNORM   = 3
+PIPE_FORMAT_TYPE_USCALED = 4
+PIPE_FORMAT_TYPE_SSCALED = 5
+PIPE_FORMAT_TYPE_SRGB    = 6
+
+def _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP8, TYPE ):
+   return ((PIPE_FORMAT_LAYOUT_RGBAZS << 0) |\
+   ((SWZ) << 2) |\
+   ((SIZEX) << 14) |\
+   ((SIZEY) << 17) |\
+   ((SIZEZ) << 20) |\
+   ((SIZEW) << 23) |\
+   ((EXP8) << 26) |\
+   ((TYPE) << 28) )
+
+def _PIPE_FORMAT_SWZ( SWZX, SWZY, SWZZ, SWZW ):
+       return (((SWZX) << 0) | ((SWZY) << 3) | ((SWZZ) << 6) | ((SWZW) << 9))
+
+def _PIPE_FORMAT_RGBAZS_1( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ):
+       return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 0, TYPE )
+
+def _PIPE_FORMAT_RGBAZS_8( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ):
+       return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE )
+
+def _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ):
+       return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 2, TYPE )
+
+_PIPE_FORMAT_R001 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 )
+_PIPE_FORMAT_RG01 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 )
+_PIPE_FORMAT_RGB1 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_1 )
+_PIPE_FORMAT_RGBA = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_A )
+_PIPE_FORMAT_ARGB = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B )
+_PIPE_FORMAT_BGRA = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A )
+_PIPE_FORMAT_1RGB = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B )
+_PIPE_FORMAT_BGR1 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 )
+_PIPE_FORMAT_0000 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+_PIPE_FORMAT_000R = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_R )
+_PIPE_FORMAT_RRR1 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 )
+_PIPE_FORMAT_RRRR = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R )
+_PIPE_FORMAT_RRRG = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G )
+_PIPE_FORMAT_Z000 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+_PIPE_FORMAT_0Z00 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+_PIPE_FORMAT_SZ00 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+_PIPE_FORMAT_ZS00 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+_PIPE_FORMAT_S000 = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
+
+def _PIPE_FORMAT_YCBCR( REV ):
+   return ((PIPE_FORMAT_LAYOUT_YCBCR << 0) |\
+   ((REV) << 2) )
+
+def _PIPE_FORMAT_DXT( LEVEL, RSIZE, GSIZE, BSIZE, ASIZE ):
+   return ((PIPE_FORMAT_LAYOUT_DXT << 0) | \
+    ((LEVEL) << 2) | \
+    ((RSIZE) << 5) | \
+    ((GSIZE) << 8) | \
+    ((BSIZE) << 11) | \
+    ((ASIZE) << 14) )
+
+PIPE_FORMAT_NONE                  = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_0000, 0, 0, 0, 0, PIPE_FORMAT_TYPE_UNKNOWN )
+PIPE_FORMAT_A8R8G8B8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ARGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_X8R8G8B8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_1RGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_B8G8R8A8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_B8G8R8X8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_A1R5G5B5_UNORM        = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_A4R4G4B4_UNORM        = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R5G6B5_UNORM          = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_L8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_A8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_I8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_A8L8_UNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_YCBCR                 = _PIPE_FORMAT_YCBCR( 0 )
+PIPE_FORMAT_YCBCR_REV             = _PIPE_FORMAT_YCBCR( 1 )
+PIPE_FORMAT_Z16_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_Z32_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_Z32_FLOAT             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_S8Z24_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_SZ00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_Z24S8_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ZS00, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_X8Z24_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_0Z00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_Z24X8_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_S8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_S000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R64_FLOAT             = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R64G64_FLOAT          = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R64G64B64_FLOAT       = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R64G64B64A64_FLOAT    = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R32_FLOAT             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R32G32_FLOAT          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R32G32B32_FLOAT       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R32G32B32A32_FLOAT    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FLOAT )
+PIPE_FORMAT_R32_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R32G32_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R32G32B32_UNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R32G32B32A32_UNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R32_USCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R32G32_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R32G32B32_USCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R32G32B32A32_USCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R32_SNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R32G32_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R32G32B32_SNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R32G32B32A32_SNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R32_SSCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R32G32_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R32G32B32_SSCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R32G32B32A32_SSCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R16_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R16G16_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R16G16B16_UNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R16G16B16A16_UNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R16_USCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R16G16_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R16G16B16_USCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R16G16B16A16_USCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R16_SNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R16G16_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R16G16B16_SNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R16G16B16A16_SNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R16_SSCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R16G16_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R16G16B16_SSCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R16G16B16A16_SSCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R8G8_UNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R8G8B8_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R8G8B8A8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R8G8B8X8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM )
+PIPE_FORMAT_R8_USCALED            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R8G8_USCALED          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R8G8B8_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R8G8B8A8_USCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R8G8B8X8_USCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED )
+PIPE_FORMAT_R8_SNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R8G8_SNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R8G8B8_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R8G8B8A8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R8G8B8X8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM )
+PIPE_FORMAT_R8_SSCALED            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R8G8_SSCALED          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R8G8B8_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R8G8B8A8_SSCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_R8G8B8X8_SSCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED )
+PIPE_FORMAT_L8_SRGB               = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB )
+PIPE_FORMAT_A8_L8_SRGB            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB )
+PIPE_FORMAT_R8G8B8_SRGB           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB )
+PIPE_FORMAT_R8G8B8A8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB )
+PIPE_FORMAT_R8G8B8X8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB )
+PIPE_FORMAT_DXT1_RGB              = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0 )
+PIPE_FORMAT_DXT1_RGBA             = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8 )
+PIPE_FORMAT_DXT3_RGBA             = _PIPE_FORMAT_DXT( 3, 8, 8, 8, 8 )
+PIPE_FORMAT_DXT5_RGBA             = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8 )
+
+formats = {
+       PIPE_FORMAT_NONE: "PIPE_FORMAT_NONE",
+       PIPE_FORMAT_A8R8G8B8_UNORM: "PIPE_FORMAT_A8R8G8B8_UNORM",
+       PIPE_FORMAT_X8R8G8B8_UNORM: "PIPE_FORMAT_X8R8G8B8_UNORM",
+       PIPE_FORMAT_B8G8R8A8_UNORM: "PIPE_FORMAT_B8G8R8A8_UNORM",
+       PIPE_FORMAT_B8G8R8X8_UNORM: "PIPE_FORMAT_B8G8R8X8_UNORM",
+       PIPE_FORMAT_A1R5G5B5_UNORM: "PIPE_FORMAT_A1R5G5B5_UNORM",
+       PIPE_FORMAT_A4R4G4B4_UNORM: "PIPE_FORMAT_A4R4G4B4_UNORM",
+       PIPE_FORMAT_R5G6B5_UNORM: "PIPE_FORMAT_R5G6B5_UNORM",
+       PIPE_FORMAT_L8_UNORM: "PIPE_FORMAT_L8_UNORM",
+       PIPE_FORMAT_A8_UNORM: "PIPE_FORMAT_A8_UNORM",
+       PIPE_FORMAT_I8_UNORM: "PIPE_FORMAT_I8_UNORM",
+       PIPE_FORMAT_A8L8_UNORM: "PIPE_FORMAT_A8L8_UNORM",
+       PIPE_FORMAT_YCBCR: "PIPE_FORMAT_YCBCR",
+       PIPE_FORMAT_YCBCR_REV: "PIPE_FORMAT_YCBCR_REV",
+       PIPE_FORMAT_Z16_UNORM: "PIPE_FORMAT_Z16_UNORM",
+       PIPE_FORMAT_Z32_UNORM: "PIPE_FORMAT_Z32_UNORM",
+       PIPE_FORMAT_Z32_FLOAT: "PIPE_FORMAT_Z32_FLOAT",
+       PIPE_FORMAT_S8Z24_UNORM: "PIPE_FORMAT_S8Z24_UNORM",
+       PIPE_FORMAT_Z24S8_UNORM: "PIPE_FORMAT_Z24S8_UNORM",
+       PIPE_FORMAT_X8Z24_UNORM: "PIPE_FORMAT_X8Z24_UNORM",
+       PIPE_FORMAT_Z24X8_UNORM: "PIPE_FORMAT_Z24X8_UNORM",
+       PIPE_FORMAT_S8_UNORM: "PIPE_FORMAT_S8_UNORM",
+       PIPE_FORMAT_R64_FLOAT: "PIPE_FORMAT_R64_FLOAT",
+       PIPE_FORMAT_R64G64_FLOAT: "PIPE_FORMAT_R64G64_FLOAT",
+       PIPE_FORMAT_R64G64B64_FLOAT: "PIPE_FORMAT_R64G64B64_FLOAT",
+       PIPE_FORMAT_R64G64B64A64_FLOAT: "PIPE_FORMAT_R64G64B64A64_FLOAT",
+       PIPE_FORMAT_R32_FLOAT: "PIPE_FORMAT_R32_FLOAT",
+       PIPE_FORMAT_R32G32_FLOAT: "PIPE_FORMAT_R32G32_FLOAT",
+       PIPE_FORMAT_R32G32B32_FLOAT: "PIPE_FORMAT_R32G32B32_FLOAT",
+       PIPE_FORMAT_R32G32B32A32_FLOAT: "PIPE_FORMAT_R32G32B32A32_FLOAT",
+       PIPE_FORMAT_R32_UNORM: "PIPE_FORMAT_R32_UNORM",
+       PIPE_FORMAT_R32G32_UNORM: "PIPE_FORMAT_R32G32_UNORM",
+       PIPE_FORMAT_R32G32B32_UNORM: "PIPE_FORMAT_R32G32B32_UNORM",
+       PIPE_FORMAT_R32G32B32A32_UNORM: "PIPE_FORMAT_R32G32B32A32_UNORM",
+       PIPE_FORMAT_R32_USCALED: "PIPE_FORMAT_R32_USCALED",
+       PIPE_FORMAT_R32G32_USCALED: "PIPE_FORMAT_R32G32_USCALED",
+       PIPE_FORMAT_R32G32B32_USCALED: "PIPE_FORMAT_R32G32B32_USCALED",
+       PIPE_FORMAT_R32G32B32A32_USCALED: "PIPE_FORMAT_R32G32B32A32_USCALED",
+       PIPE_FORMAT_R32_SNORM: "PIPE_FORMAT_R32_SNORM",
+       PIPE_FORMAT_R32G32_SNORM: "PIPE_FORMAT_R32G32_SNORM",
+       PIPE_FORMAT_R32G32B32_SNORM: "PIPE_FORMAT_R32G32B32_SNORM",
+       PIPE_FORMAT_R32G32B32A32_SNORM: "PIPE_FORMAT_R32G32B32A32_SNORM",
+       PIPE_FORMAT_R32_SSCALED: "PIPE_FORMAT_R32_SSCALED",
+       PIPE_FORMAT_R32G32_SSCALED: "PIPE_FORMAT_R32G32_SSCALED",
+       PIPE_FORMAT_R32G32B32_SSCALED: "PIPE_FORMAT_R32G32B32_SSCALED",
+       PIPE_FORMAT_R32G32B32A32_SSCALED: "PIPE_FORMAT_R32G32B32A32_SSCALED",
+       PIPE_FORMAT_R16_UNORM: "PIPE_FORMAT_R16_UNORM",
+       PIPE_FORMAT_R16G16_UNORM: "PIPE_FORMAT_R16G16_UNORM",
+       PIPE_FORMAT_R16G16B16_UNORM: "PIPE_FORMAT_R16G16B16_UNORM",
+       PIPE_FORMAT_R16G16B16A16_UNORM: "PIPE_FORMAT_R16G16B16A16_UNORM",
+       PIPE_FORMAT_R16_USCALED: "PIPE_FORMAT_R16_USCALED",
+       PIPE_FORMAT_R16G16_USCALED: "PIPE_FORMAT_R16G16_USCALED",
+       PIPE_FORMAT_R16G16B16_USCALED: "PIPE_FORMAT_R16G16B16_USCALED",
+       PIPE_FORMAT_R16G16B16A16_USCALED: "PIPE_FORMAT_R16G16B16A16_USCALED",
+       PIPE_FORMAT_R16_SNORM: "PIPE_FORMAT_R16_SNORM",
+       PIPE_FORMAT_R16G16_SNORM: "PIPE_FORMAT_R16G16_SNORM",
+       PIPE_FORMAT_R16G16B16_SNORM: "PIPE_FORMAT_R16G16B16_SNORM",
+       PIPE_FORMAT_R16G16B16A16_SNORM: "PIPE_FORMAT_R16G16B16A16_SNORM",
+       PIPE_FORMAT_R16_SSCALED: "PIPE_FORMAT_R16_SSCALED",
+       PIPE_FORMAT_R16G16_SSCALED: "PIPE_FORMAT_R16G16_SSCALED",
+       PIPE_FORMAT_R16G16B16_SSCALED: "PIPE_FORMAT_R16G16B16_SSCALED",
+       PIPE_FORMAT_R16G16B16A16_SSCALED: "PIPE_FORMAT_R16G16B16A16_SSCALED",
+       PIPE_FORMAT_R8_UNORM: "PIPE_FORMAT_R8_UNORM",
+       PIPE_FORMAT_R8G8_UNORM: "PIPE_FORMAT_R8G8_UNORM",
+       PIPE_FORMAT_R8G8B8_UNORM: "PIPE_FORMAT_R8G8B8_UNORM",
+       PIPE_FORMAT_R8G8B8A8_UNORM: "PIPE_FORMAT_R8G8B8A8_UNORM",
+       PIPE_FORMAT_R8G8B8X8_UNORM: "PIPE_FORMAT_R8G8B8X8_UNORM",
+       PIPE_FORMAT_R8_USCALED: "PIPE_FORMAT_R8_USCALED",
+       PIPE_FORMAT_R8G8_USCALED: "PIPE_FORMAT_R8G8_USCALED",
+       PIPE_FORMAT_R8G8B8_USCALED: "PIPE_FORMAT_R8G8B8_USCALED",
+       PIPE_FORMAT_R8G8B8A8_USCALED: "PIPE_FORMAT_R8G8B8A8_USCALED",
+       PIPE_FORMAT_R8G8B8X8_USCALED: "PIPE_FORMAT_R8G8B8X8_USCALED",
+       PIPE_FORMAT_R8_SNORM: "PIPE_FORMAT_R8_SNORM",
+       PIPE_FORMAT_R8G8_SNORM: "PIPE_FORMAT_R8G8_SNORM",
+       PIPE_FORMAT_R8G8B8_SNORM: "PIPE_FORMAT_R8G8B8_SNORM",
+       PIPE_FORMAT_R8G8B8A8_SNORM: "PIPE_FORMAT_R8G8B8A8_SNORM",
+       PIPE_FORMAT_R8G8B8X8_SNORM: "PIPE_FORMAT_R8G8B8X8_SNORM",
+       PIPE_FORMAT_R8_SSCALED: "PIPE_FORMAT_R8_SSCALED",
+       PIPE_FORMAT_R8G8_SSCALED: "PIPE_FORMAT_R8G8_SSCALED",
+       PIPE_FORMAT_R8G8B8_SSCALED: "PIPE_FORMAT_R8G8B8_SSCALED",
+       PIPE_FORMAT_R8G8B8A8_SSCALED: "PIPE_FORMAT_R8G8B8A8_SSCALED",
+       PIPE_FORMAT_R8G8B8X8_SSCALED: "PIPE_FORMAT_R8G8B8X8_SSCALED",
+       PIPE_FORMAT_L8_SRGB: "PIPE_FORMAT_L8_SRGB",
+       PIPE_FORMAT_A8_L8_SRGB: "PIPE_FORMAT_A8_L8_SRGB",
+       PIPE_FORMAT_R8G8B8_SRGB: "PIPE_FORMAT_R8G8B8_SRGB",
+       PIPE_FORMAT_R8G8B8A8_SRGB: "PIPE_FORMAT_R8G8B8A8_SRGB",
+       PIPE_FORMAT_R8G8B8X8_SRGB: "PIPE_FORMAT_R8G8B8X8_SRGB",
+       PIPE_FORMAT_DXT1_RGB: "PIPE_FORMAT_DXT1_RGB",
+       PIPE_FORMAT_DXT1_RGBA: "PIPE_FORMAT_DXT1_RGBA",
+       PIPE_FORMAT_DXT3_RGBA: "PIPE_FORMAT_DXT3_RGBA",
+       PIPE_FORMAT_DXT5_RGBA: "PIPE_FORMAT_DXT5_RGBA",
+}
+
+
+def read_header(infile):
+       header_fmt = "IIII"
+       header = infile.read(struct.calcsize(header_fmt))
+       return struct.unpack_from(header_fmt, header)
+
+def read_pixel(infile, fmt, cpp):
+       assert cpp == 4
+       r, g, b, a = map(ord, infile.read(4))
+       return r, g, b, a
+
+
+def process(infilename, outfilename):
+       infile = open(infilename, "rb")
+       format, cpp, width, height = read_header(infile)
+       sys.stderr.write("format = %s, cpp = %u, width = %u, height = %u\n" % (formats[format], cpp, width, height))
+       outimage = Image.new(
+    mode='RGB',
+    size=(width, height),
+    color=(0,0,0))
+       outpixels = outimage.load()
+       for y in range(height):
+               for x in range(width):
+                       r, g, b, a = read_pixel(infile, format, cpp)
+                       outpixels[x, y] = r, g, b
+       outimage.save(outfilename, "PNG")
+
+
+def main():
+       if sys.platform == 'win32':
+               # wildcard expansion
+               from glob import glob
+               args = []
+               for arg in sys.argv[1:]:
+                       args.extend(glob(arg))
+       else:
+               args = sys.argv[1:]
+       for infilename in args:
+               root, ext = os.path.splitext(infilename)
+               outfilename = root + ".png"
+               process(infilename, outfilename)
+
+
+if __name__ == '__main__':
+       main()
index 6de181739bab0baf1c47566d43eef516cbdc98e0..36b190ce89f23a0ab93ff6f1b1de5984e911da4c 100644 (file)
--- a/common.py
+++ b/common.py
@@ -245,12 +245,11 @@ def generate(env):
                                '/GX-', # disable C++ EH
                                '/GR-', # disable C++ RTTI
                                '/GF', # enable read-only string pooling
-                               '/GS', # enable security checks
                                '/G6', # optimize for PPro, P-II, P-III
                                '/Ze', # enable extensions
-                               #'/Gi-', # ???
+                               '/Gi-', # disable incremental compilation
                                '/QIfdiv-', # disable Pentium FDIV fix
-                               #'/hotpatch', # ???
+                               '/hotpatch', # prepares an image for hotpatching.
                                #'/Z7', #enable old-style debug info
                        ]
                # Put debugging information in a separate .pdb file for each object file as
index 18f28972b6eab70c6216d219945c69f49ff427fc..5283c7e1fd6673b9c6b18b4d9ed0f9c5866dcb8f 100644 (file)
@@ -68,6 +68,7 @@ Display( void )
 
    /* draw to window */
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+   glDisable(GL_DEPTH_TEST);  /* in case window has depth buffer */
    glWindowPos2iARB(0, 0);
    glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 
index 989697fbcaab8d6cb2601f430c046f81167c8714..b90e6b4f3195eb5c3d0c39695dbb4b4599504173 100644 (file)
  * This program tests GLX thread safety.
  * Command line options:
  *  -p                       Open a display connection for each thread
+ *  -l                       Enable application-side locking
  *  -n <num threads>         Number of threads to create (default is 2)
  *  -display <display name>  Specify X display (default is :0.0)
+ *  -t                       Use texture mapping
  *
  * Brian Paul  20 July 2000
  */
 
 
+/*
+ * Notes:
+ * - Each thread gets its own GLX context.
+ *
+ * - The GLX contexts share texture objects.
+ *
+ * - When 't' is pressed to update the texture image, the window/thread which
+ *   has input focus is signalled to change the texture.  The other threads
+ *   should see the updated texture the next time they call glBindTexture.
+ */
+
+
 #if defined(PTHREADS)   /* defined by Mesa on Linux and other platforms */
 
 #include <assert.h>
 #include <GL/gl.h>
 #include <GL/glx.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -55,6 +70,8 @@ struct winthread {
    float Angle;
    int WinWidth, WinHeight;
    GLboolean NewSize;
+   GLboolean Initialized;
+   GLboolean MakeNewTexture;
 };
 
 
@@ -65,8 +82,13 @@ static volatile GLboolean ExitFlag = GL_FALSE;
 
 static GLboolean MultiDisplays = 0;
 static GLboolean Locking = 0;
+static GLboolean Texture = GL_FALSE;
+static GLuint TexObj = 12;
+static GLboolean Animate = GL_TRUE;
 
 static pthread_mutex_t Mutex;
+static pthread_cond_t CondVar;
+static pthread_mutex_t CondMutex;
 
 
 static void
@@ -77,6 +99,59 @@ Error(const char *msg)
 }
 
 
+static void
+signal_redraw(void)
+{
+   pthread_mutex_lock(&CondMutex);
+   pthread_cond_broadcast(&CondVar);
+   pthread_mutex_unlock(&CondMutex);
+}
+
+
+static void
+MakeNewTexture(struct winthread *wt)
+{
+#define TEX_SIZE 128
+   static float step = 0.0;
+   GLfloat image[TEX_SIZE][TEX_SIZE][4];
+   GLint width;
+   int i, j;
+
+   for (j = 0; j < TEX_SIZE; j++) {
+      for (i = 0; i < TEX_SIZE; i++) {
+         float dt = 5.0 * (j - 0.5 * TEX_SIZE) / TEX_SIZE;
+         float ds = 5.0 * (i - 0.5 * TEX_SIZE) / TEX_SIZE;
+         float r = dt * dt + ds * ds + step;
+         image[j][i][0] = 
+         image[j][i][1] = 
+         image[j][i][2] = 0.75 + 0.25 * cos(r);
+         image[j][i][3] = 1.0;
+      }
+   }
+
+   step += 0.5;
+
+   glBindTexture(GL_TEXTURE_2D, TexObj);
+
+   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
+   if (width) {
+      assert(width == TEX_SIZE);
+      /* sub-tex replace */
+      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEX_SIZE, TEX_SIZE,
+                   GL_RGBA, GL_FLOAT, image);
+   }
+   else {
+      /* create new */
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, 
+                   GL_RGBA, GL_FLOAT, image);
+   }
+}
+
+
+
 /* draw a colored cube */
 static void
 draw_object(void)
@@ -85,52 +160,61 @@ draw_object(void)
    glScalef(0.75, 0.75, 0.75);
 
    glColor3f(1, 0, 0);
-   glBegin(GL_POLYGON);
-   glVertex3f(1, -1, -1);
-   glVertex3f(1,  1, -1);
-   glVertex3f(1,  1,  1);
-   glVertex3f(1, -1,  1);
-   glEnd();
 
+   if (Texture) {
+      glBindTexture(GL_TEXTURE_2D, TexObj);
+      glEnable(GL_TEXTURE_2D);
+   }
+   else {
+      glDisable(GL_TEXTURE_2D);
+   }
+
+   glBegin(GL_QUADS);
+
+   /* -X */
    glColor3f(0, 1, 1);
-   glBegin(GL_POLYGON);
-   glVertex3f(-1, -1, -1);
-   glVertex3f(-1,  1, -1);
-   glVertex3f(-1,  1,  1);
-   glVertex3f(-1, -1,  1);
-   glEnd();
+   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
+   glTexCoord2f(1, 0);  glVertex3f(-1,  1, -1);
+   glTexCoord2f(1, 1);  glVertex3f(-1,  1,  1);
+   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
 
-   glColor3f(0, 1, 0);
-   glBegin(GL_POLYGON);
-   glVertex3f(-1, 1, -1);
-   glVertex3f( 1, 1, -1);
-   glVertex3f( 1, 1,  1);
-   glVertex3f(-1, 1,  1);
-   glEnd();
+   /* +X */
+   glColor3f(1, 0, 0);
+   glTexCoord2f(0, 0);  glVertex3f(1, -1, -1);
+   glTexCoord2f(1, 0);  glVertex3f(1,  1, -1);
+   glTexCoord2f(1, 1);  glVertex3f(1,  1,  1);
+   glTexCoord2f(0, 1);  glVertex3f(1, -1,  1);
 
+   /* -Y */
    glColor3f(1, 0, 1);
-   glBegin(GL_POLYGON);
-   glVertex3f(-1, -1, -1);
-   glVertex3f( 1, -1, -1);
-   glVertex3f( 1, -1,  1);
-   glVertex3f(-1, -1,  1);
-   glEnd();
+   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
+   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
+   glTexCoord2f(1, 1);  glVertex3f( 1, -1,  1);
+   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
 
-   glColor3f(0, 0, 1);
-   glBegin(GL_POLYGON);
-   glVertex3f(-1, -1, 1);
-   glVertex3f( 1, -1, 1);
-   glVertex3f( 1,  1, 1);
-   glVertex3f(-1,  1, 1);
-   glEnd();
+   /* +Y */
+   glColor3f(0, 1, 0);
+   glTexCoord2f(0, 0);  glVertex3f(-1, 1, -1);
+   glTexCoord2f(1, 0);  glVertex3f( 1, 1, -1);
+   glTexCoord2f(1, 1);  glVertex3f( 1, 1,  1);
+   glTexCoord2f(0, 1);  glVertex3f(-1, 1,  1);
 
+   /* -Z */
    glColor3f(1, 1, 0);
-   glBegin(GL_POLYGON);
-   glVertex3f(-1, -1, -1);
-   glVertex3f( 1, -1, -1);
-   glVertex3f( 1,  1, -1);
-   glVertex3f(-1,  1, -1);
+   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
+   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
+   glTexCoord2f(1, 1);  glVertex3f( 1,  1, -1);
+   glTexCoord2f(0, 1);  glVertex3f(-1,  1, -1);
+
+   /* +Y */
+   glColor3f(0, 0, 1);
+   glTexCoord2f(0, 0);  glVertex3f(-1, -1, 1);
+   glTexCoord2f(1, 0);  glVertex3f( 1, -1, 1);
+   glTexCoord2f(1, 1);  glVertex3f( 1,  1, 1);
+   glTexCoord2f(0, 1);  glVertex3f(-1,  1, 1);
+
    glEnd();
+
    glPopMatrix();
 }
 
@@ -142,6 +226,8 @@ resize(struct winthread *wt, int w, int h)
    wt->NewSize = GL_TRUE;
    wt->WinWidth = w;
    wt->WinHeight = h;
+   if (!Animate)
+      signal_redraw();
 }
 
 
@@ -151,18 +237,19 @@ resize(struct winthread *wt, int w, int h)
 static void
 draw_loop(struct winthread *wt)
 {
-   GLboolean firstIter = GL_TRUE;
-
    while (!ExitFlag) {
 
       if (Locking)
          pthread_mutex_lock(&Mutex);
 
       glXMakeCurrent(wt->Dpy, wt->Win, wt->Context);
-      if (firstIter) {
+      if (!wt->Initialized) {
          printf("glthreads: %d: GL_RENDERER = %s\n", wt->Index,
                 (char *) glGetString(GL_RENDERER));
-         firstIter = GL_FALSE;
+         if (Texture /*&& wt->Index == 0*/) {
+            MakeNewTexture(wt);
+         }
+         wt->Initialized = GL_TRUE;
       }
 
       if (Locking)
@@ -182,10 +269,15 @@ draw_loop(struct winthread *wt)
          wt->NewSize = GL_FALSE;
       }
 
+      if (wt->MakeNewTexture) {
+         MakeNewTexture(wt);
+         wt->MakeNewTexture = GL_FALSE;
+      }
+
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
       glPushMatrix();
-         glRotatef(wt->Angle, 0, 0, 1);
+         glRotatef(wt->Angle, 0, 1, 0);
          glRotatef(wt->Angle, 1, 0, 0);
          glScalef(0.7, 0.7, 0.7);
          draw_object();
@@ -199,12 +291,63 @@ draw_loop(struct winthread *wt)
       if (Locking)
          pthread_mutex_unlock(&Mutex);
 
-      usleep(5000);
+      if (Animate) {
+         usleep(5000);
+      }
+      else {
+         /* wait for signal to draw */
+         pthread_mutex_lock(&CondMutex);
+         pthread_cond_wait(&CondVar, &CondMutex);
+         pthread_mutex_unlock(&CondMutex);
+      }
       wt->Angle += 1.0;
    }
 }
 
 
+static void
+keypress(XEvent *event, struct winthread *wt)
+{
+   char buf[100];
+   KeySym keySym;
+   XComposeStatus stat;
+
+   XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat);
+
+   switch (keySym) {
+   case XK_Escape:
+      /* tell all threads to exit */
+      if (!Animate) {
+         signal_redraw();
+      }
+      ExitFlag = GL_TRUE;
+      /*printf("exit draw_loop %d\n", wt->Index);*/
+      return;
+   case XK_t:
+   case XK_T:
+      if (Texture) {
+         wt->MakeNewTexture = GL_TRUE;
+         if (!Animate)
+            signal_redraw();
+      }
+      break;
+   case XK_a:
+   case XK_A:
+      Animate = !Animate;
+      if (Animate)  /* yes, prev Animate state! */
+         signal_redraw();
+      break;
+   case XK_s:
+   case XK_S:
+      if (!Animate)
+         signal_redraw();
+      break;
+   default:
+      ; /* nop */
+   }
+}
+
+
 /*
  * The main process thread runs this loop.
  * Single display connection for all threads.
@@ -250,10 +393,14 @@ event_loop(Display *dpy)
             }
             break;
          case KeyPress:
-            /* tell all threads to exit */
-            ExitFlag = GL_TRUE;
-            /*printf("exit draw_loop %d\n", wt->Index);*/
-            return;
+            for (i = 0; i < NumWinThreads; i++) {
+               struct winthread *wt = &WinThreads[i];
+               if (event.xkey.window == wt->Win) {
+                  keypress(&event, wt);
+                  break;
+               }
+            }
+            break;
          default:
             /*no-op*/ ;
       }
@@ -281,12 +428,10 @@ event_loop_multi(void)
             resize(wt, event.xconfigure.width, event.xconfigure.height);
             break;
          case KeyPress:
-            /* tell all threads to exit */
-            ExitFlag = GL_TRUE;
-            /*printf("exit draw_loop %d\n", wt->Index);*/
-            return;
+            keypress(&event, wt);
+            break;
          default:
-            /*no-op*/ ;
+            ; /* nop */
          }
       }
       w = (w + 1) % NumWinThreads;
@@ -300,7 +445,7 @@ event_loop_multi(void)
  * we'll call this once for each thread, before the threads are created.
  */
 static void
-create_window(struct winthread *wt)
+create_window(struct winthread *wt, GLXContext shareCtx)
 {
    Window win;
    GLXContext ctx;
@@ -316,9 +461,9 @@ create_window(struct winthread *wt)
    unsigned long mask;
    Window root;
    XVisualInfo *visinfo;
-   int width = 80, height = 80;
-   int xpos = (wt->Index % 10) * 90;
-   int ypos = (wt->Index / 10) * 100;
+   int width = 160, height = 160;
+   int xpos = (wt->Index % 8) * (width + 10);
+   int ypos = (wt->Index / 8) * (width + 20);
 
    scrnum = DefaultScreen(wt->Dpy);
    root = RootWindow(wt->Dpy, scrnum);
@@ -355,7 +500,7 @@ create_window(struct winthread *wt)
    }
 
 
-   ctx = glXCreateContext(wt->Dpy, visinfo, NULL, True);
+   ctx = glXCreateContext(wt->Dpy, visinfo, shareCtx, True);
    if (!ctx) {
       Error("Couldn't create GLX context");
    }
@@ -405,6 +550,25 @@ clean_up(void)
 }
 
 
+static void
+usage(void)
+{
+   printf("glthreads: test of GL thread safety (any key = exit)\n");
+   printf("Usage:\n");
+   printf("  glthreads [options]\n");
+   printf("Options:\n");
+   printf("   -display DISPLAYNAME  Specify display string\n");
+   printf("   -n NUMTHREADS  Number of threads to create\n");
+   printf("   -p  Use a separate display connection for each thread\n");
+   printf("   -l  Use application-side locking\n");
+   printf("   -t  Enable texturing\n");
+   printf("Keyboard:\n");
+   printf("   Esc  Exit\n");
+   printf("   t    Change texture image (requires -t option)\n");
+   printf("   a    Toggle animation\n");
+   printf("   s    Step rotation (when not animating)\n");
+}
+
 
 int
 main(int argc, char *argv[])
@@ -416,9 +580,7 @@ main(int argc, char *argv[])
    Status threadStat;
 
    if (argc == 1) {
-      printf("glthreads: test of GL thread safety (any key = exit)\n");
-      printf("Usage:\n");
-      printf("  glthreads [-display dpyName] [-n numthreads]\n");
+      usage();
    }
    else {
       int i;
@@ -433,6 +595,9 @@ main(int argc, char *argv[])
          else if (strcmp(argv[i], "-l") == 0) {
             Locking = 1;
          }
+         else if (strcmp(argv[i], "-t") == 0) {
+            Texture = 1;
+         }
          else if (strcmp(argv[i], "-n") == 0 && i + 1 < argc) {
             numThreads = atoi(argv[i + 1]);
             if (numThreads < 1)
@@ -442,13 +607,14 @@ main(int argc, char *argv[])
             i++;
          }
          else {
-            fprintf(stderr, "glthreads: unexpected flag: %s\n", argv[i]);
+            usage();
+            exit(1);
          }
       }
    }
    
    if (Locking)
-      printf("glthreads: Using explict locks around Xlib calls.\n");
+      printf("glthreads: Using explicit locks around Xlib calls.\n");
    else
       printf("glthreads: No explict locking.\n");
 
@@ -478,9 +644,9 @@ main(int argc, char *argv[])
       }
    }
 
-   if (Locking) {
-      pthread_mutex_init(&Mutex, NULL);
-   }
+   pthread_mutex_init(&Mutex, NULL);
+   pthread_mutex_init(&CondMutex, NULL);
+   pthread_cond_init(&CondVar, NULL);
 
    printf("glthreads: creating windows\n");
 
@@ -488,6 +654,8 @@ main(int argc, char *argv[])
 
    /* Create the GLX windows and contexts */
    for (i = 0; i < numThreads; i++) {
+      GLXContext share;
+
       if (MultiDisplays) {
          WinThreads[i].Dpy = XOpenDisplay(displayName);
          assert(WinThreads[i].Dpy);
@@ -496,7 +664,11 @@ main(int argc, char *argv[])
          WinThreads[i].Dpy = dpy;
       }
       WinThreads[i].Index = i;
-      create_window(&WinThreads[i]);
+      WinThreads[i].Initialized = GL_FALSE;
+
+      share = (Texture && i > 0) ? WinThreads[0].Context : 0;
+
+      create_window(&WinThreads[i], share);
    }
 
    printf("glthreads: creating threads\n");
@@ -505,7 +677,7 @@ main(int argc, char *argv[])
    for (i = 0; i < numThreads; i++) {
       pthread_create(&WinThreads[i].Thread, NULL, thread_function,
                      (void*) &WinThreads[i]);
-      printf("glthreads: Created thread %u\n", (unsigned int) WinThreads[i].Thread);
+      printf("glthreads: Created thread %p\n", (void *) WinThreads[i].Thread);
    }
 
    if (MultiDisplays)
index a1a3a9efaf3fef4c33f7e6d679e15aec01840ec7..dc5987df4485451d6f5e2b4554d3577fd214e08f 100644 (file)
@@ -769,8 +769,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx)
 enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
                                     const struct pipe_framebuffer_state *fb)
 {
-   /* XXX this memcmp() fails to detect buffer size changes */
-   if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) {
+   if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
       ctx->fb = *fb;
       ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
    }
index f501b2aed411c0d3705bf54647c67d1e1b5d71df..6dc20f2c90a95412cfeb1d4eceefa992a8703fde 100644 (file)
@@ -415,8 +415,11 @@ aaline_create_texture(struct aaline_stage *aaline)
 
       assert(aaline->texture->width[level] == aaline->texture->height[level]);
 
-      surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0);
-      data = pipe_surface_map(surface);
+      /* This texture is new, no need to flush. 
+       */
+      surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
+      data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
       if (data == NULL)
          return FALSE;
 
@@ -440,9 +443,8 @@ aaline_create_texture(struct aaline_stage *aaline)
       }
 
       /* unmap */
-      pipe_surface_unmap(surface);
-      pipe_surface_reference(&surface, NULL);
-      pipe->texture_update(pipe, aaline->texture, 0, (1 << level));
+      screen->surface_unmap(screen, surface);
+      screen->tex_surface_release(screen, &surface);
    }
    return TRUE;
 }
index 73ee41985802ba82d43906c44b75c30fde2da56a..4bca92ff11d9c4ae63255440692932927b82baac 100644 (file)
@@ -376,8 +376,14 @@ pstip_update_texture(struct pstip_stage *pstip)
    uint i, j;
    ubyte *data;
 
-   surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0);
-   data = pipe_surface_map(surface);
+   /* XXX: want to avoid flushing just because we use stipple: 
+    */
+   pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL );
+
+   surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0,
+                                     PIPE_BUFFER_USAGE_CPU_WRITE);
+   data = screen->surface_map(screen, surface,
+                              PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /*
     * Load alpha texture.
@@ -399,9 +405,8 @@ pstip_update_texture(struct pstip_stage *pstip)
    }
 
    /* unmap */
-   pipe_surface_unmap(surface);
-   pipe_surface_reference(&surface, NULL);
-   pipe->texture_update(pipe, pstip->texture, 0, 0x1);
+   screen->surface_unmap(screen, surface);
+   screen->tex_surface_release(screen, &surface);
 }
 
 
index d654dbcc919aa00511eb9f7ba473b39f8ce2b434..ff09011b660fba6ac96970967230d3133e91cc7c 100644 (file)
@@ -11,6 +11,7 @@ C_SOURCES = \
        pb_bufmgr_mm.c \
        pb_bufmgr_pool.c \
        pb_bufmgr_slab.c \
+       pb_validate.c \
        pb_winsys.c
 
 include ../../Makefile.template
index 604a217982e90be4736678fe01a0d2c417295922..9db0c0eae3b8f9151f8231ec5b7487b6aa495b95 100644 (file)
@@ -10,6 +10,7 @@ pipebuffer = env.ConvenienceLibrary(
                'pb_bufmgr_mm.c',
                'pb_bufmgr_pool.c',
                'pb_bufmgr_slab.c',
+               'pb_validate.c',
                'pb_winsys.c',
        ])
 
index 2fa08429715dcc59dcc144cae702acab0983262d..7f236887a9063df2e746a40639d914365e177d1f 100644 (file)
@@ -168,6 +168,28 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf)
 }
 
 
+static INLINE enum pipe_error
+_fenced_buffer_finish(struct fenced_buffer *fenced_buf)
+{
+   struct fenced_buffer_list *fenced_list = fenced_buf->list;
+   struct pipe_winsys *winsys = fenced_list->winsys;
+
+   debug_warning("waiting for GPU");
+
+   assert(fenced_buf->fence);
+   if(fenced_buf->fence) {
+      if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) {
+        return PIPE_ERROR;
+      }
+      /* Remove from the fenced list */
+      _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */
+   }
+
+   fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+   return PIPE_OK;
+}
+
+
 /**
  * Free as many fenced buffers from the list head as possible. 
  */
@@ -207,40 +229,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
 }
 
 
-/**
- * Serialize writes, but allow concurrent reads.
- */
-static INLINE enum pipe_error
-fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags)
-{
-   struct fenced_buffer_list *fenced_list = fenced_buf->list;
-   struct pipe_winsys *winsys = fenced_list->winsys;
-
-   /* Allow concurrent reads */
-   if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0)
-      return PIPE_OK;
-
-   /* Wait for the CPU to finish */
-   if(fenced_buf->mapcount) {
-      /* FIXME: Use thread conditions variables to signal when mapcount 
-       * reaches zero */
-      debug_warning("attemp to write concurrently to buffer");
-      /* XXX: we must not fail here in order to support texture mipmap generation
-      return PIPE_ERROR_RETRY;
-       */
-   }
-
-   /* Wait for the GPU to finish */
-   if(fenced_buf->fence) {
-      if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0)
-        return PIPE_ERROR_RETRY; 
-      _fenced_buffer_remove(fenced_buf);
-   }
-
-   return PIPE_OK;
-}
-
-
 static void
 fenced_buffer_destroy(struct pb_buffer *buf)
 {
@@ -280,15 +268,28 @@ fenced_buffer_map(struct pb_buffer *buf,
 {
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
    void *map;
-   assert((flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE) == 0);
+
+   assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE));
+   flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
    
-   if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK)
-      return NULL;
+   /* Check for GPU read/write access */
+   if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) {
+      /* Wait for the GPU to finish writing */
+      _fenced_buffer_finish(fenced_buf);
+   }
+
+   /* Check for CPU write access (read is OK) */
+   if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
+      /* this is legal -- just for debugging */
+      debug_warning("concurrent CPU writes");
+   }
    
    map = pb_map(fenced_buf->buffer, flags);
-   if(map)
+   if(map) {
       ++fenced_buf->mapcount;
-   fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+      fenced_buf->flags |= flags;
+   }
+
    return map;
 }
 
@@ -298,10 +299,12 @@ fenced_buffer_unmap(struct pb_buffer *buf)
 {
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
    assert(fenced_buf->mapcount);
-   pb_unmap(fenced_buf->buffer);
-   --fenced_buf->mapcount;
-   if(!fenced_buf->mapcount)
-      fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+   if(fenced_buf->mapcount) {
+      pb_unmap(fenced_buf->buffer);
+      --fenced_buf->mapcount;
+      if(!fenced_buf->mapcount)
+        fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+   }
 }
 
 
@@ -334,8 +337,10 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,
       return NULL;
    
    buf = CALLOC_STRUCT(fenced_buffer);
-   if(!buf)
+   if(!buf) {
+      pb_reference(&buffer, NULL);
       return NULL;
+   }
    
    buf->base.base.refcount = 1;
    buf->base.base.alignment = buffer->base.alignment;
@@ -374,7 +379,7 @@ buffer_fence(struct pb_buffer *buf,
    fenced_list = fenced_buf->list;
    winsys = fenced_list->winsys;
    
-   if(fence == fenced_buf->fence) {
+   if(!fence || fence == fenced_buf->fence) {
       /* Handle the same fence case specially, not only because it is a fast 
        * path, but mostly to avoid serializing two writes with the same fence, 
        * as that would bring the hardware down to synchronous operation without
@@ -384,11 +389,6 @@ buffer_fence(struct pb_buffer *buf,
       return;
    }
    
-   if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) {
-      /* FIXME: propagate error */
-      (void)0;
-   }
-   
    _glthread_LOCK_MUTEX(fenced_list->mutex);
    if (fenced_buf->fence)
       _fenced_buffer_remove(fenced_buf);
index 8de286e3f945d69483a37ddf9c800224285b6bc1..f6cc7a525b7bab55e8ee250f504ab8377e6f236b 100644 (file)
@@ -50,7 +50,8 @@
 #define PB_BUFMGR_H_
 
 
-#include <stddef.h>
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
 
 
 #ifdef __cplusplus
@@ -68,7 +69,6 @@ struct pipe_winsys;
  */
 struct pb_manager
 {
-   /* XXX: we will likely need more allocation flags */
    struct pb_buffer *
    (*create_buffer)( struct pb_manager *mgr, 
                     size_t size,
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c
new file mode 100644 (file)
index 0000000..362fd89
--- /dev/null
@@ -0,0 +1,153 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Buffer validation.
+ * 
+ * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ */
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
+#include "pipe/p_util.h"
+#include "pipe/p_debug.h"
+
+#include "pb_buffer.h"
+#include "pb_buffer_fenced.h"
+#include "pb_validate.h"
+
+
+#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */ 
+
+
+struct pb_validate
+{
+   struct pb_buffer **buffers;
+   unsigned used;
+   unsigned size;
+};
+
+
+enum pipe_error
+pb_validate_add_buffer(struct pb_validate *vl,
+                       struct pb_buffer *buf)
+{
+   assert(buf);
+   if(!buf)
+      return PIPE_ERROR;
+
+   /* We only need to store one reference for each buffer, so avoid storing
+    * consecutive references for the same buffer. It might not be the more 
+    * common pasttern, but it is easy to implement.
+    */
+   if(vl->used && vl->buffers[vl->used - 1] == buf) {
+      return PIPE_OK;
+   }
+   
+   /* Grow the table */
+   if(vl->used == vl->size) {
+      unsigned new_size;
+      struct pb_buffer **new_buffers;
+      
+      new_size = vl->size * 2;
+      if(!new_size)
+        return PIPE_ERROR_OUT_OF_MEMORY;
+
+      new_buffers = (struct pb_buffer **)REALLOC(vl->buffers,
+                                                 vl->size*sizeof(struct pb_buffer *),
+                                                 new_size*sizeof(struct pb_buffer *));
+      if(!new_buffers)
+         return PIPE_ERROR_OUT_OF_MEMORY;
+      
+      memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *));
+      
+      vl->size = new_size;
+      vl->buffers = new_buffers;
+   }
+   
+   assert(!vl->buffers[vl->used]);
+   pb_reference(&vl->buffers[vl->used], buf);
+   ++vl->used;
+   
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+pb_validate_validate(struct pb_validate *vl) 
+{
+   /* FIXME: go through each buffer, ensure its not mapped, its address is 
+    * available -- requires a new pb_buffer interface */
+   return PIPE_OK;
+}
+
+
+void
+pb_validate_fence(struct pb_validate *vl,
+                  struct pipe_fence_handle *fence)
+{
+   unsigned i;
+   for(i = 0; i < vl->used; ++i) {
+      buffer_fence(vl->buffers[i], fence);
+      pb_reference(&vl->buffers[i], NULL);
+   }
+   vl->used = 0;
+}
+
+
+void
+pb_validate_destroy(struct pb_validate *vl)
+{
+   unsigned i;
+   for(i = 0; i < vl->used; ++i)
+      pb_reference(&vl->buffers[i], NULL);
+   FREE(vl->buffers);
+   FREE(vl);
+}
+
+
+struct pb_validate *
+pb_validate_create()
+{
+   struct pb_validate *vl;
+   
+   vl = CALLOC_STRUCT(pb_validate);
+   if(!vl)
+      return NULL;
+   
+   vl->size = PB_VALIDATE_INITIAL_SIZE;
+   vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *));
+   if(!vl->buffers) {
+      FREE(vl);
+      return NULL;
+   }
+
+   return vl;
+}
+
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h
new file mode 100644 (file)
index 0000000..3db1d53
--- /dev/null
@@ -0,0 +1,91 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Buffer validation.
+ * 
+ * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ */
+
+#ifndef PB_VALIDATE_H_
+#define PB_VALIDATE_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct pb_buffer;
+struct pipe_fence_handle;
+
+
+/**
+ * Buffer validation list.
+ * 
+ * It holds a list of buffers to be validated and fenced when flushing.
+ */
+struct pb_validate;
+
+
+enum pipe_error
+pb_validate_add_buffer(struct pb_validate *vl,
+                       struct pb_buffer *buf);
+
+/**
+ * Validate all buffers for hardware access.
+ * 
+ * Should be called right before issuing commands to the hardware.
+ */
+enum pipe_error
+pb_validate_validate(struct pb_validate *vl);
+
+/**
+ * Fence all buffers and clear the list.
+ * 
+ * Should be called right before issuing commands to the hardware.
+ */
+void
+pb_validate_fence(struct pb_validate *vl,
+                  struct pipe_fence_handle *fence);
+
+struct pb_validate *
+pb_validate_create(void);
+
+void
+pb_validate_destroy(struct pb_validate *vl);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*PB_VALIDATE_H_*/
index 4ec17466624a7f3a7add760063552472be5f214e..ce7fb589562fbe18cbf0e63856a281720bcc3b7a 100644 (file)
@@ -67,7 +67,7 @@ void _debug_vprintf(const char *format, va_list ap)
    static char buf[512 + 1] = {'\0'};
    size_t len = strlen(buf);
    int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap);
-   if(ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) {
+   if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) {
       _EngDebugPrint("%s", buf);
       buf[0] = '\0';
    }
@@ -154,6 +154,7 @@ debug_get_option(const char *name, const char *dfault)
 {
    const char *result;
 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
+#ifdef DEBUG
    ULONG_PTR iFile = 0;
    const void *pMap = NULL;
    const char *sol, *eol, *sep;
@@ -183,6 +184,9 @@ debug_get_option(const char *name, const char *dfault)
       }
       EngUnmapFile(iFile);
    }
+#else
+   result = dfault;
+#endif
 #else
    
    result = getenv(name);
@@ -203,15 +207,15 @@ debug_get_bool_option(const char *name, boolean dfault)
    
    if(str == NULL)
       result = dfault;
-   else if(!strcmp(str, "n"))
+   else if(!util_strcmp(str, "n"))
       result = FALSE;
-   else if(!strcmp(str, "no"))
+   else if(!util_strcmp(str, "no"))
       result = FALSE;
-   else if(!strcmp(str, "0"))
+   else if(!util_strcmp(str, "0"))
       result = FALSE;
-   else if(!strcmp(str, "f"))
+   else if(!util_strcmp(str, "f"))
       result = FALSE;
-   else if(!strcmp(str, "false"))
+   else if(!util_strcmp(str, "false"))
       result = FALSE;
    else
       result = TRUE;
@@ -244,7 +248,7 @@ debug_get_flags_option(const char *name,
    else {
       result = 0;
       while( flags->name ) {
-        if (!strcmp(str, "all") || strstr(str, flags->name ))
+        if (!util_strcmp(str, "all") || util_strstr(str, flags->name ))
            result |= flags->value;
         ++flags;
       }
@@ -299,10 +303,10 @@ debug_dump_flags(const struct debug_named_value *names,
    while(names->name) {
       if((names->value & value) == names->value) {
         if (!first)
-           strncat(output, "|", sizeof(output));
+           util_strncat(output, "|", sizeof(output));
         else
            first = 0;
-        strncat(output, names->name, sizeof(output));
+        util_strncat(output, names->name, sizeof(output));
         value &= ~names->value;
       }
       ++names;
@@ -310,12 +314,12 @@ debug_dump_flags(const struct debug_named_value *names,
    
    if (value) {
       if (!first)
-        strncat(output, "|", sizeof(output));
+        util_strncat(output, "|", sizeof(output));
       else
         first = 0;
       
       util_snprintf(rest, sizeof(rest), "0x%08lx", value);
-      strncat(output, rest, sizeof(output));
+      util_strncat(output, rest, sizeof(output));
    }
    
    if(first)
@@ -325,101 +329,159 @@ debug_dump_flags(const struct debug_named_value *names,
 }
 
 
+static const struct debug_named_value pipe_format_names[] = {
+#ifdef DEBUG
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA),
+   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA),
+#endif
+   DEBUG_NAMED_VALUE_END
+};
 
-
-
+#ifdef DEBUG
+void debug_print_format(const char *msg, unsigned fmt )
+{
+   debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); 
+}
+#endif
 
 char *pf_sprint_name( char *str, enum pipe_format format )
 {
-   strcpy( str, "PIPE_FORMAT_" );
-   switch (pf_layout( format )) {
-   case PIPE_FORMAT_LAYOUT_RGBAZS:
-      {
-         pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format;
-         uint                 i;
-         uint                 scale = 1 << (pf_exp8( rgbazs ) * 3);
-
-         for (i = 0; i < 4; i++) {
-            uint  size = pf_size_xyzw( rgbazs, i );
-
-            if (size == 0) {
-               break;
-            }
-            switch (pf_swizzle_xyzw( rgbazs, i )) {
-            case PIPE_FORMAT_COMP_R:
-               strcat( str, "R" );
-               break;
-            case PIPE_FORMAT_COMP_G:
-               strcat( str, "G" );
-               break;
-            case PIPE_FORMAT_COMP_B:
-               strcat( str, "B" );
-               break;
-            case PIPE_FORMAT_COMP_A:
-               strcat( str, "A" );
-               break;
-            case PIPE_FORMAT_COMP_0:
-               strcat( str, "0" );
-               break;
-            case PIPE_FORMAT_COMP_1:
-               strcat( str, "1" );
-               break;
-            case PIPE_FORMAT_COMP_Z:
-               strcat( str, "Z" );
-               break;
-            case PIPE_FORMAT_COMP_S:
-               strcat( str, "S" );
-               break;
-            }
-            util_snprintf( &str[strlen( str )], 32, "%u", size * scale );
-         }
-         if (i != 0) {
-            strcat( str, "_" );
-         }
-         switch (pf_type( rgbazs )) {
-         case PIPE_FORMAT_TYPE_UNKNOWN:
-            strcat( str, "NONE" );
-            break;
-         case PIPE_FORMAT_TYPE_FLOAT:
-            strcat( str, "FLOAT" );
-            break;
-         case PIPE_FORMAT_TYPE_UNORM:
-            strcat( str, "UNORM" );
-            break;
-         case PIPE_FORMAT_TYPE_SNORM:
-            strcat( str, "SNORM" );
-            break;
-         case PIPE_FORMAT_TYPE_USCALED:
-            strcat( str, "USCALED" );
-            break;
-         case PIPE_FORMAT_TYPE_SSCALED:
-            strcat( str, "SSCALED" );
-            break;
-         }
-      }
-      break;
-   case PIPE_FORMAT_LAYOUT_YCBCR:
-      {
-         pipe_format_ycbcr_t  ycbcr = (pipe_format_ycbcr_t) format;
-
-         strcat( str, "YCBCR" );
-         if (pf_rev( ycbcr )) {
-            strcat( str, "_REV" );
-         }
-      }
-      break;
-   }
+   strcpy( str, debug_dump_enum(pipe_format_names, format) );
    return str;
 }
 
 
 #ifdef DEBUG
-void debug_print_format(const char *msg, unsigned fmt )
+void debug_dump_image(const char *prefix,
+                      unsigned format, unsigned cpp,
+                      unsigned width, unsigned height,
+                      unsigned pitch,
+                      const void *data)     
 {
-   char fmtstr[80];
-   pf_sprint_name(fmtstr, (enum pipe_format)fmt);
+#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
+   static unsigned no = 0; 
+   char filename[256];
+   WCHAR wfilename[sizeof(filename)];
+   ULONG_PTR iFile = 0;
+   struct {
+      unsigned format;
+      unsigned cpp;
+      unsigned width;
+      unsigned height;
+   } header;
+   unsigned char *pMap = NULL;
+   unsigned i;
 
-   debug_printf("%s: %s\n", msg, fmtstr); 
+   util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u%s.raw", ++no, prefix);
+   for(i = 0; i < sizeof(filename); ++i)
+      wfilename[i] = (WCHAR)filename[i];
+   
+   pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile);
+   if(!pMap)
+      return;
+   
+   header.format = format;
+   header.cpp = cpp;
+   header.width = width;
+   header.height = height;
+   memcpy(pMap, &header, sizeof(header));
+   pMap += sizeof(header);
+   
+   for(i = 0; i < height; ++i) {
+      memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width);
+      pMap += cpp*width;
+   }
+      
+   EngUnmapFile(iFile);
+#endif
 }
 #endif
index 3b5e4fbaeea9539f757408448878eab4d7c18f4c..78497c5f6af8b29253b6fac9f66409a4636cee04 100644 (file)
@@ -211,6 +211,7 @@ debug_memory_begin(void)
 void 
 debug_memory_end(unsigned long start_no)
 {
+   size_t total_size = 0;
    struct list_head *entry;
 
    entry = list.prev;
@@ -220,9 +221,15 @@ debug_memory_end(unsigned long start_no)
       hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
       ptr = data_from_header(hdr);
       if(start_no <= hdr->no && hdr->no < last_no ||
-        last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))
+        last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) {
         debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
                      hdr->file, hdr->line, hdr->function,
                      hdr->size, ptr);
+        total_size += hdr->size;
+      }
+   }
+   if(total_size) {
+      debug_printf("Total of %u KB of system memory apparently leaked\n",
+                  (total_size + 1023)/1024);
    }
 }
index 63e1cc6013a82dac2e5bd076154ff9ab812adfae..5728757d2fb492a2f98a15cdc070eb9a2367cb67 100644 (file)
@@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
                   uint x, uint y, uint w, uint h,
                   void *p, int dst_stride)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint cpp = ps->cpp;
    const ubyte *pSrc;
    const uint src_stride = ps->pitch * cpp;
@@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe,
    if (pipe_clip_tile(x, y, &w, &h, ps))
       return;
 
-   pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+   pSrc = (const ubyte *) screen->surface_map(screen, ps,
+                                              PIPE_BUFFER_USAGE_CPU_READ);
+   assert(pSrc);                /* XXX: proper error handling! */
+
+   pSrc += (y * ps->pitch + x) * cpp;
    pDest = (ubyte *) p;
 
    for (i = 0; i < h; i++) {
@@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
       pSrc += src_stride;
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
@@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
                   uint x, uint y, uint w, uint h,
                   const void *p, int src_stride)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint cpp = ps->cpp;
    const ubyte *pSrc;
    const uint dst_stride = ps->pitch * cpp;
@@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe,
       return;
 
    pSrc = (const ubyte *) p;
-   pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+
+   pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+   assert(pDest);               /* XXX: proper error handling */
+
+   pDest += (y * ps->pitch + x) * cpp;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w * cpp);
@@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
       pSrc += src_stride;
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
@@ -834,18 +844,26 @@ pipe_get_tile_z(struct pipe_context *pipe,
                 uint x, uint y, uint w, uint h,
                 uint *z)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint dstStride = w;
+   void *map;
    uint *pDest = z;
    uint i, j;
 
    if (pipe_clip_tile(x, y, &w, &h, ps))
       return;
 
+   map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
+   if (!map) {
+      assert(0);
+      return;
+   }
+
    switch (ps->format) {
    case PIPE_FORMAT_Z32_UNORM:
       {
          const uint *pSrc
-            = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+            = (const uint *)map  + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             memcpy(pDest, pSrc, 4 * w);
             pDest += dstStride;
@@ -857,7 +875,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
    case PIPE_FORMAT_X8Z24_UNORM:
       {
          const uint *pSrc
-            = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+            = (const uint *)map + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             for (j = 0; j < w; j++) {
                /* convert 24-bit Z to 32-bit Z */
@@ -871,7 +889,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
    case PIPE_FORMAT_Z16_UNORM:
       {
          const ushort *pSrc
-            = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
+            = (const ushort *)map + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             for (j = 0; j < w; j++) {
                /* convert 16-bit Z to 32-bit Z */
@@ -886,7 +904,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
       assert(0);
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
@@ -896,17 +914,25 @@ pipe_put_tile_z(struct pipe_context *pipe,
                 uint x, uint y, uint w, uint h,
                 const uint *zSrc)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint srcStride = w;
    const uint *pSrc = zSrc;
+   void *map;
    uint i, j;
 
    if (pipe_clip_tile(x, y, &w, &h, ps))
       return;
 
+   map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+   if (!map) {
+      assert(0);
+      return;
+   }
+
    switch (ps->format) {
    case PIPE_FORMAT_Z32_UNORM:
       {
-         uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+         uint *pDest = (uint *) map + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             memcpy(pDest, pSrc, 4 * w);
             pDest += ps->pitch;
@@ -917,7 +943,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
    case PIPE_FORMAT_S8Z24_UNORM:
    case PIPE_FORMAT_X8Z24_UNORM:
       {
-         uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+         uint *pDest = (uint *) map + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             for (j = 0; j < w; j++) {
                /* convert 32-bit Z to 24-bit Z (0 stencil) */
@@ -930,7 +956,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
       break;
    case PIPE_FORMAT_Z16_UNORM:
       {
-         ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
+         ushort *pDest = (ushort *) map + (y * ps->pitch + x);
          for (i = 0; i < h; i++) {
             for (j = 0; j < w; j++) {
                /* convert 32-bit Z to 16-bit Z */
@@ -945,7 +971,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
       assert(0);
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
index 568d62ced190bf2dc48e39d86079f33902b6f922..999a3e50995e929aaf66601d9b04727d85f55855 100644 (file)
@@ -287,7 +287,8 @@ util_blit_pixels(struct blit_state *ctx,
    if (!tex)
       return;
 
-   texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0);
+   texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, 
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
 
    /* load temp texture */
    pipe->surface_copy(pipe, FALSE,
@@ -295,7 +296,9 @@ util_blit_pixels(struct blit_state *ctx,
                       src, srcLeft, srcTop, /* src */
                       srcW, srcH);     /* size */
 
-   pipe->texture_update(pipe, tex, 0, 1 << 0);
+   /* free the surface, update the texture if necessary.
+    */
+   screen->tex_surface_release(screen, &texSurf);
 
    /* save state (restored below) */
    cso_save_blend(ctx->cso);
@@ -356,8 +359,6 @@ util_blit_pixels(struct blit_state *ctx,
    cso_restore_vertex_shader(ctx->cso);
    cso_restore_viewport(ctx->cso);
 
-   /* free the texture */
-   pipe_surface_reference(&texSurf, NULL);
    screen->texture_release(screen, &tex);
 }
 
index e659edb0881013ce4a24eb3b905ccc73f8fa04c2..bf143815d8b762442df0dc3948ee964c124f69a7 100644 (file)
@@ -82,52 +82,51 @@ util_draw_texquad(struct pipe_context *pipe,
 {
    struct pipe_buffer *vbuf;
    uint numAttribs = 2, vertexBytes, i, j;
-   float *v;
 
    vertexBytes = 4 * (4 * numAttribs * sizeof(float));
 
    /* XXX create one-time */
    vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
                                       PIPE_BUFFER_USAGE_VERTEX, vertexBytes);
-   assert(vbuf);
-
-   v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
-                                          PIPE_BUFFER_USAGE_CPU_WRITE);
-
-   /*
-    * Load vertex buffer
-    */
-   for (i = j = 0; i < 4; i++) {
-      v[j + 2] = z;   /* z */
-      v[j + 3] = 1.0; /* w */
-      v[j + 6] = 0.0; /* r */
-      v[j + 7] = 1.0; /* q */
-      j += 8;
+   if (vbuf) {
+      float *v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
+                                             PIPE_BUFFER_USAGE_CPU_WRITE);
+      if (v) {
+         /*
+          * Load vertex buffer
+          */
+         for (i = j = 0; i < 4; i++) {
+            v[j + 2] = z;   /* z */
+            v[j + 3] = 1.0; /* w */
+            v[j + 6] = 0.0; /* r */
+            v[j + 7] = 1.0; /* q */
+            j += 8;
+         }
+
+         v[0] = x0;
+         v[1] = y0;
+         v[4] = 0.0; /*s*/
+         v[5] = 0.0; /*t*/
+
+         v[8] = x1;
+         v[9] = y0;
+         v[12] = 1.0;
+         v[13] = 0.0;
+
+         v[16] = x1;
+         v[17] = y1;
+         v[20] = 1.0;
+         v[21] = 1.0;
+
+         v[24] = x0;
+         v[25] = y1;
+         v[28] = 0.0;
+         v[29] = 1.0;
+
+         pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
+         util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+      }
+
+      pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
    }
-
-   v[0] = x0;
-   v[1] = y0;
-   v[4] = 0.0; /*s*/
-   v[5] = 0.0; /*t*/
-
-   v[8] = x1;
-   v[9] = y0;
-   v[12] = 1.0;
-   v[13] = 0.0;
-
-   v[16] = x1;
-   v[17] = y1;
-   v[20] = 1.0;
-   v[21] = 1.0;
-
-   v[24] = x0;
-   v[25] = y1;
-   v[28] = 0.0;
-   v[29] = 1.0;
-
-   pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
-
-   util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
-
-   pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
 }
index c53c51226818b54c839d5d8824ff4340923e41d8..7d71aefda9d88eb047c61a11c120733a626974f0 100644 (file)
@@ -589,8 +589,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
       struct pipe_surface *srcSurf, *dstSurf;
       void *srcMap, *dstMap;
       
-      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
-      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+
+      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
 
       srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
                                             PIPE_BUFFER_USAGE_CPU_READ)
@@ -629,8 +632,10 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
       struct pipe_surface *srcSurf, *dstSurf;
       ubyte *srcMap, *dstMap;
       
-      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
-      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
 
       srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
                                             PIPE_BUFFER_USAGE_CPU_READ)
@@ -891,10 +896,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
 
+      struct pipe_surface *surf = 
+         screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+                                 PIPE_BUFFER_USAGE_GPU_WRITE);
+
       /*
        * Setup framebuffer / dest surface
        */
-      fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+      fb.cbufs[0] = surf;
       fb.width = pt->width[dstLevel];
       fb.height = pt->height[dstLevel];
       cso_set_framebuffer(ctx->cso, &fb);
@@ -925,7 +934,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
       pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
       /* need to signal that the texture has changed _after_ rendering to it */
-      pipe->texture_update(pipe, pt, face, (1 << dstLevel));
+      pipe_surface_reference( &surf, NULL );
    }
 
    /* restore state we changed */
index f3f16a8d94f606f437f365927de4062a7addece8..dd5eca7fca357811d2fecf47a9f9d4ce5673df9e 100644 (file)
@@ -67,6 +67,13 @@ struct hash_table_item
 };
 
 
+static INLINE struct hash_table_item *
+hash_table_item(struct cso_hash_iter iter)
+{
+   return (struct hash_table_item *)cso_hash_iter_data(iter);
+}
+
+
 struct hash_table *
 hash_table_create(unsigned (*hash)(void *key),
                   int (*compare)(void *key1, void *key2))
@@ -90,7 +97,27 @@ hash_table_create(unsigned (*hash)(void *key),
 }
 
 
-static struct hash_table_item *
+static INLINE struct cso_hash_iter
+hash_table_find_iter(struct hash_table *ht,
+                     void *key, 
+                     unsigned key_hash)
+{
+   struct cso_hash_iter iter;
+   struct hash_table_item *item;
+   
+   iter = cso_hash_find(ht->cso, key_hash);
+   while (!cso_hash_iter_is_null(iter)) {
+      item = (struct hash_table_item *)cso_hash_iter_data(iter);
+      if (!ht->compare(item->key, key))
+         break;
+      iter = cso_hash_iter_next(iter);
+   }
+   
+   return iter;
+}
+
+
+static INLINE struct hash_table_item *
 hash_table_find_item(struct hash_table *ht,
                      void *key, 
                      unsigned key_hash)
@@ -117,6 +144,7 @@ hash_table_set(struct hash_table *ht,
 {
    unsigned key_hash;
    struct hash_table_item *item;
+   struct cso_hash_iter iter;
 
    assert(ht);
 
@@ -136,9 +164,8 @@ hash_table_set(struct hash_table *ht,
    item->key = key;
    item->value = value;
    
-   cso_hash_insert(ht->cso, key_hash, item);
-   /* FIXME: there is no OOM propagation in cso_hash */
-   if(0) {
+   iter = cso_hash_insert(ht->cso, key_hash, item);
+   if(cso_hash_iter_is_null(iter)) {
       FREE(item);
       return PIPE_ERROR_OUT_OF_MEMORY;
    }
@@ -171,19 +198,39 @@ hash_table_remove(struct hash_table *ht,
                   void *key)
 {
    unsigned key_hash;
+   struct cso_hash_iter iter;
    struct hash_table_item *item;
 
    assert(ht);
 
    key_hash = ht->hash(key);
 
-   item = hash_table_find_item(ht, key, key_hash);
-   if(!item)
+   iter = hash_table_find_iter(ht, key, key_hash);
+   if(cso_hash_iter_is_null(iter))
       return;
    
-   /* FIXME: cso_hash_take takes the first element of the collision list 
-    * indiscriminately, so we can not take the item down. */
-   item->value = NULL;
+   item = hash_table_item(iter);
+   assert(item);
+   FREE(item);
+   
+   cso_hash_erase(ht->cso, iter);
+}
+
+
+void 
+hash_table_clear(struct hash_table *ht)
+{
+   struct cso_hash_iter iter;
+   struct hash_table_item *item;
+
+   assert(ht);
+   
+   iter = cso_hash_first_node(ht->cso);
+   while (!cso_hash_iter_is_null(iter)) {
+      item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter));
+      FREE(item);
+      iter = cso_hash_first_node(ht->cso);
+   }
 }
 
 
@@ -196,6 +243,8 @@ hash_table_foreach(struct hash_table *ht,
    struct hash_table_item *item;
    enum pipe_error result;
    
+   assert(ht);
+   
    iter = cso_hash_first_node(ht->cso);
    while (!cso_hash_iter_is_null(iter)) {
       item = (struct hash_table_item *)cso_hash_iter_data(iter);
@@ -212,7 +261,17 @@ hash_table_foreach(struct hash_table *ht,
 void
 hash_table_destroy(struct hash_table *ht)
 {
+   struct cso_hash_iter iter;
+   struct hash_table_item *item;
+   
    assert(ht);
+   
+   iter = cso_hash_first_node(ht->cso);
+   while (!cso_hash_iter_is_null(iter)) {
+      item = (struct hash_table_item *)cso_hash_iter_data(iter);
+      FREE(item);
+      iter = cso_hash_iter_next(iter);
+   }
 
    cso_hash_delete(ht->cso);
    
index 1583bd7548c32b3be9d8680f5adc75a0da5fdc32..feee881582e1b891d456fcdc0be82d5bf917dbb0 100644 (file)
@@ -75,6 +75,10 @@ hash_table_remove(struct hash_table *ht,
                   void *key);
 
 
+void
+hash_table_clear(struct hash_table *ht);
+
+
 enum pipe_error
 hash_table_foreach(struct hash_table *ht,
                    enum pipe_error (*callback)(void *key, void *value, void *data),
index 0b917c005f1526b0a8c8770ec0db0f1bdcff154d..655e2c825925e6bc89db6c032650186fbb42c169 100644 (file)
@@ -101,6 +101,19 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
          *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
       }
       return;
+   case PIPE_FORMAT_A8_UNORM:
+      {
+         ubyte *d = (ubyte *) dest;
+         *d = a;
+      }
+      return;
+   case PIPE_FORMAT_L8_UNORM:
+   case PIPE_FORMAT_I8_UNORM:
+      {
+         ubyte *d = (ubyte *) dest;
+         *d = r;
+      }
+      return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       {
          float *d = (float *) dest;
@@ -198,6 +211,19 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
          *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
       }
       return;
+   case PIPE_FORMAT_A8_UNORM:
+      {
+         ubyte *d = (ubyte *) dest;
+         *d = a;
+      }
+      return;
+   case PIPE_FORMAT_L8_UNORM:
+   case PIPE_FORMAT_I8_UNORM:
+      {
+         ubyte *d = (ubyte *) dest;
+         *d = r;
+      }
+      return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       {
          float *d = (float *) dest;
index b99d4e8021cbb479521a46709365a47d11596b60..73c88d87b4c643c79d815ea674813b6a5b3f2cc3 100644 (file)
@@ -41,6 +41,8 @@
 #include <stddef.h>
 #include <stdarg.h>
 
+#include "pipe/p_compiler.h"
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -48,11 +50,129 @@ extern "C" {
 
    
 #ifdef WIN32
+   
 int util_vsnprintf(char *, size_t, const char *, va_list);
 int util_snprintf(char *str, size_t size, const char *format, ...);
+
+static INLINE void 
+util_vsprintf(char *str, const char *format, va_list ap)
+{
+   util_vsnprintf(str, (size_t)-1, format, ap);
+}
+
+static INLINE void 
+util_sprintf(char *str, const char *format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   util_vsnprintf(str, (size_t)-1, format, ap);
+   va_end(ap);
+}
+
+static INLINE char *
+util_strchr(const char *s, char c)
+{
+   while(*s) {
+      if(*s == c)
+        return (char *)s;
+      ++s;
+   }
+   return NULL;
+}
+
+static INLINE char*
+util_strncat(char *dst, const char *src, size_t n)
+{
+   char *p = dst + strlen(dst);
+   const char *q = src;
+   size_t i;
+
+   for (i = 0; i < n && *q != '\0'; ++i)
+       *p++ = *q++;
+   *p = '\0';
+
+   return dst;
+}
+
+static INLINE int
+util_strcmp(const char *s1, const char *s2)
+{
+   unsigned char u1, u2;
+
+   while (1) {
+      u1 = (unsigned char) *s1++;
+      u2 = (unsigned char) *s2++;
+      if (u1 != u2)
+        return u1 - u2;
+      if (u1 == '\0')
+        return 0;
+   }
+   return 0;
+}
+
+static INLINE int
+util_strncmp(const char *s1, const char *s2, size_t n)
+{
+   unsigned char u1, u2;
+
+   while (n-- > 0) {
+      u1 = (unsigned char) *s1++;
+      u2 = (unsigned char) *s2++;
+      if (u1 != u2)
+        return u1 - u2;
+      if (u1 == '\0')
+        return 0;
+   }
+   return 0;
+}
+
+static INLINE char *
+util_strstr(const char *haystack, const char *needle)
+{
+   const char *p = haystack;
+   int len = strlen(needle);
+
+   for (; (p = util_strchr(p, *needle)) != 0; p++) {
+      if (util_strncmp(p, needle, len) == 0) {
+        return (char *)p;
+      }
+   }
+   return NULL;
+}
+
+static INLINE void *
+util_memmove(void *dest, const void *src, size_t n)
+{
+   char *p = (char *)dest;
+   const char *q = (const char *)src;
+   if (dest < src) {
+      while (n--)
+        *p++ = *q++;
+   }
+   else
+   {
+      p += n;
+      q += n;
+      while (n--)
+        *--p = *--q;
+   }
+   return dest;
+}
+
+
 #else
+
 #define util_vsnprintf vsnprintf
 #define util_snprintf snprintf
+#define util_vsprintf vsprintf
+#define util_sprintf sprintf
+#define util_strchr strchr
+#define util_strcmp strcmp
+#define util_strncmp strncmp
+#define util_strncat strncat
+#define util_strstr strstr
+#define util_memmove memmove
+
 #endif
 
 
index cb95ba516f905b09cecc9f7c1c4cb96d22523f15..014a3e31d5055a3cb27792a609f60264380aa7b8 100644 (file)
@@ -147,8 +147,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
    failover->pipe.texture_create = hw->texture_create;
    failover->pipe.texture_release = hw->texture_release;
    failover->pipe.get_tex_surface = hw->get_tex_surface;
-#endif
    failover->pipe.texture_update = hw->texture_update;
+#endif
 
    failover->pipe.flush = hw->flush;
 
index 646cfd921d1698f6889bba57e49cf4c2ef831c65..ba8f183bdf022586d6f84a1aea1fec22f0da3f43 100644 (file)
@@ -201,6 +201,35 @@ i915_destroy_screen( struct pipe_screen *screen )
 }
 
 
+static void *
+i915_surface_map( struct pipe_screen *screen,
+                  struct pipe_surface *surface,
+                  unsigned flags )
+{
+   char *map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags );
+   if (map == NULL)
+      return NULL;
+
+   if (surface->texture &&
+       (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) 
+   {
+      /* Do something to notify contexts of a texture change.  
+       */
+      /* i915_screen(screen)->timestamp++; */
+   }
+   
+   return map + surface->offset;
+}
+
+static void
+i915_surface_unmap(struct pipe_screen *screen,
+                   struct pipe_surface *surface)
+{
+   screen->winsys->buffer_unmap( screen->winsys, surface->buffer );
+}
+
+
+
 /**
  * Create a new i915_screen object
  */
@@ -244,6 +273,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
    i915screen->screen.get_param = i915_get_param;
    i915screen->screen.get_paramf = i915_get_paramf;
    i915screen->screen.is_format_supported = i915_is_format_supported;
+   i915screen->screen.surface_map = i915_surface_map;
+   i915screen->screen.surface_unmap = i915_surface_unmap;
 
    i915_init_screen_texture_functions(&i915screen->screen);
 
index f4fbedbe9bc07166f1b2f30847099f4893a27614..98367ac0739a6e360bec4841fbfa8a933a507245 100644 (file)
@@ -51,17 +51,25 @@ i915_surface_copy(struct pipe_context *pipe,
    assert( dst->cpp == src->cpp );
 
    if (0) {
-      pipe_copy_rect(pipe_surface_map(dst),
+      void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                                 dst,
+                                                 PIPE_BUFFER_USAGE_CPU_WRITE );
+      
+      const void *src_map = pipe->screen->surface_map( pipe->screen,
+                                                       src,
+                                                       PIPE_BUFFER_USAGE_CPU_READ );
+      
+      pipe_copy_rect(dst_map,
                      dst->cpp,
                      dst->pitch,
                      dstx, dsty, 
                      width, height, 
-                     pipe_surface_map(src)
+                     src_map
                      do_flip ? -(int) src->pitch : src->pitch, 
                      srcx, do_flip ? 1 - srcy - height : srcy);
 
-      pipe_surface_unmap(src);
-      pipe_surface_unmap(dst);
+      pipe->screen->surface_unmap(pipe->screen, src);
+      pipe->screen->surface_unmap(pipe->screen, dst);
    }
    else {
       i915_copy_blit( i915_context(pipe),
@@ -92,7 +100,10 @@ i915_surface_fill(struct pipe_context *pipe,
 {
    if (0) {
       unsigned i, j;
-      void *dst_map = pipe_surface_map(dst);
+      void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                                 dst,
+                                                 PIPE_BUFFER_USAGE_CPU_WRITE );
+
 
       switch (dst->cpp) {
       case 1: {
@@ -126,7 +137,7 @@ i915_surface_fill(struct pipe_context *pipe,
         break;
       }
 
-      pipe_surface_unmap( dst );
+      pipe->screen->surface_unmap(pipe->screen, dst);
    }
    else {
       i915_fill_blit( i915_context(pipe),
index c39e747705b040243608b4017a0e76b0b7df217d..3e23e540f9d57e432a8ae19c0c983173e163dfc1 100644 (file)
@@ -105,6 +105,51 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
 }
 
 
+/* Hack it up to use the old winsys->surface_alloc_storage()
+ * method for now:
+ */
+static boolean
+i915_displaytarget_layout(struct pipe_screen *screen,
+                          struct i915_texture *tex)
+{
+   struct pipe_winsys *ws = screen->winsys;
+   struct pipe_surface surf;
+   unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
+                     PIPE_BUFFER_USAGE_CPU_WRITE |
+                     PIPE_BUFFER_USAGE_GPU_READ |
+                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+   memset(&surf, 0, sizeof(surf));
+
+   ws->surface_alloc_storage( ws, 
+                              &surf,
+                              tex->base.width[0], 
+                              tex->base.height[0],
+                              tex->base.format,
+                              flags,
+                              tex->base.tex_usage);
+      
+   /* Now extract the goodies: 
+    */
+   i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
+   i915_miptree_set_level_info( tex, 0, 0, 0, 0, 
+                                tex->base.width[0],
+                                tex->base.height[0],
+                                1 );
+
+   tex->buffer = surf.buffer;
+   tex->pitch = surf.pitch;
+   tex->total_height = 0;
+
+
+   return tex->buffer != NULL;
+}
+
+
+
+
+
 static void
 i945_miptree_layout_2d( struct i915_texture *tex )
 {
@@ -483,30 +528,45 @@ static struct pipe_texture *
 i915_texture_create_screen(struct pipe_screen *screen,
                            const struct pipe_texture *templat)
 {
+   struct i915_screen *i915screen = i915_screen(screen);
+   struct pipe_winsys *ws = screen->winsys;
    struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
 
-   if (tex) {
-      struct i915_screen *i915screen = i915_screen(screen);
-      struct pipe_winsys *ws = screen->winsys;
-
-      tex->base = *templat;
-      tex->base.refcount = 1;
-      tex->base.screen = screen;
+   if (!tex) 
+      return NULL;
 
-      if (i915screen->is_i945 ? i945_miptree_layout(tex) :
-         i915_miptree_layout(tex))
-        tex->buffer = ws->buffer_create(ws, 64,
-                                         PIPE_BUFFER_USAGE_PIXEL,
-                                         tex->pitch * tex->base.cpp *
-                                         tex->total_height);
+   tex->base = *templat;
+   tex->base.refcount = 1;
+   tex->base.screen = screen;
 
-      if (!tex->buffer) {
-        FREE(tex);
-        return NULL;
+   if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+      if (!i915_displaytarget_layout(screen, tex))
+         goto fail;
+   }
+   else {
+      if (i915screen->is_i945) {
+         if (!i945_miptree_layout(tex))
+            goto fail;
+      }
+      else {
+         if (!i915_miptree_layout(tex))
+            goto fail;
       }
+      
+      tex->buffer = ws->buffer_create(ws, 64,
+                                      PIPE_BUFFER_USAGE_PIXEL,
+                                      tex->pitch * tex->base.cpp *
+                                      tex->total_height);
+
+      if (!tex->buffer) 
+         goto fail;
    }
 
    return &tex->base;
+
+ fail:
+   FREE(tex);
+   return NULL;
 }
 
 
@@ -541,13 +601,6 @@ i915_texture_release_screen(struct pipe_screen *screen,
 }
 
 
-static void
-i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
-                    uint face, uint levelsMask)
-{
-   /* no-op? */
-}
-
 
 /*
  * XXX note: same as code in sp_surface.c
@@ -555,7 +608,8 @@ i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
 static struct pipe_surface *
 i915_get_tex_surface_screen(struct pipe_screen *screen,
                             struct pipe_texture *pt,
-                            unsigned face, unsigned level, unsigned zslice)
+                            unsigned face, unsigned level, unsigned zslice,
+                            unsigned flags)
 {
    struct i915_texture *tex = (struct i915_texture *)pt;
    struct pipe_winsys *ws = screen->winsys;
@@ -586,6 +640,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen,
       ps->height = pt->height[level];
       ps->pitch = tex->pitch;
       ps->offset = offset;
+      ps->usage = flags;
    }
    return ps;
 }
@@ -594,7 +649,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen,
 void
 i915_init_texture_functions(struct i915_context *i915)
 {
-   i915->pipe.texture_update = i915_texture_update;
+//   i915->pipe.texture_update = i915_texture_update;
 }
 
 
index c99a91dcf76478f61ddf83af81f40a2309edbe56..3e3736b28065cac9df63fab4e55ae6e878128a3e 100644 (file)
 #include "util/p_tile.h"
 
 
-/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-static void
-brw_surface_data(struct pipe_context *pipe,
-                 struct pipe_surface *dst,
-                 unsigned dstx, unsigned dsty,
-                 const void *src, unsigned src_pitch,
-                 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
-   pipe_copy_rect(pipe_surface_map(dst) + dst->offset,
-                  dst->cpp, dst->pitch,
-                  dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
-   pipe_surface_unmap(dst);
-}
-
 
 /* Assumes all values are within bounds -- no checking at this level -
  * do it higher up if required.
@@ -72,17 +51,25 @@ brw_surface_copy(struct pipe_context *pipe,
    assert(dst->cpp == src->cpp);
 
    if (0) {
-      pipe_copy_rect(pipe_surface_map(dst) + dst->offset,
+      void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                                 dst,
+                                                 PIPE_BUFFER_USAGE_CPU_WRITE );
+      
+      const void *src_map = pipe->screen->surface_map( pipe->screen,
+                                                       src,
+                                                       PIPE_BUFFER_USAGE_CPU_READ );
+      
+      pipe_copy_rect(dst_map,
                      dst->cpp,
                      dst->pitch,
-                     dstx, dsty,
-                     width, height,
-                     pipe_surface_map(src) + src->offset,
-                     do_flip ? -src->pitch : src->pitch,
+                     dstx, dsty, 
+                     width, height, 
+                     src_map, 
+                     do_flip ? -(int) src->pitch : src->pitch, 
                      srcx, do_flip ? 1 - srcy - height : srcy);
 
-      pipe_surface_unmap(src);
-      pipe_surface_unmap(dst);
+      pipe->screen->surface_unmap(pipe->screen, src);
+      pipe->screen->surface_unmap(pipe->screen, dst);
    }
    else {
       brw_copy_blit(brw_context(pipe),
@@ -113,7 +100,10 @@ brw_surface_fill(struct pipe_context *pipe,
 {
    if (0) {
       unsigned i, j;
-      void *dst_map = pipe_surface_map(dst);
+      void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                                 dst,
+                                                 PIPE_BUFFER_USAGE_CPU_WRITE );
+
 
       switch (dst->cpp) {
       case 1: {
@@ -147,7 +137,7 @@ brw_surface_fill(struct pipe_context *pipe,
         break;
       }
 
-      pipe_surface_unmap( dst );
+      pipe->screen->surface_unmap(pipe->screen, dst);
    }
    else {
       brw_fill_blit(brw_context(pipe),
@@ -164,7 +154,6 @@ brw_surface_fill(struct pipe_context *pipe,
 void
 brw_init_surface_functions(struct brw_context *brw)
 {
-   (void) brw_surface_data; /* silence warning */
    brw->pipe.surface_copy  = brw_surface_copy;
    brw->pipe.surface_fill  = brw_surface_fill;
 }
index b580f98204c745c19fd6e729f43aec4590c4bcc8..78ae0b1223e25362aca3abb39af738b058de2a8e 100644 (file)
@@ -357,14 +357,6 @@ brw_texture_release_screen(struct pipe_screen *screen,
 }
 
 
-static void
-brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
-                   uint face, uint levelsMask)
-{
-   /* no-op? */
-}
-
-
 static struct pipe_surface *
 brw_get_tex_surface_screen(struct pipe_screen *screen,
                            struct pipe_texture *pt,
@@ -407,7 +399,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen,
 void
 brw_init_texture_functions(struct brw_context *brw)
 {
-   brw->pipe.texture_update = brw_texture_update;
+//   brw->pipe.texture_update = brw_texture_update;
 }
 
 
index fe9cd8375e39ef26175d869e48629a43c22f13e5..2af0db37143752f521c5b6cdeb3457707e30aa0e 100644 (file)
@@ -192,11 +192,11 @@ softpipe_create( struct pipe_screen *screen,
     * Must be before quad stage setup!
     */
    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
-      softpipe->cbuf_cache[i] = sp_create_tile_cache();
-   softpipe->zsbuf_cache = sp_create_tile_cache();
+      softpipe->cbuf_cache[i] = sp_create_tile_cache( screen );
+   softpipe->zsbuf_cache = sp_create_tile_cache( screen );
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-      softpipe->tex_cache[i] = sp_create_tile_cache();
+      softpipe->tex_cache[i] = sp_create_tile_cache( screen );
 
 
    /* setup quad rendering stages */
index 0625b69099b084e378970ed84bb4f37f64bae712..e03994b63b76a53e7ff12afc4145b8b8170f6a90 100644 (file)
@@ -50,25 +50,28 @@ softpipe_flush( struct pipe_context *pipe,
 
    draw_flush(softpipe->draw);
 
-   /* - flush the quad pipeline
-    * - flush the texture cache
-    * - flush the render cache
-    */
+   if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+      for (i = 0; i < softpipe->num_textures; i++) {
+         sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]);
+      }
+   }
 
-   for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
-      if (softpipe->cbuf_cache[i])
-         sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
+   if (flags & PIPE_FLUSH_RENDER_CACHE) {
+      for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
+         if (softpipe->cbuf_cache[i])
+            sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
 
-   if (softpipe->zsbuf_cache)
-      sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
+      if (softpipe->zsbuf_cache)
+         sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
 
-   /* Need this call for hardware buffers before swapbuffers.
-    *
-    * there should probably be another/different flush-type function
-    * that's called before swapbuffers because we don't always want
-    * to unmap surfaces when flushing.
-    */
-   softpipe_unmap_surfaces(softpipe);
+      /* Need this call for hardware buffers before swapbuffers.
+       *
+       * there should probably be another/different flush-type function
+       * that's called before swapbuffers because we don't always want
+       * to unmap surfaces when flushing.
+       */
+      softpipe_unmap_surfaces(softpipe);
+   }
 
    if (fence)
       *fence = NULL;
index 7dacb1c461378ca5c104935789d5c8749d047c0c..e9926bf41f93bc54a3886fd58056e28804e05499 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "sp_texture.h"
 #include "sp_winsys.h"
+#include "sp_screen.h"
 
 
 static const char *
@@ -137,6 +138,7 @@ softpipe_destroy_screen( struct pipe_screen *screen )
 }
 
 
+
 /**
  * Create a new pipe_screen object
  * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
@@ -144,22 +146,22 @@ softpipe_destroy_screen( struct pipe_screen *screen )
 struct pipe_screen *
 softpipe_create_screen(struct pipe_winsys *winsys)
 {
-   struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+   struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
 
    if (!screen)
       return NULL;
 
-   screen->winsys = winsys;
+   screen->base.winsys = winsys;
 
-   screen->destroy = softpipe_destroy_screen;
+   screen->base.destroy = softpipe_destroy_screen;
 
-   screen->get_name = softpipe_get_name;
-   screen->get_vendor = softpipe_get_vendor;
-   screen->get_param = softpipe_get_param;
-   screen->get_paramf = softpipe_get_paramf;
-   screen->is_format_supported = softpipe_is_format_supported;
+   screen->base.get_name = softpipe_get_name;
+   screen->base.get_vendor = softpipe_get_vendor;
+   screen->base.get_param = softpipe_get_param;
+   screen->base.get_paramf = softpipe_get_paramf;
+   screen->base.is_format_supported = softpipe_is_format_supported;
 
-   softpipe_init_screen_texture_funcs(screen);
+   softpipe_init_screen_texture_funcs(&screen->base);
 
-   return screen;
+   return &screen->base;
 }
diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h
new file mode 100644 (file)
index 0000000..3d4bfd3
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_SCREEN_H
+#define SP_SCREEN_H
+
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
+
+
+
+struct softpipe_screen {
+   struct pipe_screen base;
+
+   /* Increments whenever textures are modified.  Contexts can track
+    * this.
+    */
+   unsigned timestamp;          
+};
+
+
+
+
+static INLINE struct softpipe_screen *
+softpipe_screen( struct pipe_screen *pipe )
+{
+   return (struct softpipe_screen *)pipe;
+}
+
+
+#endif /* SP_SCREEN_H */
index 653449c4f182473a25f02d642bb8753c1545ed33..29a1e92416ee15e1f9b470868dcfb9af1200d32f 100644 (file)
@@ -46,19 +46,28 @@ sp_surface_copy(struct pipe_context *pipe,
                struct pipe_surface *src,
                unsigned srcx, unsigned srcy, unsigned width, unsigned height)
 {
+   void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                              dst,
+                                              PIPE_BUFFER_USAGE_CPU_WRITE );
+
+   const void *src_map = pipe->screen->surface_map( pipe->screen,
+                                                    src,
+                                                    PIPE_BUFFER_USAGE_CPU_READ );
+
    assert( dst->cpp == src->cpp );
+   assert(src_map && dst_map);
 
-   pipe_copy_rect(pipe_surface_map(dst),
+   pipe_copy_rect(dst_map,
                   dst->cpp,
                   dst->pitch,
                   dstx, dsty,
                   width, height,
-                  pipe_surface_map(src),
+                  src_map,
                   do_flip ? -(int) src->pitch : src->pitch,
                   srcx, do_flip ? 1 - srcy - height : srcy);
 
-   pipe_surface_unmap(src);
-   pipe_surface_unmap(dst);
+   pipe->screen->surface_unmap(pipe->screen, src);
+   pipe->screen->surface_unmap(pipe->screen, dst);
 }
 
 
@@ -83,7 +92,9 @@ sp_surface_fill(struct pipe_context *pipe,
                unsigned width, unsigned height, unsigned value)
 {
    unsigned i, j;
-   void *dst_map = pipe_surface_map(dst);
+   void *dst_map = pipe->screen->surface_map( pipe->screen,
+                                              dst,
+                                              PIPE_BUFFER_USAGE_CPU_WRITE );
 
    assert(dst->pitch > 0);
    assert(width <= dst->pitch);
@@ -147,7 +158,7 @@ sp_surface_fill(struct pipe_context *pipe,
       break;
    }
 
-   pipe_surface_unmap( dst );
+   pipe->screen->surface_unmap(pipe->screen, dst);
 }
 
 
index 256586ec886e8026301cd3d6bff068ce4705ccc2..1d7a1fffe4da3ba16a7bd04761aed65c726f4cbe 100644 (file)
@@ -40,6 +40,7 @@
 #include "sp_state.h"
 #include "sp_texture.h"
 #include "sp_tile_cache.h"
+#include "sp_screen.h"
 
 
 /* Simple, maximally packed layout.
@@ -51,40 +52,88 @@ static unsigned minify( unsigned d )
 }
 
 
-static void
-softpipe_texture_layout(struct softpipe_texture * spt)
+/* Conventional allocation path for non-display textures:
+ */
+static boolean
+softpipe_texture_layout(struct pipe_screen *screen,
+                        struct softpipe_texture * spt)
 {
+   struct pipe_winsys *ws = screen->winsys;
    struct pipe_texture *pt = &spt->base;
    unsigned level;
    unsigned width = pt->width[0];
    unsigned height = pt->height[0];
    unsigned depth = pt->depth[0];
 
-   spt->buffer_size = 0;
+   unsigned buffer_size = 0;
 
    for (level = 0; level <= pt->last_level; level++) {
       pt->width[level] = width;
       pt->height[level] = height;
       pt->depth[level] = depth;
+      spt->pitch[level] = width;
 
-      spt->level_offset[level] = spt->buffer_size;
+      spt->level_offset[level] = buffer_size;
 
-      spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
-                         ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
-                         width * pt->cpp;
+      buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) *
+                      ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
+                      width * pt->cpp);
 
       width  = minify(width);
       height = minify(height);
       depth = minify(depth);
    }
+
+   spt->buffer = ws->buffer_create(ws, 32,
+                                   PIPE_BUFFER_USAGE_PIXEL,
+                                   buffer_size);
+
+   return spt->buffer != NULL;
+}
+
+
+
+/* Hack it up to use the old winsys->surface_alloc_storage()
+ * method for now:
+ */
+static boolean
+softpipe_displaytarget_layout(struct pipe_screen *screen,
+                              struct softpipe_texture * spt)
+{
+   struct pipe_winsys *ws = screen->winsys;
+   struct pipe_surface surf;
+   unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
+                     PIPE_BUFFER_USAGE_CPU_WRITE |
+                     PIPE_BUFFER_USAGE_GPU_READ |
+                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+   memset(&surf, 0, sizeof(surf));
+
+   ws->surface_alloc_storage( ws, 
+                              &surf,
+                              spt->base.width[0], 
+                              spt->base.height[0],
+                              spt->base.format,
+                              flags,
+                              spt->base.tex_usage);
+      
+   /* Now extract the goodies: 
+    */
+   spt->buffer = surf.buffer;
+   spt->pitch[0] = surf.pitch;
+
+   return spt->buffer != NULL;
 }
 
 
+
+
+
 static struct pipe_texture *
 softpipe_texture_create(struct pipe_screen *screen,
                         const struct pipe_texture *templat)
 {
-   struct pipe_winsys *ws = screen->winsys;
    struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
    if (!spt)
       return NULL;
@@ -93,19 +142,21 @@ softpipe_texture_create(struct pipe_screen *screen,
    spt->base.refcount = 1;
    spt->base.screen = screen;
 
-   softpipe_texture_layout(spt);
-
-   spt->buffer = ws->buffer_create(ws, 32,
-                                   PIPE_BUFFER_USAGE_PIXEL,
-                                   spt->buffer_size);
-   if (!spt->buffer) {
-      FREE(spt);
-      return NULL;
+   if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+      if (!softpipe_displaytarget_layout(screen, spt))
+         goto fail;
    }
-
+   else {
+      if (!softpipe_texture_layout(screen, spt))
+         goto fail;
+   }
+    
    assert(spt->base.refcount == 1);
-
    return &spt->base;
+
+ fail:
+   FREE(spt);
+   return NULL;
 }
 
 
@@ -116,19 +167,10 @@ softpipe_texture_release(struct pipe_screen *screen,
    if (!*pt)
       return;
 
-   /*
-   DBG("%s %p refcount will be %d\n",
-       __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
-   */
    if (--(*pt)->refcount <= 0) {
       struct softpipe_texture *spt = softpipe_texture(*pt);
 
-      /*
-      DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
-      */
-
       pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
-
       FREE(spt);
    }
    *pt = NULL;
@@ -138,7 +180,8 @@ softpipe_texture_release(struct pipe_screen *screen,
 static struct pipe_surface *
 softpipe_get_tex_surface(struct pipe_screen *screen,
                          struct pipe_texture *pt,
-                         unsigned face, unsigned level, unsigned zslice)
+                         unsigned face, unsigned level, unsigned zslice,
+                         unsigned usage)
 {
    struct pipe_winsys *ws = screen->winsys;
    struct softpipe_texture *spt = softpipe_texture(pt);
@@ -157,6 +200,24 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
       ps->height = pt->height[level];
       ps->pitch = ps->width;
       ps->offset = spt->level_offset[level];
+      ps->usage = usage;
+      
+      /* Because we are softpipe, anything that the state tracker
+       * thought was going to be done with the GPU will actually get
+       * done with the CPU.  Let's adjust the flags to take that into
+       * account.
+       */
+      if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+         ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE;
+
+      if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
+         ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
+
+      pipe_texture_reference(&ps->texture, pt); 
+      ps->face = face;
+      ps->level = level;
+      ps->zslice = zslice;
 
       if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
         ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
@@ -172,25 +233,64 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
 }
 
 
-static void
-softpipe_texture_update(struct pipe_context *pipe,
-                        struct pipe_texture *texture,
-                        uint face, uint levelsMask)
+static void 
+softpipe_tex_surface_release(struct pipe_screen *screen, 
+                             struct pipe_surface **s)
 {
-   struct softpipe_context *softpipe = softpipe_context(pipe);
-   uint unit;
-   for (unit = 0; unit < softpipe->num_textures; unit++) {
-      if (softpipe->texture[unit] == texture) {
-         sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
-      }
+   /* Effectively do the texture_update work here - if texture images
+    * needed post-processing to put them into hardware layout, this is
+    * where it would happen.  For softpipe, nothing to do.
+    */
+   assert ((*s)->texture);
+   pipe_texture_reference(&(*s)->texture, NULL); 
+
+   screen->winsys->surface_release(screen->winsys, s);
+}
+
+
+static void *
+softpipe_surface_map( struct pipe_screen *screen,
+                      struct pipe_surface *surface,
+                      unsigned flags )
+{
+   ubyte *map;
+
+   if (flags & ~surface->usage) {
+      assert(0);
+      return NULL;
+   }
+
+   map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags );
+   if (map == NULL)
+      return NULL;
+
+   /* May want to different things here depending on read/write nature
+    * of the map:
+    */
+   if (surface->texture &&
+       (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) 
+   {
+      /* Do something to notify sharing contexts of a texture change.
+       * In softpipe, that would mean flushing the texture cache.
+       */
+      softpipe_screen(screen)->timestamp++;
    }
+   
+   return map + surface->offset;
+}
+
+
+static void
+softpipe_surface_unmap(struct pipe_screen *screen,
+                       struct pipe_surface *surface)
+{
+   screen->winsys->buffer_unmap( screen->winsys, surface->buffer );
 }
 
 
 void
-softpipe_init_texture_funcs( struct softpipe_context *softpipe )
+softpipe_init_texture_funcs(struct softpipe_context *sp)
 {
-   softpipe->pipe.texture_update = softpipe_texture_update;
 }
 
 
@@ -199,5 +299,10 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
 {
    screen->texture_create = softpipe_texture_create;
    screen->texture_release = softpipe_texture_release;
+
    screen->get_tex_surface = softpipe_get_tex_surface;
+   screen->tex_surface_release = softpipe_tex_surface_release;
+
+   screen->surface_map = softpipe_surface_map;
+   screen->surface_unmap = softpipe_surface_unmap;
 }
index a7322144e6f7f857567747c68c537b753dc5350c..779a9d8fc970c0bf070886fe312858b44aa4a235 100644 (file)
@@ -42,11 +42,11 @@ struct softpipe_texture
    struct pipe_texture base;
 
    unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+   unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
 
    /* The data is held here:
     */
    struct pipe_buffer *buffer;
-   unsigned long buffer_size;
 };
 
 
@@ -61,7 +61,6 @@ softpipe_texture(struct pipe_texture *pt)
 extern void
 softpipe_init_texture_funcs( struct softpipe_context *softpipe );
 
-
 extern void
 softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
 
index 1117c0ad4c7a364c02020df17a784db24e144c05..28c29da87c9079edebb7bc18d55aaa8be5933cf3 100644 (file)
@@ -49,6 +49,7 @@
 
 struct softpipe_tile_cache
 {
+   struct pipe_screen *screen;
    struct pipe_surface *surface;  /**< the surface we're caching */
    void *surface_map;
    struct pipe_texture *texture;  /**< if caching a texture */
@@ -109,13 +110,14 @@ clear_clear_flag(uint *bitvec, int x, int y)
    
 
 struct softpipe_tile_cache *
-sp_create_tile_cache(void)
+sp_create_tile_cache( struct pipe_screen *screen )
 {
    struct softpipe_tile_cache *tc;
    uint pos;
 
    tc = CALLOC_STRUCT( softpipe_tile_cache );
    if (tc) {
+      tc->screen = screen;
       for (pos = 0; pos < NUM_ENTRIES; pos++) {
          tc->entries[pos].x =
          tc->entries[pos].y = -1;
@@ -154,16 +156,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
    assert(!tc->texture);
 
    if (tc->surface_map) {
-      /*assert(tc->surface != ps);*/
-      pipe_surface_unmap(tc->surface);
+      tc->screen->surface_unmap(tc->screen, tc->surface);
       tc->surface_map = NULL;
    }
 
    pipe_surface_reference(&tc->surface, ps);
 
-   if (ps) {
-      if (tc->surface_map)
-        tc->surface_map = pipe_surface_map(ps);
+   if (tc->surface) {
+      if (tc->surface_map) /* XXX: this is always NULL!? */
+        tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+                                                   PIPE_BUFFER_USAGE_CPU_READ | 
+                                                   PIPE_BUFFER_USAGE_CPU_WRITE);
 
       tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
                            ps->format == PIPE_FORMAT_Z16_UNORM ||
@@ -187,10 +190,13 @@ void
 sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc)
 {
    if (tc->surface && !tc->surface_map)
-      tc->surface_map = pipe_surface_map(tc->surface);
+      tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+                                                PIPE_BUFFER_USAGE_CPU_WRITE |
+                                                PIPE_BUFFER_USAGE_CPU_READ);
 
    if (tc->tex_surf && !tc->tex_surf_map)
-      tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+      tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf,
+                                                 PIPE_BUFFER_USAGE_CPU_READ);
 }
 
 
@@ -198,12 +204,12 @@ void
 sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
 {
    if (tc->surface_map) {
-      pipe_surface_unmap(tc->surface);
+      tc->screen->surface_unmap(tc->screen, tc->surface);
       tc->surface_map = NULL;
    }
 
    if (tc->tex_surf_map) {
-      pipe_surface_unmap(tc->tex_surf);
+      tc->screen->surface_unmap(tc->screen, tc->tex_surf);
       tc->tex_surf_map = NULL;
    }
 }
@@ -224,7 +230,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe,
    pipe_texture_reference(&tc->texture, texture);
 
    if (tc->tex_surf_map) {
-      pipe_surface_unmap(tc->tex_surf);
+      tc->screen->surface_unmap(tc->screen, tc->tex_surf);
       tc->tex_surf_map = NULL;
    }
    pipe_surface_reference(&tc->tex_surf, NULL);
@@ -514,10 +520,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
          /* get new surface (view into texture) */
 
         if (tc->tex_surf_map)
-            pipe_surface_unmap(tc->tex_surf);
+            tc->screen->surface_unmap(tc->screen, tc->tex_surf);
 
-         tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z);
-         tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+         tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, 
+                                                PIPE_BUFFER_USAGE_CPU_READ);
+         tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf,
+                                                PIPE_BUFFER_USAGE_CPU_READ);
 
          tc->tex_face = face;
          tc->tex_level = level;
index 2631e29a3a6620dcac80b1ad397dcefee40bf2b2..bc96c941f61887d4b44e199a7cd639410a1c9258 100644 (file)
@@ -61,7 +61,7 @@ struct softpipe_cached_tile
 
 
 extern struct softpipe_tile_cache *
-sp_create_tile_cache(void);
+sp_create_tile_cache( struct pipe_screen *screen );
 
 extern void
 sp_destroy_tile_cache(struct softpipe_tile_cache *tc);
index f3a9c2cd8b27e5da451240a581f1799ad27ecc69..0f68f592f77072859276bc78c17147a7cbc8b4b0 100644 (file)
@@ -198,12 +198,6 @@ struct pipe_context {
    /*@}*/
 
 
-   /** Called when texture data is changed */
-   void (*texture_update)(struct pipe_context *pipe,
-                          struct pipe_texture *texture,
-                          uint face, uint dirtyLevelsMask);
-
-
    /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
    void (*flush)( struct pipe_context *pipe,
                   unsigned flags,
index 7a7312ea1228dbeb37c81c893da8355fc90e4852..1263d0da6195ef38559a9677992095bc49098373 100644 (file)
@@ -313,6 +313,17 @@ void
 debug_memory_end(unsigned long beginning);
 
 
+#ifdef DEBUG
+void debug_dump_image(const char *prefix,
+                      unsigned format, unsigned cpp,
+                      unsigned width, unsigned height,
+                      unsigned pitch,
+                      const void *data);
+#else
+#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0)
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
index 46a355daa216038aa31fa92e177b23bc2779459e..83330ef22febd7adaaa4d528232abdaa148e5016 100644 (file)
@@ -173,6 +173,12 @@ enum pipe_texture_target {
 #define PIPE_SURFACE        2  /**< user-created surfaces */
 
 
+/**
+ * Surface layout
+ */
+#define PIPE_SURFACE_LAYOUT_LINEAR  0
+
+
 /**
  * Surface status
  */
index 8eb604e73f1c5e42f267f13820ab6b64bdcb605a..1e4b98edb4883eca0c05794968ae00e87e5807e7 100644 (file)
@@ -39,21 +39,40 @@ extern "C" {
 #endif
 
 
+/* XXX: these are a kludge.  will fix when all surfaces are views into
+ * textures, and free-floating winsys surfaces go away.
+ */
 static INLINE void *
-pipe_surface_map(struct pipe_surface *surface)
+pipe_surface_map( struct pipe_surface *surf, unsigned flags )
 {
-   return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer,
-                                              PIPE_BUFFER_USAGE_CPU_WRITE |
-                                              PIPE_BUFFER_USAGE_CPU_READ )
-      + surface->offset;
+   if (surf->texture) {
+      struct pipe_screen *screen = surf->texture->screen;
+      return surf->texture->screen->surface_map( screen, surf, flags );
+   }
+   else {
+      struct pipe_winsys *winsys = surf->winsys;
+      char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags );
+      if (map == NULL)
+         return NULL;
+      return (void *)(map + surf->offset);
+   }
 }
 
 static INLINE void
-pipe_surface_unmap(struct pipe_surface *surface)
+pipe_surface_unmap( struct pipe_surface *surf )
 {
-   surface->winsys->buffer_unmap( surface->winsys, surface->buffer );
+   if (surf->texture) {
+      struct pipe_screen *screen = surf->texture->screen;
+      surf->texture->screen->surface_unmap( screen, surf );
+   }
+   else {
+      struct pipe_winsys *winsys = surf->winsys;
+      winsys->buffer_unmap( winsys, surf->buffer );
+   }
 }
 
+
+
 /**
  * Set 'ptr' to point to 'surf' and update reference counting.
  * The old thing pointed to, if any, will be unreferenced first.
@@ -66,9 +85,20 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
    if (surf) 
       surf->refcount++;
 
-   if (*ptr /* && --(*ptr)->refcount == 0 */) {
-      struct pipe_winsys *winsys = (*ptr)->winsys;
-      winsys->surface_release(winsys, ptr);
+   if (*ptr) {
+
+      /* There are currently two sorts of surfaces... This needs to be
+       * fixed so that all surfaces are views into a texture.
+       */
+      if ((*ptr)->texture) {
+         struct pipe_screen *screen = (*ptr)->texture->screen;
+         screen->tex_surface_release( screen, ptr );
+      }
+      else {
+         struct pipe_winsys *winsys = (*ptr)->winsys;
+         winsys->surface_release(winsys, ptr);
+      }
+
       assert(!*ptr);
    }
 
index 26ac99d287d4bfe87e8b0bbcbb7f3bf5ffe3a4fb..cc8430dae1695c90295bf3b0e85332660f9902f1 100644 (file)
@@ -89,6 +89,18 @@ struct pipe_screen {
    struct pipe_texture * (*texture_create)(struct pipe_screen *,
                                            const struct pipe_texture *templat);
 
+   /**
+    * Create a new texture object, using the given template info, but on top of 
+    * existing memory.
+    * 
+    * It is assumed that the buffer data is layed out according to the expected
+    * by the hardware. NULL will be returned if any inconsistency is found.  
+    */
+   struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
+                                            const struct pipe_texture *templat,
+                                            const unsigned *pitch,
+                                            struct pipe_buffer *buffer);
+
    void (*texture_release)(struct pipe_screen *,
                            struct pipe_texture **pt);
 
@@ -96,7 +108,22 @@ struct pipe_screen {
    struct pipe_surface *(*get_tex_surface)(struct pipe_screen *,
                                            struct pipe_texture *texture,
                                            unsigned face, unsigned level,
-                                           unsigned zslice);
+                                           unsigned zslice,
+                                           unsigned usage );
+
+   /* Surfaces allocated by the above must be released here:
+    */
+   void (*tex_surface_release)( struct pipe_screen *,
+                                struct pipe_surface ** );
+   
+
+   void *(*surface_map)( struct pipe_screen *,
+                         struct pipe_surface *surface,
+                         unsigned flags );
+
+   void (*surface_unmap)( struct pipe_screen *,
+                          struct pipe_surface *surface );
+   
 };
 
 
index 912d84e7b997aef8b50e8194b55af82c26ef7a2e..e7ee8c97ed73e076c982d69c804446914bc579e9 100644 (file)
@@ -271,12 +271,26 @@ struct pipe_surface
    unsigned width;
    unsigned height;
    unsigned pitch;               /**< in pixels */
+   unsigned layout;              /**< PIPE_SURFACE_LAYOUT_x */
    unsigned offset;              /**< offset from start of buffer, in bytes */
    unsigned refcount;
+   unsigned usage;              /**< PIPE_BUFFER_USAGE_*  */
+
    struct pipe_winsys *winsys;   /**< winsys which owns/created the surface */
+
+   struct pipe_texture *texture; /**< optional texture into which this is a view  */
+   unsigned face;
+   unsigned level;
+   unsigned zslice;
 };
 
 
+#define PIPE_TEXTURE_USAGE_RENDER_TARGET   0x1
+#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET  0x2 /* ie a backbuffer */
+#define PIPE_TEXTURE_USAGE_PRIMARY         0x4 /* ie a frontbuffer */
+#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL   0x8
+#define PIPE_TEXTURE_USAGE_SAMPLER         0x10
+
 /**
  * Texture object.
  */
@@ -292,6 +306,8 @@ struct pipe_texture
    unsigned cpp:8;
    unsigned last_level:8;    /**< Index of last mipmap level present/defined */
    unsigned compressed:1;
+   
+   unsigned tex_usage;          /* PIPE_TEXTURE_USAGE_* */
 
    /* These are also refcounted:
     */
index 0e7e246666231bc8f3aa7b0b19d6f7167e27cd4a..0d8ed167b2a1f6479bc7c7f0284cbbbe64644877 100644 (file)
@@ -204,7 +204,10 @@ mem_dup(const void *src, uint size)
 #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
 #define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
 
+#ifndef Elements
 #define Elements(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
 #define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER))
 
 /**
index 3005ec2d94181d130adab4530b663093c850f83b..7ebc2851928580d804b1fbd8bda32e1111fa0932 100644 (file)
@@ -86,11 +86,12 @@ struct pipe_winsys
                                 struct pipe_surface *surf,
                                 unsigned width, unsigned height,
                                 enum pipe_format format,
-                                unsigned flags);
+                                unsigned flags,
+                                unsigned tex_usage);
    
    void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s);
 
-   
+
    /**
     * Buffer management. Buffer attributes are mostly fixed over its lifetime.
     *
index 77dec9488dfaca4837de846461d39c97a5ee68d4..d15143acfd4a0865e9005d07f74e3516805d153d 100644 (file)
@@ -206,7 +206,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
                                  struct pipe_surface *surf,
                                  unsigned width, unsigned height,
                                  enum pipe_format format, 
-                                 unsigned flags)
+                                 unsigned flags,
+                                 unsigned tex_usage)
 {
    const unsigned alignment = 64;
    int ret;
index 14c3892559b9828c71ce6fbc81bdd97f05db1a5b..b14758f333656ac9fa37ae9d55cb5d01df548e01 100644 (file)
@@ -489,7 +489,8 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
                          struct pipe_surface *surf,
                          unsigned width, unsigned height,
                          enum pipe_format format, 
-                         unsigned flags)
+                         unsigned flags,
+                         unsigned tex_usage)
 {
    const unsigned alignment = 64;
 
@@ -498,6 +499,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
    surf->format = format;
    surf->cpp = pf_get_size(format);
    surf->pitch = round_up(width, alignment / surf->cpp);
+   surf->usage = flags;
 
 #ifdef GALLIUM_CELL /* XXX a bit of a hack */
    height = round_up(height, TILE_SIZE);
@@ -551,6 +553,7 @@ static void
 xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
 {
    struct pipe_surface *surf = *s;
+   assert(!surf->texture);
    surf->refcount--;
    if (surf->refcount == 0) {
       if (surf->buffer)
index f42f7fcc5f1ad547774b587b1f7f22eb823f1da4..77376099f0d01a3d6b1c07e204604bddc3476463 100644 (file)
@@ -276,7 +276,8 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
                                struct pipe_surface *surf,
                                unsigned width, unsigned height,
                                enum pipe_format format,
-                               unsigned flags)
+                               unsigned flags,
+                               unsigned tex_usage)
 {
     const unsigned alignment = 64;
 
index f12fa28d97bb4d21407bed38bcec429a4918a74e..5ec03563ba2e4af807b6a9e3231466a05ca4b845 100644 (file)
@@ -126,6 +126,8 @@ _mesa_free_shader_program_data(GLcontext *ctx,
    for (i = 0; i < shProg->NumShaders; i++) {
       _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
    }
+   shProg->NumShaders = 0;
+
    if (shProg->Shaders) {
       _mesa_free(shProg->Shaders);
       shProg->Shaders = NULL;
@@ -1008,6 +1010,8 @@ _mesa_link_program(GLcontext *ctx, GLuint program)
       return;
    }
 
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
    _slang_link(ctx, program, shProg);
 }
 
index 18063adc79c16056d1d30620d4ede76b802a8928..ecfd1179189d86fc3abdaae6402858efb059882a 100644 (file)
  */
 static const struct st_tracked_state *atoms[] =
 {
-   &st_update_framebuffer,
    &st_update_depth_stencil_alpha,
    &st_update_clip,
 
+   &st_finalize_textures,
    &st_update_shader,
 
    &st_update_rasterizer,
@@ -58,6 +58,7 @@ static const struct st_tracked_state *atoms[] =
    &st_update_blend,
    &st_update_sampler,
    &st_update_texture,
+   &st_update_framebuffer,
    &st_update_vs_constants,
    &st_update_fs_constants,
    &st_update_pixel_transfer
index c6c6eba812139e301d765171a8e3ff0483636e43..c7cffd85c8a89d03b2c729622108e29bce2077a8 100644 (file)
@@ -55,6 +55,7 @@ extern const struct st_tracked_state st_update_scissor;
 extern const struct st_tracked_state st_update_blend;
 extern const struct st_tracked_state st_update_sampler;
 extern const struct st_tracked_state st_update_texture;
+extern const struct st_tracked_state st_finalize_textures;
 extern const struct st_tracked_state st_update_fs_constants;
 extern const struct st_tracked_state st_update_vs_constants;
 extern const struct st_tracked_state st_update_pixel_transfer;
index 0a6974d8a7fe5f9bb54105bf8db073ea3424b284..d46c3ee16c5d8af9b6f6f3851f1114d18c9d0859 100644 (file)
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_cb_fbo.h"
+#include "st_texture.h"
 #include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
 #include "cso_cache/cso_context.h"
 
 
+
+/**
+ * When doing GL render to texture, we have to be sure that finalize_texture()
+ * didn't yank out the pipe_texture that we earlier created a surface for.
+ * Check for that here and create a new surface if needed.
+ */
+static void
+update_renderbuffer_surface(struct st_context *st,
+                            struct st_renderbuffer *strb)
+{
+   struct pipe_screen *screen = st->pipe->screen;
+   struct pipe_texture *texture = strb->rtt->pt;
+   int rtt_width = strb->Base.Width;
+   int rtt_height = strb->Base.Height;
+
+   if (!strb->surface ||
+       strb->surface->texture != texture ||
+       strb->surface->width != rtt_width ||
+       strb->surface->height != rtt_height) {
+      int level;
+      /* find matching mipmap level size */
+      for (level = 0; level <= texture->last_level; level++) {
+         if (texture->width[level] == rtt_width &&
+             texture->height[level] == rtt_height) {
+
+            pipe_surface_reference(&strb->surface, NULL);
+
+            strb->surface = screen->get_tex_surface(screen,
+                                              texture,
+                                              strb->rtt_face,
+                                              level,
+                                              strb->rtt_slice,
+                                              PIPE_BUFFER_USAGE_GPU_READ |
+                                              PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+            printf("-- alloc new surface %d x %d into tex %p\n",
+                   strb->surface->width, strb->surface->height,
+                   texture);
+#endif
+            break;
+         }
+      }
+   }
+}
+
+
 /**
  * Update framebuffer state (color, depth, stencil, etc. buffers)
- * XXX someday: separate draw/read buffers.
  */
 static void
 update_framebuffer_state( struct st_context *st )
@@ -55,6 +102,8 @@ update_framebuffer_state( struct st_context *st )
    framebuffer->width = fb->Width;
    framebuffer->height = fb->Height;
 
+   /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/
+
    /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
     * to determine which surfaces to draw to
     */
@@ -62,6 +111,13 @@ update_framebuffer_state( struct st_context *st )
    for (j = 0; j < MAX_DRAW_BUFFERS; j++) {
       for (i = 0; i < fb->_NumColorDrawBuffers[j]; i++) {
          strb = st_renderbuffer(fb->_ColorDrawBuffers[j][i]);
+
+         /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
+         if (strb->rtt) {
+            /* rendering to a GL texture, may have to update surface */
+            update_renderbuffer_surface(st, strb);
+         }
+
          assert(strb->surface);
          framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface;
          framebuffer->num_cbufs++;
@@ -71,6 +127,11 @@ update_framebuffer_state( struct st_context *st )
    strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
    if (strb) {
       strb = st_renderbuffer(strb->Base.Wrapped);
+      if (strb->rtt) {
+         /* rendering to a GL texture, may have to update surface */
+         update_renderbuffer_surface(st, strb);
+      }
+
       assert(strb->surface);
       framebuffer->zsbuf = strb->surface;
    }
@@ -99,7 +160,7 @@ const struct st_tracked_state st_update_framebuffer = {
    "st_update_framebuffer",                            /* name */
    {                                                   /* dirty */
       _NEW_BUFFERS,                                    /* mesa */
-      0,                                               /* st */
+      ST_NEW_FRAMEBUFFER,                              /* st */
    },
    update_framebuffer_state                            /* update */
 };
index 999c14844908a10eb6fa052b34a6f30bf2d1c211..e500ac8684df9e0091df70259d9aed5163a0565c 100644 (file)
@@ -126,7 +126,8 @@ create_color_map_texture(GLcontext *ctx)
 
    /* create texture for color map/table */
    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0,
-                          texSize, texSize, 1, 0);
+                          texSize, texSize, 1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
    return pt;
 }
 
@@ -148,8 +149,10 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
    uint *dest;
    uint i, j;
 
-   surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
-   dest = (uint *) pipe_surface_map(surface);
+   surface = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+                                     PIPE_BUFFER_USAGE_CPU_WRITE);
+   dest = (uint *) screen->surface_map(screen, surface,
+                                       PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* Pack four 1D maps into a 2D texture:
     * R map is placed horizontally, indexed by S, in channel 0
@@ -168,9 +171,8 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
       }
    }
 
-   pipe_surface_unmap(surface);
+   screen->surface_unmap(screen, surface);
    pipe_surface_reference(&surface, NULL);
-   pipe->texture_update(pipe, pt, 0, 0x1);
 }
 
 
index 7745591afbafb05e614c861103c146552ad7e588..a62ea8161c5b581c80d192525926e9330c000938 100644 (file)
@@ -44,6 +44,8 @@
 #include "pipe/p_context.h"
 #include "pipe/p_shader_tokens.h"
 
+#include "util/u_simple_shaders.h"
+
 #include "cso_cache/cso_context.h"
 
 #include "st_context.h"
@@ -252,6 +254,22 @@ st_free_translated_vertex_programs(struct st_context *st,
 }
 
 
+static void *
+get_passthrough_fs(struct st_context *st)
+{
+   struct pipe_shader_state shader;
+
+   if (!st->passthrough_fs) {
+      st->passthrough_fs =
+         util_make_fragment_passthrough_shader(st->pipe, &shader);
+#if 0      /* We actually need to keep the tokens around at this time */
+      free((void *) shader.tokens);
+#endif
+   }
+
+   return st->passthrough_fs;
+}
+
 
 static void
 update_linkage( struct st_context *st )
@@ -277,7 +295,15 @@ update_linkage( struct st_context *st )
    st_reference_fragprog(st, &st->fp, stfp);
 
    cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
-   cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+
+   if (st->missing_textures) {
+      /* use a pass-through frag shader that uses no textures */
+      void *fs = get_passthrough_fs(st);
+      cso_set_fragment_shader_handle(st->cso_context, fs);
+   }
+   else {
+      cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+   }
 
    st->vertex_result_to_slot = xvp->output_to_slot;
 }
index 767654f3d0ff9a940ad5c32253fc058eaf3bde96..1ec671ed48fc9b436e356604f85751dad508bb7f 100644 (file)
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 #include "cso_cache/cso_context.h"
-#include "util/u_simple_shaders.h"
 
 
-static void *
-get_passthrough_fs(struct st_context *st)
-{
-   struct pipe_shader_state shader;
-
-   if (!st->passthrough_fs) {
-      st->passthrough_fs =
-         util_make_fragment_passthrough_shader(st->pipe, &shader);
-      free((void *) shader.tokens);
-   }
-
-   return st->passthrough_fs;
-}
-
-
-/**
- * XXX This needs some work yet....
- * Need to "upload" texture images at appropriate times.
- */
 static void 
 update_textures(struct st_context *st)
 {
    struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
    GLuint su;
-   GLboolean missing_textures = GL_FALSE;
 
    st->state.num_textures = 0;
 
@@ -85,13 +64,11 @@ update_textures(struct st_context *st)
             retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
             if (!retval) {
                /* out of mem */
-               missing_textures = GL_TRUE;
+               /* missing texture */
                continue;
             }
 
             st->state.num_textures = su + 1;
-
-            stObj->teximage_realloc = TRUE;
          }
 
          pt = st_get_stobj_texture(stObj);
@@ -103,12 +80,6 @@ update_textures(struct st_context *st)
    cso_set_sampler_textures(st->cso_context,
                             st->state.num_textures,
                             st->state.sampler_texture);
-
-   if (missing_textures) {
-      /* use a pass-through frag shader that uses no textures */
-      void *fs = get_passthrough_fs(st);
-      cso_set_fragment_shader_handle(st->cso_context, fs);
-   }
 }
 
 
@@ -120,3 +91,52 @@ const struct st_tracked_state st_update_texture = {
    },
    update_textures                                     /* update */
 };
+
+
+
+
+static void 
+finalize_textures(struct st_context *st)
+{
+   struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+   const GLboolean prev_missing_textures = st->missing_textures;
+   GLuint su;
+
+   st->missing_textures = GL_FALSE;
+
+   for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
+      if (fprog->Base.SamplersUsed & (1 << su)) {
+         const GLuint texUnit = fprog->Base.SamplerUnits[su];
+         struct gl_texture_object *texObj
+            = st->ctx->Texture.Unit[texUnit]._Current;
+         struct st_texture_object *stObj = st_texture_object(texObj);
+
+         if (texObj) {
+            GLboolean flush, retval;
+
+            retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+            if (!retval) {
+               /* out of mem */
+               st->missing_textures = GL_TRUE;
+               continue;
+            }
+
+            stObj->teximage_realloc = TRUE;
+         }
+      }
+   }
+
+   if (prev_missing_textures != st->missing_textures)
+      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+
+const struct st_tracked_state st_finalize_textures = {
+   "st_finalize_textures",             /* name */
+   {                                   /* dirty */
+      _NEW_TEXTURE,                    /* mesa */
+      0,                               /* st */
+   },
+   finalize_textures                   /* update */
+};
index 1636bed91a5ccf7b1ec56c69e59c566795bc60eb..8098d75e18f337a78755f74bb9db78e92f5cda8e 100644 (file)
@@ -105,14 +105,18 @@ void
 st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
-   struct pipe_surface *acc_ps = acc_strb->surface;
+   struct pipe_surface *acc_ps;
+   struct pipe_screen *screen = ctx->st->pipe->screen;
    const GLint xpos = ctx->DrawBuffer->_Xmin;
    const GLint ypos = ctx->DrawBuffer->_Ymin;
    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
    GLvoid *map;
 
-   map = pipe_surface_map(acc_ps);
+   acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+                                    PIPE_BUFFER_USAGE_CPU_WRITE);
+   map = screen->surface_map(screen, acc_ps,
+                             PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* note acc_strb->format might not equal acc_ps->format */
    switch (acc_strb->format) {
@@ -140,7 +144,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
       _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
    }
 
-   pipe_surface_unmap(acc_ps);
+   screen->surface_unmap(screen, acc_ps);
+   pipe_surface_reference(&acc_ps, NULL);
 }
 
 
@@ -150,10 +155,12 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
           GLint xpos, GLint ypos, GLint width, GLint height,
           struct st_renderbuffer *acc_strb)
 {
+   struct pipe_screen *screen = ctx->st->pipe->screen;
    struct pipe_surface *acc_ps = acc_strb->surface;
    GLvoid *map;
 
-   map = pipe_surface_map(acc_ps);
+   map = screen->surface_map(screen, acc_ps, 
+                             PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* note acc_strb->format might not equal acc_ps->format */
    switch (acc_strb->format) {
@@ -174,77 +181,107 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
 
-   pipe_surface_unmap(acc_ps);
+   screen->surface_unmap(screen, acc_ps);
 }
 
 
 static void
 accum_accum(struct pipe_context *pipe, GLfloat value,
             GLint xpos, GLint ypos, GLint width, GLint height,
-            struct pipe_surface *acc_ps,
-            struct pipe_surface *color_ps)
+            struct st_renderbuffer *acc_strb,
+            struct st_renderbuffer *color_strb)
 {
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_surface *acc_surf, *color_surf;
    GLfloat *colorBuf, *accBuf;
    GLint i;
 
+   acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+                                      (PIPE_BUFFER_USAGE_CPU_WRITE |
+                                       PIPE_BUFFER_USAGE_CPU_READ));
+
+   color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+
    colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
    accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-   pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf);
-   acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+   pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf);
+   acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
 
    for (i = 0; i < 4 * width * height; i++) {
       accBuf[i] = accBuf[i] + colorBuf[i] * value;
    }
 
-   acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+   acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
 
    free(colorBuf);
    free(accBuf);
+   pipe_surface_reference(&acc_surf, NULL);
+   pipe_surface_reference(&color_surf, NULL);
 }
 
 
 static void
 accum_load(struct pipe_context *pipe, GLfloat value,
            GLint xpos, GLint ypos, GLint width, GLint height,
-           struct pipe_surface *acc_ps,
-           struct pipe_surface *color_ps)
+           struct st_renderbuffer *acc_strb,
+           struct st_renderbuffer *color_strb)
 {
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_surface *acc_surf, *color_surf;
    GLfloat *buf;
    GLint i;
 
+   acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+                                      PIPE_BUFFER_USAGE_CPU_WRITE);
+
+   color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+
    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-   pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf);
+   pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf);
 
    for (i = 0; i < 4 * width * height; i++) {
       buf[i] = buf[i] * value;
    }
 
-   acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
+   acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf);
 
    free(buf);
+   pipe_surface_reference(&acc_surf, NULL);
+   pipe_surface_reference(&color_surf, NULL);
 }
 
 
 static void
 accum_return(GLcontext *ctx, GLfloat value,
              GLint xpos, GLint ypos, GLint width, GLint height,
-             struct pipe_surface *acc_ps,
-             struct pipe_surface *color_ps)
+             struct st_renderbuffer *acc_strb,
+             struct st_renderbuffer *color_strb)
 {
    struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_screen *screen = pipe->screen;
    const GLubyte *colormask = ctx->Color.ColorMask;
+   struct pipe_surface *acc_surf, *color_surf;
    GLfloat *abuf, *cbuf = NULL;
    GLint i, ch;
 
    abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-   acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
+   acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+                                      PIPE_BUFFER_USAGE_CPU_READ);
+
+   color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+                                        (PIPE_BUFFER_USAGE_CPU_READ |
+                                         PIPE_BUFFER_USAGE_CPU_WRITE));
+
+   acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf);
 
    if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
       cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
-      pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf);
+      pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf);
    }
 
    for (i = 0; i < width * height; i++) {
@@ -259,11 +296,13 @@ accum_return(GLcontext *ctx, GLfloat value,
       }
    }
 
-   pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf);
+   pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf);
 
    free(abuf);
    if (cbuf)
       free(cbuf);
+   pipe_surface_reference(&acc_surf, NULL);
+   pipe_surface_reference(&color_surf, NULL);
 }
 
 
@@ -276,8 +315,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
      = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
    struct st_renderbuffer *color_strb
       = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
-   struct pipe_surface *acc_ps = acc_strb->surface;
-   struct pipe_surface *color_ps = color_strb->surface;
 
    const GLint xpos = ctx->DrawBuffer->_Xmin;
    const GLint ypos = ctx->DrawBuffer->_Ymin;
@@ -300,14 +337,14 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
       break;
    case GL_ACCUM:
       if (value != 0.0F) {
-         accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+         accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
       }
       break;
    case GL_LOAD:
-      accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+      accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
       break;
    case GL_RETURN:
-      accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps);
+      accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
       break;
    default:
       assert(0);
index ce8fefe703fc395083e782e9c059ed07827fe2e1..b17681a05b825d14d5008f5d095f65c7885c9e4c 100644 (file)
@@ -321,16 +321,18 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
     * Create texture to hold bitmap pattern.
     */
    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format,
-                          0, width, height, 1, 0);
+                          0, width, height, 1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt) {
       _mesa_unmap_bitmap_pbo(ctx, unpack);
       return NULL;
    }
 
-   surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+   surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+                                     PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* map texture surface */
-   dest = pipe_surface_map(surface);
+   dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* Put image into texture surface */
    memset(dest, 0xff, height * surface->pitch);
@@ -340,9 +342,8 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    _mesa_unmap_bitmap_pbo(ctx, unpack);
 
    /* Release surface */
-   pipe_surface_unmap(surface);
+   screen->surface_unmap(screen, surface);
    pipe_surface_reference(&surface, NULL);
-   pipe->texture_update(pipe, pt, 0, 0x1);
 
    return pt;
 }
@@ -539,13 +540,16 @@ reset_cache(struct st_context *st)
    cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
                                       st->bitmap.tex_format, 0,
                                       BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
-                                      1, 0);
+                                      1, 0,
+                                      PIPE_TEXTURE_USAGE_SAMPLER);
 
    /* Map the texture surface.
     * Subsequent glBitmap calls will write into the texture image.
     */
-   cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0);
-   cache->buffer = pipe_surface_map(cache->surf);
+   cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0,
+                                         PIPE_BUFFER_USAGE_CPU_WRITE);
+   cache->buffer = screen->surface_map(screen, cache->surf,
+                                       PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* init image to all 0xff */
    memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT);
@@ -562,6 +566,7 @@ st_flush_bitmap_cache(struct st_context *st)
       if (st->ctx->DrawBuffer) {
          struct bitmap_cache *cache = st->bitmap.cache;
          struct pipe_context *pipe = st->pipe;
+         struct pipe_screen *screen = pipe->screen;
 
          assert(cache->xmin <= cache->xmax);
          /*
@@ -574,11 +579,8 @@ st_flush_bitmap_cache(struct st_context *st)
          /* The texture surface has been mapped until now.
           * So unmap and release the texture surface before drawing.
           */
-         pipe_surface_unmap(cache->surf);
-         pipe_surface_reference(&cache->surf, NULL);
-
-         /* XXX is this needed? */
-         pipe->texture_update(pipe, cache->texture, 0, 0x1);
+         screen->surface_unmap(screen, cache->surf);
+         screen->tex_surface_release(screen, &cache->surf);
 
          draw_bitmap_quad(st->ctx,
                           cache->xpos,
@@ -662,6 +664,9 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    struct st_context *st = ctx->st;
    struct pipe_texture *pt;
 
+   if (width == 0 || height == 0)
+      return;
+
    st_validate_state(st);
 
    if (!st->bitmap.vs) {
index 65bfd6cfcc01499d30ebc3b1d618ca572d2076cb..43e00e6acc2096d1587863a73922f51bcf9d84de 100644 (file)
@@ -346,7 +346,8 @@ make_texture(struct st_context *st,
       return NULL;
 
    pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
-                         1, 0);
+                         1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt) {
       _mesa_unmap_drawpix_pbo(ctx, unpack);
       return NULL;
@@ -362,10 +363,12 @@ make_texture(struct st_context *st,
       /* we'll do pixel transfer in a fragment shader */
       ctx->_ImageTransferState = 0x0;
 
-      surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+      surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
 
       /* map texture surface */
-      dest = pipe_surface_map(surface);
+      dest = screen->surface_map(screen, surface,
+                                 PIPE_BUFFER_USAGE_CPU_WRITE);
 
       /* Put image into texture surface.
        * Note that the image is actually going to be upside down in
@@ -384,9 +387,8 @@ make_texture(struct st_context *st,
                                     unpack);
 
       /* unmap */
-      pipe_surface_unmap(surface);
+      screen->surface_unmap(screen, surface);
       pipe_surface_reference(&surface, NULL);
-      pipe->texture_update(pipe, pt, 0, 0x1);
 
       assert(success);
 
@@ -482,7 +484,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
       ubyte *map;
 
       /* allocate/load buffer object with vertex data */
-      buf = pipe_buffer_create(pipe,32, PIPE_BUFFER_USAGE_VERTEX,
+      buf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
                                sizeof(verts));
       map = pipe_buffer_map(pipe, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
       memcpy(map, verts, sizeof(verts));
@@ -492,8 +494,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
                               PIPE_PRIM_QUADS,
                               4,  /* verts */
                               3); /* attribs/vert */
-
-      pipe_buffer_destroy(pipe, buf);
+      pipe_buffer_reference(pipe->winsys, &buf, NULL);
    }
 }
 
@@ -600,8 +601,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    x1 = x + width * ctx->Pixel.ZoomX;
    y0 = y;
    y1 = y + height * ctx->Pixel.ZoomY;
+   //if(!color)
    draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
-
+   //else
+   //printf("skip draw quad\n");
    /* restore state */
    cso_restore_rasterizer(cso);
    cso_restore_viewport(cso);
@@ -731,15 +734,23 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
 {
    struct st_context *st = ctx->st;
    struct pipe_context *pipe = st->pipe;
-   struct pipe_surface *ps = st->state.framebuffer.zsbuf;
+   struct pipe_screen *screen = pipe->screen;
+   struct st_renderbuffer *strb;
+   struct pipe_surface *ps;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    GLint skipPixels;
    ubyte *stmap;
 
    pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
+   strb = st_renderbuffer(ctx->DrawBuffer->
+                          Attachment[BUFFER_STENCIL].Renderbuffer);
+   ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+                                PIPE_BUFFER_USAGE_CPU_WRITE);
+
    /* map the stencil buffer */
-   stmap = pipe_surface_map(ps);
+   stmap = screen->surface_map(screen, ps, 
+                               PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* if width > MAX_WIDTH, have to process image in chunks */
    skipPixels = 0;
@@ -796,7 +807,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    }
 
    /* unmap the stencil buffer */
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
+   pipe_surface_reference(&ps, NULL);
 }
 
 
@@ -869,7 +881,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                     GLint dstx, GLint dsty)
 {
    struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
-   struct pipe_surface *psDraw = rbDraw->surface;
+   struct pipe_screen *screen = ctx->st->pipe->screen;
+   struct pipe_surface *psDraw;
    ubyte *drawMap;
    ubyte *buffer;
    int i;
@@ -884,8 +897,11 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE,
                           &ctx->DefaultPacking, buffer);
 
+   psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
+                                    PIPE_BUFFER_USAGE_CPU_WRITE);
+
    /* map the stencil buffer */
-   drawMap = pipe_surface_map(psDraw);
+   drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* draw */
    /* XXX PixelZoom not handled yet */
@@ -925,7 +941,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    free(buffer);
 
    /* unmap the stencil buffer */
-   pipe_surface_unmap(psDraw);
+   screen->surface_unmap(screen, psDraw);
+   pipe_surface_reference(&psDraw, NULL);
 }
 
 
@@ -940,7 +957,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    struct st_renderbuffer *rbRead;
    struct st_vertex_program *stvp;
    struct st_fragment_program *stfp;
-   struct pipe_surface *psRead;
    struct pipe_surface *psTex;
    struct pipe_texture *pt;
    GLfloat *color;
@@ -971,8 +987,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
    }
 
-   psRead = rbRead->surface;
-   srcFormat = psRead->format;
+   srcFormat = rbRead->texture->format;
 
    if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) {
       texFormat = srcFormat;
@@ -984,54 +999,72 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
          assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
       }
       else {
-         /* todo */
-         assert(0);
+         /* default color format */
+         texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE);
+         assert(texFormat != PIPE_FORMAT_NONE);
       }
    }
 
    pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
-                          width, height, 1, 0);
+                          width, height, 1, 0,
+                          PIPE_TEXTURE_USAGE_SAMPLER);
    if (!pt)
       return;
 
-   psTex = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       srcy = ctx->DrawBuffer->Height - srcy - height;
    }
 
    if (srcFormat == texFormat) {
       /* copy source framebuffer surface into mipmap/texture */
+      struct pipe_surface *psRead = screen->get_tex_surface(screen,
+                                       rbRead->texture, 0, 0, 0,
+                                       PIPE_BUFFER_USAGE_GPU_READ);
+      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+                                      PIPE_BUFFER_USAGE_GPU_WRITE );
       pipe->surface_copy(pipe,
                          FALSE,
                         psTex, /* dest */
                         0, 0, /* destx/y */
                         psRead,
                         srcx, srcy, width, height);
+      pipe_surface_reference(&psRead, NULL);
    }
-   else if (type == GL_COLOR) {
-      /* alternate path using get/put_tile() */
-      GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+   else {
+      /* CPU-based fallback/conversion */
+      struct pipe_surface *psRead = screen->get_tex_surface(screen,
+                                       rbRead->texture, 0, 0, 0,
+                                       PIPE_BUFFER_USAGE_CPU_READ);
 
-      pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
-      pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+      psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
+                                      PIPE_BUFFER_USAGE_CPU_WRITE );
 
-      free(buf);
-   }
-   else {
-      /* GL_DEPTH */
-      GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
-      pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
-      pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
-      free(buf);
+      if (type == GL_COLOR) {
+         /* alternate path using get/put_tile() */
+         GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+         pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
+         pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+
+         free(buf);
+      }
+      else {
+         /* GL_DEPTH */
+         GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
+         pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
+         pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
+         free(buf);
+      }
+      pipe_surface_reference(&psRead, NULL);
    }
 
+   pipe_surface_reference(&psTex, NULL);
+
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                       pt, stvp, stfp, color, GL_TRUE);
 
-   pipe_surface_reference(&psTex, NULL);
    pipe_texture_reference(&pt, NULL);
 }
 
index fc8a5ea7f621c7565a9b0598882108a8b488ae3d..3e592730f831d2e461654e3e2babdbd025c10186 100644 (file)
@@ -77,6 +77,11 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
    return info.size;
 }
 
+static INLINE GLboolean pf_is_depth_stencil( enum pipe_format format )
+{
+   return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
+           pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
+}
 
 /**
  * gl_renderbuffer::AllocStorage()
@@ -90,80 +95,94 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 {
    struct pipe_context *pipe = ctx->st->pipe;
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   enum pipe_format pipeFormat;
-   GLbitfield flags = 0x0; /* XXX needed? */
-   int ret;
-
-   if (!strb->surface) {
-      /* first time surface creation */
-      strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
-      assert(strb->surface);
-      assert(strb->surface->refcount);
-      assert(strb->surface->winsys);
-      if (!strb->surface)
-         return GL_FALSE;
+   struct pipe_texture template;
+   unsigned surface_usage;
+
+   /* Free the old surface (and texture if we hold the last
+    * reference):
+    */
+   pipe_surface_reference( &strb->surface, NULL );
+
+   memset(&template, 0, sizeof(template));
+
+   if (strb->format != PIPE_FORMAT_NONE) {
+      template.format = strb->format;
    }
-   else if (strb->surface->buffer) {
-      /* release/discard the old surface buffer */
-      pipe_reference_buffer(pipe, &strb->surface->buffer, NULL);
+   else {
+      template.format = st_choose_renderbuffer_format(pipe, internalFormat);
    }
 
-   /* Determine surface format here */
-   if (strb->format != PIPE_FORMAT_NONE) {
-      assert(strb->format != 0);
-      /* we'll hit this for front/back color bufs */
-      pipeFormat = strb->format;
+   strb->Base.Width  = width;
+   strb->Base.Height = height;
+   init_renderbuffer_bits(strb, template.format);
+
+   template.target = PIPE_TEXTURE_2D;
+   template.compressed = 0;
+   template.cpp = pf_get_size(template.format);
+   template.width[0] = width;
+   template.height[0] = height;
+   template.depth[0] = 1;
+   template.last_level = 0;
+
+   if (pf_is_depth_stencil(template.format)) {
+      template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
    }
    else {
-      pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
+      template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+                            PIPE_TEXTURE_USAGE_RENDER_TARGET);
    }
 
-   init_renderbuffer_bits(strb, pipeFormat);
-
-   ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
-                                             strb->surface,
-                                             width,
-                                             height,
-                                             pipeFormat,
-                                             flags);
-   if (ret || !strb->surface->buffer) {
-      if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
-         /* Accum buffer.  Try a different surface format.  Since accum
-          * buffers are s/w only for now, the surface pixel format doesn't
-          * really matter, only that the buffer is large enough.
-          */
-         int sz, mult;
-         enum pipe_format accum_format;
-
-         /* allocate a buffer of (typically) double height to get 64bpp */
-         accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
-         sz = pf_get_size(accum_format);
-         mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
-
-         ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
-                                                   strb->surface,
-                                                   width, height * mult,
-                                                   accum_format, flags);
-         if (ret)
-            return GL_FALSE; /* we've _really_ failed */
-
-      }
-      else {
-         return GL_FALSE; /* out of memory, try s/w buffer? */
-      }
+
+   /* Probably need dedicated flags for surface usage too: 
+    */
+   surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
+                    PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+                    PIPE_BUFFER_USAGE_CPU_READ |
+                    PIPE_BUFFER_USAGE_CPU_WRITE);
+#endif
+
+   strb->texture = pipe->screen->texture_create( pipe->screen,
+                                                 &template );
+
+   /* Special path for accum buffers.  
+    *
+    * Try a different surface format.  Since accum buffers are s/w
+    * only for now, the surface pixel format doesn't really matter,
+    * only that the buffer is large enough.
+    */
+   if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) 
+   {
+      /* Actually, just setting this usage value should be sufficient
+       * to tell the driver to go ahead and allocate the buffer, even
+       * if HW doesn't support the format.
+       */
+      template.tex_usage = 0;
+      surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
+                       PIPE_BUFFER_USAGE_CPU_WRITE);
+
+      strb->texture = pipe->screen->texture_create( pipe->screen,
+                                                    &template );
+
    }
 
-   ASSERT(strb->surface->buffer);
-   ASSERT(strb->surface->format);
-   ASSERT(strb->surface->cpp);
-   ASSERT(strb->surface->width == width);
-   /*ASSERT(strb->surface->height == height);*/
-   ASSERT(strb->surface->pitch);
+   if (!strb->texture) 
+      return FALSE;
 
-   strb->Base.Width  = width;
-   strb->Base.Height = height;
+   strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+                                                  strb->texture,
+                                                  0, 0, 0,
+                                                  surface_usage );
+
+   assert(strb->surface->buffer);
+   assert(strb->surface->format);
+   assert(strb->surface->cpp);
+   assert(strb->surface->width == width);
+   assert(strb->surface->height == height);
+   assert(strb->surface->pitch);
 
-   return GL_TRUE;
+
+   return strb->surface != NULL;
 }
 
 
@@ -175,10 +194,8 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *strb = st_renderbuffer(rb);
    ASSERT(strb);
-   if (strb->surface) {
-      struct pipe_winsys *ws = strb->surface->winsys;
-      ws->surface_release(ws, &strb->surface);
-   }
+   pipe_surface_reference(&strb->surface, NULL);
+   pipe_texture_reference(&strb->texture, NULL);
    free(strb);
 }
 
@@ -341,6 +358,10 @@ st_render_texture(GLcontext *ctx,
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_texture *pt;
+   struct st_texture_object *stObj;
+   const struct gl_texture_image *texImage =
+      att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+
 
    assert(!att->Renderbuffer);
 
@@ -357,21 +378,27 @@ st_render_texture(GLcontext *ctx,
    strb = st_renderbuffer(rb);
 
    /* get the texture for the texture object */
+   stObj = st_texture_object(att->Texture);
+
+   /* point renderbuffer at texobject */
+   strb->rtt = stObj;
+   strb->rtt_level = att->TextureLevel;
+   strb->rtt_face = att->CubeMapFace;
+   strb->rtt_slice = att->Zoffset;
+
+   rb->Width = texImage->Width2;
+   rb->Height = texImage->Height2;
+   /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
+
    pt = st_get_texobj_texture(att->Texture);
    assert(pt);
-   assert(pt->width[att->TextureLevel]);
+   /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+
+   pipe_texture_reference( &strb->texture, pt );
 
-   rb->Width = pt->width[att->TextureLevel];
-   rb->Height = pt->height[att->TextureLevel];
+   pipe_surface_reference(&strb->surface, NULL);
 
-   /* the renderbuffer's surface is inside the texture */
-   strb->surface = screen->get_tex_surface(screen, pt,
-                                           att->CubeMapFace,
-                                           att->TextureLevel,
-                                           att->Zoffset);
-   assert(strb->surface);
-   assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE));
-   assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE));
+   /* the new surface will be created during framebuffer validation */
 
    init_renderbuffer_bits(strb, pt->format);
 
@@ -396,22 +423,22 @@ static void
 st_finish_render_texture(GLcontext *ctx,
                          struct gl_renderbuffer_attachment *att)
 {
+   struct pipe_screen *screen = ctx->st->pipe->screen;
    struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
 
    assert(strb);
 
    ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
-   ctx->st->pipe->texture_update(ctx->st->pipe,
-                                 st_get_texobj_texture(att->Texture),
-                                 att->CubeMapFace, 1 << att->TextureLevel);
+   if (strb->surface)
+      screen->tex_surface_release( screen, &strb->surface );
+
+   strb->rtt = NULL;
 
    /*
    printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
    */
 
-   pipe_surface_reference(&strb->surface, NULL);
-
    _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
 
    /* restore previous framebuffer state */
index c1aa14f9b22ceeef99098c7ba5d13da6a7480b94..87b0734a0c8595dcbe1c8b13e4ec6bab0a8c850e 100644 (file)
 struct st_renderbuffer
 {
    struct gl_renderbuffer Base;
-   struct pipe_surface *surface;
+   struct pipe_texture *texture;
+   struct pipe_surface *surface; /* temporary view into texture */
    enum pipe_format format;  /** preferred format, or PIPE_FORMAT_NONE */
+
+   struct st_texture_object *rtt;  /**< GL render to texture's texture */
+   int rtt_level, rtt_face, rtt_slice;
 };
 
 
index 1b50792bd1cdb260ac4fe0a494bf5f85d8047552..19021411cfc9ec9fc6581d6c4cd2400ad3768d84 100644 (file)
@@ -173,6 +173,12 @@ feedback_reset_stipple_counter( struct draw_stage *stage )
 }
 
 
+static void
+feedback_destroy( struct draw_stage *stage )
+{
+   /* no-op */
+}
+
 /**
  * Create GL feedback drawing stage.
  */
@@ -188,6 +194,7 @@ draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
    fs->stage.tri = feedback_tri;
    fs->stage.flush = feedback_flush;
    fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
+   fs->stage.destroy = feedback_destroy;
    fs->ctx = ctx;
 
    return &fs->stage;
index ddbe36106c86367c4478eeb59b7c5073f71b662d..3615fafc0aee27977cca20813fa7edebf2772ee7 100644 (file)
@@ -61,13 +61,18 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                        GLvoid *pixels)
 {
    struct gl_framebuffer *fb = ctx->ReadBuffer;
+   struct pipe_screen *screen = ctx->st->pipe->screen;
    struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer);
-   struct pipe_surface *ps = strb->surface;
+   struct pipe_surface *ps;
    ubyte *stmap;
    GLint j;
 
+   /* Create a CPU-READ surface/view into the renderbuffer's texture */
+   ps = screen->get_tex_surface(screen, strb->texture,  0, 0, 0,
+                                PIPE_BUFFER_USAGE_CPU_READ);
+
    /* map the stencil buffer */
-   stmap = pipe_surface_map(ps);
+   stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
 
    /* width should never be > MAX_WIDTH since we did clipping earlier */
    ASSERT(width <= MAX_WIDTH);
@@ -124,7 +129,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
 
 
    /* unmap the stencil buffer */
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
+   pipe_surface_reference(&ps, NULL);
 }
 
 
@@ -168,12 +174,16 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
               GLvoid *dest)
 {
    struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_screen *screen = pipe->screen;
    GLfloat temp[MAX_WIDTH][4];
    const GLbitfield transferOps = ctx->_ImageTransferState;
    GLint i, yStep, dfStride;
    GLfloat *df;
    struct st_renderbuffer *strb;
    struct gl_pixelstore_attrib clippedPacking = *pack;
+   struct pipe_surface *surf;
+
+   assert(ctx->ReadBuffer->Width > 0);
 
    /* XXX convolution not done yet */
    assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0);
@@ -229,6 +239,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       yStep = 1;
    }
 
+   /* Create a CPU-READ surface/view into the renderbuffer's texture */
+   surf = screen->get_tex_surface(screen, strb->texture,  0, 0, 0,
+                                  PIPE_BUFFER_USAGE_CPU_READ);
+
    /*
     * Copy pixels from pipe_surface to user memory
     */
@@ -240,15 +254,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
                                                      format, type);
 
-      if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM ||
-          strb->surface->format == PIPE_FORMAT_X8Z24_UNORM) {
+      if (surf->format == PIPE_FORMAT_S8Z24_UNORM ||
+          surf->format == PIPE_FORMAT_X8Z24_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH], j;
                GLfloat zfloat[MAX_WIDTH];
                const double scale = 1.0 / ((1 << 24) - 1);
-               pipe_get_tile_raw(pipe, strb->surface, x, y,
-                                 width, 1, ztemp, 0);
+               pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
                y += yStep;
                for (j = 0; j < width; j++) {
                   zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff));
@@ -262,18 +275,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
             /* untested, but simple: */
             assert(format == GL_DEPTH_STENCIL_EXT);
             for (i = 0; i < height; i++) {
-               pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, dst, 0);
+               pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0);
                y += yStep;
                dst += dstStride;
             }
          }
       }
-      else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) {
+      else if (surf->format == PIPE_FORMAT_Z16_UNORM) {
          for (i = 0; i < height; i++) {
             GLushort ztemp[MAX_WIDTH], j;
             GLfloat zfloat[MAX_WIDTH];
             const double scale = 1.0 / 0xffff;
-            pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+            pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
             y += yStep;
             for (j = 0; j < width; j++) {
                zfloat[j] = (float) (scale * ztemp[j]);
@@ -283,12 +296,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
             dst += dstStride;
          }
       }
-      else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) {
+      else if (surf->format == PIPE_FORMAT_Z32_UNORM) {
          for (i = 0; i < height; i++) {
             GLuint ztemp[MAX_WIDTH], j;
             GLfloat zfloat[MAX_WIDTH];
             const double scale = 1.0 / 0xffffffff;
-            pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+            pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
             y += yStep;
             for (j = 0; j < width; j++) {
                zfloat[j] = (float) (scale * ztemp[j]);
@@ -302,7 +315,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
          /* RGBA format */
          /* Do a row at a time to flip image data vertically */
          for (i = 0; i < height; i++) {
-            pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df);
+            pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df);
             y += yStep;
             df += dfStride;
             if (!dfStride) {
@@ -314,6 +327,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       }
    }
 
+   pipe_surface_reference(&surf, NULL);
+
    _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
 }
 
index 866683c23e99a0cec7a524c419408c2b539efed7..c0dba4cf2dab36b919c06d7cc53ad73900c8e16c 100644 (file)
@@ -306,6 +306,11 @@ guess_and_alloc_texture(struct st_context *st,
          depth <<= 1;
    }
 
+   if (width == 0 || height == 0 || depth == 0) {
+      /* no texture needed */
+      return;
+   }
+
    /* Guess a reasonable value for lastLevel.  This is probably going
     * to be wrong fairly often and might mean that we have to look at
     * resizable buffers, or require that buffers implement lazy
@@ -333,7 +338,9 @@ guess_and_alloc_texture(struct st_context *st,
                                  width,
                                  height,
                                  depth,
-                                 comp_byte);
+                                 comp_byte,
+                                 ( PIPE_TEXTURE_USAGE_RENDER_TARGET |
+                                   PIPE_TEXTURE_USAGE_SAMPLER ));
 
    DBG("%s - success\n", __FUNCTION__);
 }
@@ -478,7 +485,6 @@ st_TexImage(GLcontext * ctx,
             struct gl_texture_image *texImage,
             GLsizei imageSize, int compressed)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
    struct st_texture_object *stObj = st_texture_object(texObj);
    struct st_texture_image *stImage = st_texture_image(texImage);
    GLint postConvWidth, postConvHeight;
@@ -637,8 +643,10 @@ st_TexImage(GLcontext * ctx,
       return;
 
    if (stImage->pt) {
-      texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
-      dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+      texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+                                            PIPE_BUFFER_USAGE_CPU_WRITE);
+      if (stImage->surface)
+         dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
    }
    else {
       /* Allocate regular memory and store the image there temporarily.   */
@@ -656,6 +664,11 @@ st_TexImage(GLcontext * ctx,
       texImage->Data = malloc(sizeInBytes);
    }
 
+   if (!texImage->Data) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+      return;
+   }
+
    DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
        width, height, depth, width * texelBytes, dstRowStride);
 
@@ -686,8 +699,9 @@ st_TexImage(GLcontext * ctx,
         }
 
         if (stImage->pt && i < depth) {
-           st_texture_image_unmap(stImage);
-           texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+           st_texture_image_unmap(ctx->st, stImage);
+           texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+                                                  PIPE_BUFFER_USAGE_CPU_WRITE);
            src += srcImageStride;
         }
       }
@@ -696,13 +710,10 @@ st_TexImage(GLcontext * ctx,
    _mesa_unmap_teximage_pbo(ctx, unpack);
 
    if (stImage->pt) {
-      st_texture_image_unmap(stImage);
+      st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
 
-   if (stObj->pt)
-      pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
       ctx->Driver.GenerateMipmap(ctx, target, texObj);
    }
@@ -795,7 +806,8 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
       /* Image is stored in hardware format in a buffer managed by the
        * kernel.  Need to explicitly map and unmap it.
        */
-      texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
+      texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+                                            PIPE_BUFFER_USAGE_CPU_READ);
       texImage->RowStride = stImage->surface->pitch;
    }
    else {
@@ -825,8 +837,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
       }
 
       if (stImage->pt && i < depth) {
-        st_texture_image_unmap(stImage);
-        texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+        st_texture_image_unmap(ctx->st, stImage);
+        texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+                                               PIPE_BUFFER_USAGE_CPU_READ);
         dest += dstImageStride;
       }
    }
@@ -835,7 +848,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
 
    /* Unmap */
    if (stImage->pt) {
-      st_texture_image_unmap(stImage);
+      st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
 }
@@ -876,8 +889,6 @@ st_TexSubimage(GLcontext * ctx,
                  struct gl_texture_object *texObj,
                  struct gl_texture_image *texImage)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
-   struct st_texture_object *stObj = st_texture_object(texObj);
    struct st_texture_image *stImage = st_texture_image(texImage);
    GLuint dstRowStride;
    GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
@@ -899,8 +910,10 @@ st_TexSubimage(GLcontext * ctx,
     * from uploading the buffer under us.
     */
    if (stImage->pt) {
-      texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
-      dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+      texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 
+                                            PIPE_BUFFER_USAGE_CPU_WRITE);
+      if (stImage->surface)
+         dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
    }
 
    if (!texImage->Data) {
@@ -924,8 +937,9 @@ st_TexSubimage(GLcontext * ctx,
 
       if (stImage->pt && i < depth) {
          /* map next slice of 3D texture */
-        st_texture_image_unmap(stImage);
-        texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
+        st_texture_image_unmap(ctx->st, stImage);
+        texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i,
+                                               PIPE_BUFFER_USAGE_CPU_WRITE);
         src += srcImageStride;
       }
    }
@@ -937,11 +951,9 @@ st_TexSubimage(GLcontext * ctx,
    _mesa_unmap_teximage_pbo(ctx, packing);
 
    if (stImage->pt) {
-      st_texture_image_unmap(stImage);
+      st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
-
-   pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
 }
 
 
@@ -1059,8 +1071,11 @@ fallback_copy_texsubimage(GLcontext *ctx,
    }
 
    src_surf = strb->surface;
+   src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ,
+                                       PIPE_BUFFER_USAGE_CPU_READ);
 
-   dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ);
+   dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ,
+                                       PIPE_BUFFER_USAGE_CPU_WRITE);
 
    assert(width <= MAX_WIDTH);
 
@@ -1094,6 +1109,9 @@ fallback_copy_texsubimage(GLcontext *ctx,
          pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
       }
    }
+
+   screen->tex_surface_release(screen, &dest_surf);
+   screen->tex_surface_release(screen, &src_surf);
 }
 
 
@@ -1121,13 +1139,11 @@ do_copy_texsubimage(GLcontext *ctx,
    struct gl_texture_image *texImage =
       _mesa_select_tex_image(ctx, texObj, target, level);
    struct st_texture_image *stImage = st_texture_image(texImage);
-   struct st_texture_object *stObj = st_texture_object(texObj);
    GLenum baseFormat = texImage->InternalFormat;
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct st_renderbuffer *strb;
    struct pipe_context *pipe = ctx->st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *dest_surface;
    uint dest_format, src_format;
    uint do_flip = FALSE;
    GLboolean use_fallback = GL_TRUE;
@@ -1158,12 +1174,7 @@ do_copy_texsubimage(GLcontext *ctx,
    src_format = strb->surface->format;
    dest_format = stImage->pt->format;
 
-   dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
-                                          stImage->level, destZ);
-
-   if (ctx->_ImageTransferState == 0x0 &&
-       strb->surface->buffer &&
-       dest_surface->buffer) {
+   if (ctx->_ImageTransferState == 0x0) {
       /* do blit-style copy */
 
       /* XXX may need to invert image depending on window
@@ -1186,6 +1197,14 @@ do_copy_texsubimage(GLcontext *ctx,
                         x, y + height, dstx, dsty, width, height,
                         GL_COPY); /* ? */
 #else
+      struct pipe_surface *dest_surface;
+
+      dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
+                                             stImage->level, destZ,
+                                             PIPE_BUFFER_USAGE_GPU_WRITE);
+
+      assert(strb->surface->buffer);
+      assert(dest_surface->buffer);
 
       if (src_format == dest_format) {
           pipe->surface_copy(pipe,
@@ -1213,6 +1232,8 @@ do_copy_texsubimage(GLcontext *ctx,
                           0.0, PIPE_TEX_MIPFILTER_NEAREST);
          use_fallback = GL_FALSE;
       }
+
+      pipe_surface_reference(&dest_surface, NULL);
 #endif
    }
 
@@ -1223,10 +1244,6 @@ do_copy_texsubimage(GLcontext *ctx,
                                 srcX, srcY, width, height);
    }
 
-   pipe_surface_reference(&dest_surface, NULL);
-
-   pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
       ctx->Driver.GenerateMipmap(ctx, target, texObj);
    }
@@ -1486,6 +1503,7 @@ st_finalize_texture(GLcontext *ctx,
           stObj->pt->cpp != cpp ||
           stObj->pt->compressed != firstImage->base.IsCompressed) {
          pipe_texture_release(&stObj->pt);
+         ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
       }
    }
 
@@ -1499,7 +1517,11 @@ st_finalize_texture(GLcontext *ctx,
                                     firstImage->base.Width2,
                                     firstImage->base.Height2,
                                     firstImage->base.Depth2,
-                                    comp_byte);
+                                    comp_byte,
+
+                                    ( PIPE_TEXTURE_USAGE_RENDER_TARGET |
+                                      PIPE_TEXTURE_USAGE_SAMPLER ));
+
       if (!stObj->pt) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
          return GL_FALSE;
@@ -1519,7 +1541,6 @@ st_finalize_texture(GLcontext *ctx,
          if (stImage && stObj->pt != stImage->pt) {
             copy_image_data_to_texture(ctx->st, stObj, level, stImage);
            *needFlush = GL_TRUE;
-            pipe->texture_update(pipe, stObj->pt, face, (1 << level));
          }
       }
    }
index 1ca779d0a98e5eb2d2a4db787d4a046a84b18547..69be4ebdd07b42c0f26270b25cdaba617f0340aa 100644 (file)
@@ -53,6 +53,7 @@ struct bitmap_cache;
 #define ST_NEW_MESA                    0x1 /* Mesa state has changed */
 #define ST_NEW_FRAGMENT_PROGRAM        0x2
 #define ST_NEW_VERTEX_PROGRAM          0x4
+#define ST_NEW_FRAMEBUFFER             0x8
 
 
 struct st_state_flags {
@@ -121,6 +122,8 @@ struct st_context
 
    struct st_state_flags dirty;
 
+   GLboolean missing_textures;
+
    GLfloat polygon_offset_scale; /* ?? */
 
    /** Mapping from VERT_RESULT_x to post-transformed vertex slot */
index 1a0e19c2f92ae2008dd735e86147726cf8cf9a55..cfacfdd04cdde9ce63dfc539e27cc628ed4645d3 100644 (file)
@@ -123,8 +123,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
       const ubyte *srcData;
       ubyte *dstData;
 
-      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
-      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+      srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+      dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+                                        PIPE_BUFFER_USAGE_CPU_WRITE);
 
       srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer,
                                           PIPE_BUFFER_USAGE_CPU_READ)
index f68bef1207c3d4e0781a3c813ffe68d14e7c7f70..9553b34e317b178980691d1da27dd79931cfaba2 100644 (file)
@@ -75,7 +75,8 @@ st_texture_create(struct st_context *st,
                  GLuint width0,
                  GLuint height0,
                  GLuint depth0,
-                 GLuint compress_byte)
+                 GLuint compress_byte,
+                  GLuint usage )
 {
    struct pipe_texture pt, *newtex;
    struct pipe_screen *screen = st->pipe->screen;
@@ -98,6 +99,7 @@ st_texture_create(struct st_context *st,
    pt.depth[0] = depth0;
    pt.compressed = compress_byte ? 1 : 0;
    pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format);
+   pt.tex_usage = usage;
 
    newtex = screen->texture_create(screen, &pt);
 
@@ -184,25 +186,33 @@ st_texture_image_offset(const struct pipe_texture * pt,
  */
 GLubyte *
 st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
-                    GLuint zoffset)
+                    GLuint zoffset,
+                     GLuint flags )
 {
    struct pipe_screen *screen = st->pipe->screen;
    struct pipe_texture *pt = stImage->pt;
    DBG("%s \n", __FUNCTION__);
 
    stImage->surface = screen->get_tex_surface(screen, pt, stImage->face,
-                                              stImage->level, zoffset);
+                                              stImage->level, zoffset, 
+                                              flags);
 
-   return pipe_surface_map(stImage->surface);
+   if (stImage->surface)
+      return screen->surface_map(screen, stImage->surface, flags);
+   else
+      return NULL;
 }
 
 
 void
-st_texture_image_unmap(struct st_texture_image *stImage)
+st_texture_image_unmap(struct st_context *st,
+                       struct st_texture_image *stImage)
 {
+   struct pipe_screen *screen = st->pipe->screen;
+
    DBG("%s\n", __FUNCTION__);
 
-   pipe_surface_unmap(stImage->surface);
+   screen->surface_unmap(screen, stImage->surface);
 
    pipe_surface_reference(&stImage->surface, NULL);
 }
@@ -224,12 +234,15 @@ st_surface_data(struct pipe_context *pipe,
                const void *src, unsigned src_pitch,
                unsigned srcx, unsigned srcy, unsigned width, unsigned height)
 {
-   pipe_copy_rect(pipe_surface_map(dst),
+   struct pipe_screen *screen = pipe->screen;
+   void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+   pipe_copy_rect(map,
                   dst->cpp,
                   dst->pitch,
                   dstx, dsty, width, height, src, src_pitch, srcx, srcy);
 
-   pipe_surface_unmap(dst);
+   screen->surface_unmap(screen, dst);
 }
 
 
@@ -256,7 +269,8 @@ st_texture_image_data(struct pipe_context *pipe,
       if(dst->compressed)
         height /= 4;
 
-      dst_surface = screen->get_tex_surface(screen, dst, face, level, i);
+      dst_surface = screen->get_tex_surface(screen, dst, face, level, i,
+                                            PIPE_BUFFER_USAGE_CPU_WRITE);
 
       st_surface_data(pipe, dst_surface,
                      0, 0,                             /* dstx, dsty */
@@ -265,7 +279,7 @@ st_texture_image_data(struct pipe_context *pipe,
                      0, 0,                             /* source x, y */
                      dst->width[level], height);       /* width, height */
 
-      pipe_surface_reference(&dst_surface, NULL);
+      screen->tex_surface_release(screen, &dst_surface);
 
       srcUB += src_image_pitch * dst->cpp;
    }
@@ -304,8 +318,27 @@ st_texture_image_copy(struct pipe_context *pipe,
       assert(src->width[srcLevel] == width);
       assert(src->height[srcLevel] == height);
 
-      dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i);
-      src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i);
+#if 0
+      {
+         src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+                                               PIPE_BUFFER_USAGE_CPU_READ);
+         ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ);
+         map += src_surface->width * src_surface->height * 4 / 2;
+         printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n",
+                __FUNCTION__,
+                map[0], map[1], map[2], map[3],
+                src, srcLevel, dst, dstLevel);
+
+         screen->surface_unmap(screen, src_surface);
+         pipe_surface_reference(&src_surface, NULL);
+      }
+#endif
+
+      dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i,
+                                            PIPE_BUFFER_USAGE_GPU_WRITE);
+
+      src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+                                            PIPE_BUFFER_USAGE_GPU_READ);
 
       pipe->surface_copy(pipe,
                          FALSE,
@@ -315,7 +348,7 @@ st_texture_image_copy(struct pipe_context *pipe,
                         0, 0, /* srcX, Y */
                         width, copyHeight);
 
-      pipe_surface_reference(&dst_surface, NULL);
-      pipe_surface_reference(&src_surface, NULL);
+      screen->tex_surface_release(screen, &src_surface);
+      screen->tex_surface_release(screen, &dst_surface);
    }
 }
index b05762113ccf20b1c181757b584a0fff774adbbd..55d1a367b507a0ad3de73471099e8d05b665f6a1 100644 (file)
@@ -103,7 +103,8 @@ st_texture_create(struct st_context *st,
                   GLuint width0,
                   GLuint height0,
                   GLuint depth0,
-                  GLuint compress_byte);
+                  GLuint compress_byte,
+                  GLuint tex_usage );
 
 
 /* Check if an image fits into an existing texture object.
@@ -119,10 +120,12 @@ st_texture_match_image(const struct pipe_texture *pt,
 extern GLubyte *
 st_texture_image_map(struct st_context *st,
                      struct st_texture_image *stImage,
-                    GLuint zoffset);
+                    GLuint zoffset,
+                     GLuint flags);
 
 extern void
-st_texture_image_unmap(struct st_texture_image *stImage);
+st_texture_image_unmap(struct st_context *st,
+                       struct st_texture_image *stImage);
 
 
 /* Return pointers to each 2d slice within an image.  Indexed by depth