diff options
56 files changed, 1325 insertions, 796 deletions
diff --git a/bin/raw2png.py b/bin/raw2png.py index 9268257f056..880dc89f550 100755 --- a/bin/raw2png.py +++ b/bin/raw2png.py @@ -35,6 +35,7 @@ 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_LAYOUT_MIXED = 3 PIPE_FORMAT_COMP_R = 0 PIPE_FORMAT_COMP_G = 1 @@ -52,16 +53,17 @@ PIPE_FORMAT_TYPE_SNORM = 3 PIPE_FORMAT_TYPE_USCALED = 4 PIPE_FORMAT_TYPE_SSCALED = 5 PIPE_FORMAT_TYPE_SRGB = 6 +PIPE_FORMAT_TYPE_FIXED = 7 -def _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP8, TYPE ): +def _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP2, TYPE ): return ((PIPE_FORMAT_LAYOUT_RGBAZS << 0) |\ ((SWZ) << 2) |\ ((SIZEX) << 14) |\ ((SIZEY) << 17) |\ ((SIZEZ) << 20) |\ ((SIZEW) << 23) |\ - ((EXP8) << 26) |\ - ((TYPE) << 28) ) + ((EXP2) << 26) |\ + ((TYPE) << 29) ) def _PIPE_FORMAT_SWZ( SWZX, SWZY, SWZZ, SWZW ): return (((SWZX) << 0) | ((SWZY) << 3) | ((SWZZ) << 6) | ((SWZW) << 9)) @@ -69,19 +71,39 @@ def _PIPE_FORMAT_SWZ( SWZX, SWZY, SWZZ, SWZW ): 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_2( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ): + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE ) + def _PIPE_FORMAT_RGBAZS_8( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ): - return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE ) + return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 3, TYPE ) def _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE ): - return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 2, TYPE ) + return _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 6, TYPE ) + +def _PIPE_FORMAT_MIXED( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, SIGNX, SIGNY, SIGNZ, SIGNW, NORMALIZED, SCALE8 ): + return ((PIPE_FORMAT_LAYOUT_MIXED << 0) |\ + ((SWZ) << 2) |\ + ((SIZEX) << 14) |\ + ((SIZEY) << 17) |\ + ((SIZEZ) << 20) |\ + ((SIZEW) << 23) |\ + ((SIGNX) << 26) |\ + ((SIGNY) << 27) |\ + ((SIGNZ) << 28) |\ + ((SIGNW) << 29) |\ + ((NORMALIZED) << 30) |\ + ((SCALE8) << 31) ) + _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_ABGR = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R ) _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_1BGR = _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R ) _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 ) @@ -99,7 +121,7 @@ def _PIPE_FORMAT_YCBCR( REV ): ((REV) << 2) ) def _PIPE_FORMAT_DXT( LEVEL, RSIZE, GSIZE, BSIZE, ASIZE ): - return ((PIPE_FORMAT_LAYOUT_DXT << 0) | \ + return ((PIPE_FORMAT_LAYOUT_DXT << 0) | \ ((LEVEL) << 2) | \ ((RSIZE) << 5) | \ ((GSIZE) << 8) | \ @@ -114,10 +136,12 @@ PIPE_FORMAT_B8G8R8X8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1 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_A2B10G10R10_UNORM = _PIPE_FORMAT_RGBAZS_2 ( _PIPE_FORMAT_ABGR, 1, 5, 5, 5, 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_L16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 2, 2, 2, 0, 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 ) @@ -183,114 +207,35 @@ PIPE_FORMAT_R8G8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1 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_B6G5R5_SNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, PIPE_FORMAT_TYPE_SNORM ) +PIPE_FORMAT_A8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ) +PIPE_FORMAT_X8B8G8R8_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_R32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FIXED ) +PIPE_FORMAT_R32G32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FIXED ) +PIPE_FORMAT_R32G32B32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FIXED ) +PIPE_FORMAT_R32G32B32A32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FIXED ) 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_X8UB8UG8SR8S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_1BGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ) +PIPE_FORMAT_B6UG5SR5S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, 0, 1, 1, 0, 1, 0 ) 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", -} + +formats = {} +for name, value in globals().items(): + if name.startswith("PIPE_FORMAT_") and isinstance(value, int): + formats[value] = name def clip(g): @@ -332,6 +277,7 @@ translate = { PIPE_FORMAT_X8R8G8B8_UNORM: (4, 1, 1, translate_rgba), PIPE_FORMAT_B8G8R8A8_UNORM: (4, 1, 1, translate_rgba), PIPE_FORMAT_B8G8R8X8_UNORM: (4, 1, 1, translate_rgba), + PIPE_FORMAT_A8B8G8R8_SNORM: (4, 1, 1, translate_rgba), PIPE_FORMAT_YCBCR: (4, 2, 1, translate_ycbcr), PIPE_FORMAT_YCBCR_REV: (4, 2, 1, translate_ycbcr_rev), } @@ -342,15 +288,20 @@ def read_header(infile): return struct.unpack_from(header_fmt, header) def process(infilename, outfilename): + sys.stderr.write("%s -> %s\n" % (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)) + sys.stderr.write(" %ux%ux%ubpp %s\n" % (width, height, cpp*8, formats[format])) outimage = Image.new( mode='RGB', size=(width, height), color=(0,0,0)) outpixels = outimage.load() - bsize, bwidth, bheight, translate_func = translate[format] + try: + bsize, bwidth, bheight, translate_func = translate[format] + except KeyError: + sys.stderr.write('error: unsupported format %s\n' % formats[format]) + return for y in range(0, height, bheight): for x in range(0, width, bwidth): indata = map(ord, infile.read(4)) diff --git a/include/GLES/glplatform.h b/include/GLES/glplatform.h index 543464ba6fb..dbbf2b91949 100644 --- a/include/GLES/glplatform.h +++ b/include/GLES/glplatform.h @@ -51,15 +51,16 @@ extern "C" { # else # define GL_API __declspec(dllimport) # endif +# define GL_APIENTRY __stdcall #else # ifdef __GL_EXPORTS # define GL_API # else # define GL_API extern # endif +# define GL_APIENTRY #endif -#define GL_APIENTRY #ifndef APIENTRY # define APIENTRY GL_APIENTRY diff --git a/include/GLES2/gl2platform.h b/include/GLES2/gl2platform.h index 7c3a22e43e4..348daea7656 100644 --- a/include/GLES2/gl2platform.h +++ b/include/GLES2/gl2platform.h @@ -51,15 +51,16 @@ extern "C" { # else # define GL_APICALL __declspec(dllimport) # endif +# define GL_APIENTRY __stdcall #else # ifdef __GL_EXPORTS # define GL_APICALL # else # define GL_APICALL extern # endif +# define GL_APIENTRY #endif -#define GL_APIENTRY #ifdef __cplusplus } diff --git a/progs/demos/tunnel2.c b/progs/demos/tunnel2.c index 75a199af5d3..f4171a8346d 100644 --- a/progs/demos/tunnel2.c +++ b/progs/demos/tunnel2.c @@ -205,6 +205,8 @@ key(unsigned char k, int x, int y) { switch (k) { case 27: + glutDestroyWindow(channel[0]); + glutDestroyWindow(channel[1]); exit(0); break; diff --git a/progs/egl/.gitignore b/progs/egl/.gitignore index 336d82cd283..497b0ebbe33 100644 --- a/progs/egl/.gitignore +++ b/progs/egl/.gitignore @@ -3,6 +3,7 @@ demo2 demo3 eglgears eglinfo +egltri peglgears xeglgears xegl_tri diff --git a/progs/egl/Makefile b/progs/egl/Makefile index 3bde6029aca..948d7356098 100644 --- a/progs/egl/Makefile +++ b/progs/egl/Makefile @@ -12,6 +12,7 @@ PROGRAMS = \ demo1 \ demo2 \ demo3 \ + egltri \ eglinfo \ eglgears \ peglgears \ @@ -48,6 +49,13 @@ demo3.o: demo3.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include demo3.c +egltri: egltri.o $(TOP)/$(LIB_DIR)/libEGL.so + $(CC) $(CFLAGS) egltri.o -L$(TOP)/$(LIB_DIR) -lGL -lEGL $(LIBDRM_LIB) -o $@ + +egltri.o: egltri.c $(HEADERS) + $(CC) -c $(CFLAGS) -I$(TOP)/include egltri.c + + eglinfo: eglinfo.o $(TOP)/$(LIB_DIR)/libEGL.so $(CC) $(CFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lGL -lEGL $(LIBDRM_LIB) -o $@ @@ -61,12 +69,14 @@ eglgears: eglgears.o $(TOP)/$(LIB_DIR)/libEGL.so eglgears.o: eglgears.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c + peglgears: peglgears.o $(TOP)/$(LIB_DIR)/libEGL.so $(CC) $(CFLAGS) peglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ peglgears.o: peglgears.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include peglgears.c + xeglgears: xeglgears.o $(TOP)/$(LIB_DIR)/libEGL.so $(CC) $(CFLAGS) xeglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ @@ -87,7 +97,7 @@ clean: rm -f $(PROGRAMS) run: - LD_LIBRARY_PATH=$(TOP)/lib ./peglgears + LD_LIBRARY_PATH=$(TOP)/lib ./egltri debug: - LD_LIBRARY_PATH=$(TOP)/lib gdb ./peglgears + LD_LIBRARY_PATH=$(TOP)/lib gdb ./eglgears diff --git a/progs/egl/egltri.c b/progs/egl/egltri.c new file mode 100644 index 00000000000..78c67939b28 --- /dev/null +++ b/progs/egl/egltri.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Jakob Bornecrantz 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + +/* + * This program is based on eglgears and xegl_tri. + * Remixed by Jakob Bornecrantz + * + * No command line options. + * Program runs for 5 seconds then exits, outputing framerate to console + */ + +#define EGL_EGLEXT_PROTOTYPES + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <GL/gl.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#define MAX_CONFIGS 10 +#define MAX_MODES 100 + + +/* XXX this probably isn't very portable */ + +#include <sys/time.h> +#include <unistd.h> + +/* return current time (in seconds) */ +static double +current_time(void) +{ + struct timeval tv; +#ifdef __VMS + (void) gettimeofday(&tv, NULL ); +#else + struct timezone tz; + (void) gettimeofday(&tv, &tz); +#endif + return (double) tv.tv_sec + tv.tv_usec / 1000000.0; +} + + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + +static void draw() +{ + static const GLfloat verts[3][2] = { + { -1, -1 }, + { 1, -1 }, + { 0, 1 } + }; + static const GLfloat colors[3][3] = { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 } + }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + { + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(3, GL_FLOAT, 0, colors); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + glPopMatrix(); +} + +static void init() +{ + glClearColor(0.4, 0.4, 0.4, 0.0); +} + +/* new window size or exposure */ +static void reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + +static void run(EGLDisplay dpy, EGLSurface surf, int ttr) +{ + double st = current_time(); + double ct = st; + int frames = 0; + + while (ct - st < ttr) + { + double tt = current_time(); + double dt = tt - ct; + ct = tt; + + draw(); + + eglSwapBuffers(dpy, surf); + + frames++; + } + + GLfloat seconds = ct - st; + GLfloat fps = frames / seconds; + printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds, fps); +} + +int main(int argc, char *argv[]) +{ + int maj, min; + EGLContext ctx; + EGLSurface screen_surf; + EGLConfig configs[MAX_CONFIGS]; + EGLint numConfigs, i; + EGLBoolean b; + EGLDisplay d; + EGLint screenAttribs[10]; + EGLModeMESA mode[MAX_MODES]; + EGLScreenMESA screen; + EGLint count, chosenMode = 0; + GLboolean printInfo = GL_FALSE; + EGLint width = 0, height = 0; + + /* parse cmd line args */ + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-info") == 0) + { + printInfo = GL_TRUE; + } + else + printf("Warning: unknown parameter: %s\n", argv[i]); + } + + /* DBR : Create EGL context/surface etc */ + d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915"); + assert(d); + + if (!eglInitialize(d, &maj, &min)) { + printf("egltri: eglInitialize failed\n"); + exit(1); + } + + printf("egltri: EGL version = %d.%d\n", maj, min); + printf("egltri: EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR)); + + /* XXX use ChooseConfig */ + eglGetConfigs(d, configs, MAX_CONFIGS, &numConfigs); + eglGetScreensMESA(d, &screen, 1, &count); + + if (!eglGetModesMESA(d, screen, mode, MAX_MODES, &count) || count == 0) { + printf("egltri: eglGetModesMESA failed!\n"); + return 0; + } + + /* Print list of modes, and find the one to use */ + printf("egltri: Found %d modes:\n", count); + for (i = 0; i < count; i++) { + EGLint w, h; + eglGetModeAttribMESA(d, mode[i], EGL_WIDTH, &w); + eglGetModeAttribMESA(d, mode[i], EGL_HEIGHT, &h); + printf("%3d: %d x %d\n", i, w, h); + if (w > width && h > height && w <= 1280 && h <= 1024) { + width = w; + height = h; + chosenMode = i; + } + } + printf("egltri: Using screen mode/size %d: %d x %d\n", chosenMode, width, height); + + ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); + if (ctx == EGL_NO_CONTEXT) { + printf("egltri: failed to create context\n"); + return 0; + } + + /* build up screenAttribs array */ + i = 0; + screenAttribs[i++] = EGL_WIDTH; + screenAttribs[i++] = width; + screenAttribs[i++] = EGL_HEIGHT; + screenAttribs[i++] = height; + screenAttribs[i++] = EGL_NONE; + + screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs); + if (screen_surf == EGL_NO_SURFACE) { + printf("egltri: failed to create screen surface\n"); + return 0; + } + + b = eglShowScreenSurfaceMESA(d, screen, screen_surf, mode[chosenMode]); + if (!b) { + printf("egltri: show surface failed\n"); + return 0; + } + + b = eglMakeCurrent(d, screen_surf, screen_surf, ctx); + if (!b) { + printf("egltri: make current failed\n"); + return 0; + } + + if (printInfo) + { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + reshape(width, height); + + glDrawBuffer( GL_BACK ); + + run(d, screen_surf, 5.0); + + eglDestroySurface(d, screen_surf); + eglDestroyContext(d, ctx); + eglTerminate(d); + + return 0; +} diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile index 477a75184ac..252d00b6c22 100644 --- a/src/egl/drivers/xdri/Makefile +++ b/src/egl/drivers/xdri/Makefile @@ -27,6 +27,8 @@ OBJECTS = $(SOURCES:.c=.o) DRM_LIB = `pkg-config --libs libdrm` +MISC_LIBS = -ldl -lXext -lGL + .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ @@ -47,7 +49,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) -noprefix \ -major 1 -minor 0 \ -install $(TOP)/$(LIB_DIR) \ - -ldl $(OBJECTS) $(DRM_LIB) + $(OBJECTS) $(DRM_LIB) $(MISC_LIBS) clean: diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 71d4f15371d..5e50d6034ac 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -118,6 +118,10 @@ struct xdri_egl_config }; +/* XXX temp hack */ +static struct xdri_egl_driver *TheDriver = NULL; + + /** cast wrapper */ static struct xdri_egl_driver * xdri_egl_driver(_EGLDriver *drv) @@ -154,6 +158,21 @@ lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config) +/** Get size of given window */ +static Status +get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} + + /** * Produce a set of EGL configs. * Note that we get the list of GLcontextModes from the GLX library. @@ -273,24 +292,25 @@ dri_context_modes_create(unsigned count, size_t minimum_size) static __DRIscreen * dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn) { - /* unused? */ - return NULL; + assert(TheDriver); + + return &TheDriver->driScreen; } static GLboolean -dri_window_exists(__DRInativeDisplay *dpy, __DRIid draw) +dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw) { return EGL_TRUE; } static GLboolean -dri_create_context(__DRInativeDisplay *dpy, int screenNum, int configID, +dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID, void * contextID, drm_context_t * hw_context) { assert(configID >= 0); - return XF86DRICreateContextWithConfig(dpy, screenNum, + return XF86DRICreateContextWithConfig(ndpy, screenNum, configID, contextID, hw_context); } @@ -325,7 +345,7 @@ dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable) static GLboolean -dri_get_drawable_info(__DRInativeDisplay *dpy, int scrn, +dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn, __DRIid draw, unsigned int * index, unsigned int * stamp, int * x, int * y, int * width, int * height, int * numClipRects, drm_clip_rect_t ** pClipRects, @@ -335,7 +355,7 @@ dri_get_drawable_info(__DRInativeDisplay *dpy, int scrn, { _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - if (!XF86DRIGetDrawableInfo(dpy, scrn, draw, index, stamp, + if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp, x, y, width, height, numClipRects, pClipRects, backX, backY, @@ -570,17 +590,29 @@ load_dri_driver(struct xdri_egl_driver *xdri_drv) char filename[100]; int flags = RTLD_NOW; - snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name); + /* try "egl_xxx_dri.so" first */ + snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name); _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); - xdri_drv->dri_driver_handle = dlopen(filename, flags); - if (!xdri_drv->dri_driver_handle) { - _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", - filename, dlerror()); + if (xdri_drv->dri_driver_handle) { + _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); + return EGL_TRUE; + } + else { + _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror()); + } - return EGL_FALSE; + /* try regular "xxx_dri.so" next */ + snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name); + _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); + xdri_drv->dri_driver_handle = dlopen(filename, flags); + if (xdri_drv->dri_driver_handle) { + _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); + return EGL_TRUE; } - return EGL_TRUE; + + _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror()); + return EGL_FALSE; } @@ -646,6 +678,24 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +static _EGLProc +xdri_eglGetProcAddress(const char *procname) +{ +#if 0 + _EGLDriver *drv = NULL; + + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/ + _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname); + return proc; +#elif 0 + return (_EGLProc) st_get_proc_address(procname); +#else + return NULL; +#endif +} + + /** * Called via eglCreateContext(), drv->API.CreateContext(). */ @@ -724,6 +774,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _EGLDisplay *disp = _eglLookupDisplay(dpy); struct xdri_egl_surface *xdri_surf; int scrn = DefaultScreen(disp->Xdpy); + uint width, height; xdri_surf = CALLOC_STRUCT(xdri_egl_surface); if (!xdri_surf) @@ -744,6 +795,10 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _eglSaveSurface(&xdri_surf->Base); + get_drawable_size(disp->Xdpy, window, &width, &height); + xdri_surf->Base.Width = width; + xdri_surf->Base.Height = height; + _eglLog(_EGL_DEBUG, "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d", (int) window, _eglGetSurfaceHandle(&xdri_surf->Base), @@ -790,9 +845,8 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - __GLXdisplayPrivate *priv = __glXInitialize(disp->Xdpy); - __GLXscreenConfigs *scrn = priv->screenConfigs; - __DRIscreen *psc = &scrn->driScreen; + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + __DRIscreen *psc = &xdri_drv->driScreen; __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy, xdri_surf->driDrawable, psc->private); @@ -818,10 +872,15 @@ _eglMain(_EGLDisplay *disp, const char *args) if (!xdri_drv) return NULL; + /* XXX temp hack */ + TheDriver = xdri_drv; + _eglInitDriverFallbacks(&xdri_drv->Base); xdri_drv->Base.API.Initialize = xdri_eglInitialize; xdri_drv->Base.API.Terminate = xdri_eglTerminate; + xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress; + xdri_drv->Base.API.CreateContext = xdri_eglCreateContext; xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent; xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface; diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index d12f66245c0..db1c4c10e08 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -6,7 +6,7 @@ #include <GLES/gl.h> -#define MAX_ATTRIBS 100 +#define MAX_ATTRIBS 128 #define FIRST_ATTRIB EGL_BUFFER_SIZE @@ -17,7 +17,11 @@ struct _egl_config }; -#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL) +#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) \ + assert((ATTR) - FIRST_ATTRIB < MAX_ATTRIBS); \ + ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL) + + #define GET_CONFIG_ATTRIB(CONF, ATTR) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB]) diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 9140faeea9d..85a75525c8b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -37,6 +37,8 @@ static unsigned trim( unsigned count, unsigned first, unsigned incr ) { + if (count < first) + return 0; return count - (count - first) % incr; } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 6b928118707..8e834501a4c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -184,7 +184,6 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) if (!load_input( cp, i, linear )) return FALSE; cp->insn_counter++; - debug_printf("\n"); } return TRUE; @@ -316,7 +315,6 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) aos_release_xmm_reg( cp, data.idx ); cp->insn_counter++; - debug_printf("\n"); } return TRUE; diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 83ea0be74b8..8505d333bda 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -221,7 +221,7 @@ pb_check_alignment(size_t requested, size_t provided) static INLINE boolean pb_check_usage(unsigned requested, unsigned provided) { - return (requested & provided) == provided ? TRUE : FALSE; + return (requested & provided) == requested ? TRUE : FALSE; } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 92aff889259..a395c630cc7 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -573,7 +573,8 @@ tgsi_dump_declaration( if (decl->Declaration.Semantic) { TXT( ", " ); ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); - if (decl->Semantic.SemanticIndex != 0) { + if (decl->Semantic.SemanticIndex != 0 || + decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { CHR( '[' ); UID( decl->Semantic.SemanticIndex ); CHR( ']' ); diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 2815e61345c..cf4964b26b3 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -581,6 +581,7 @@ i915_texture_create(struct pipe_screen *screen, struct i915_screen *i915screen = i915_screen(screen); struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); + size_t tex_size; if (!tex) return NULL; @@ -600,14 +601,22 @@ i915_texture_create(struct pipe_screen *screen, goto fail; } + tex_size = tex->stride * tex->total_nblocksy; + tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->stride * - tex->total_nblocksy); + tex_size); if (!tex->buffer) goto fail; +#if 0 + void *ptr = ws->buffer_map(ws, tex->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + memset(ptr, 0x80, tex_size); + ws->buffer_unmap(ws, tex->buffer); +#endif + return &tex->base; fail: @@ -710,6 +719,8 @@ i915_texture_blanket(struct pipe_screen * screen, return NULL; tex->base = *base; + tex->base.refcount = 1; + tex->base.screen = screen; tex->stride = stride[0]; diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 24b91fbc794..901c8f83e75 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -154,8 +154,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, /* note: reference counting */ pipe_buffer_reference(ws, &softpipe->constants[shader].buffer, - buf->buffer); - softpipe->constants[shader].size = buf->size; + buf ? buf->buffer : NULL); + softpipe->constants[shader].size = buf ? buf->size : 0; softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 4db045cdc3d..f775591352b 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -122,8 +122,10 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ - spt->buffer = surf.buffer; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); spt->stride[0] = surf.stride; + spt->buffer = surf.buffer; return spt->buffer != NULL; } @@ -162,6 +164,39 @@ softpipe_texture_create(struct pipe_screen *screen, } +static struct pipe_texture * +softpipe_texture_blanket(struct pipe_screen * screen, + const struct pipe_texture *base, + const unsigned *stride, + struct pipe_buffer *buffer) +{ + struct softpipe_texture *spt; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *base; + spt->base.refcount = 1; + spt->base.screen = screen; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); + spt->stride[0] = stride[0]; + + pipe_buffer_reference(screen->winsys, &spt->buffer, buffer); + + return &spt->base; +} + + static void softpipe_texture_release(struct pipe_screen *screen, struct pipe_texture **pt) @@ -309,6 +344,7 @@ void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; + screen->texture_blanket = softpipe_texture_blanket; screen->texture_release = softpipe_texture_release; screen->get_tex_surface = softpipe_get_tex_surface; diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index efb57a394e4..8db03296156 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte return &buffer->base; } +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + /* * Surface functions. @@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert((size_t)"intel_i915_surface_release is deprecated" & 0); } + /* * Fence functions */ @@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + /* * Misc functions */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index abf02539171..3f8b3f585c7 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -48,14 +48,23 @@ struct intel_be_buffer { struct _DriBufferObject *driBO; }; +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + static INLINE struct intel_be_buffer * -intel_be_buffer( struct pipe_buffer *buf ) +intel_be_buffer(struct pipe_buffer *buf) { return (struct intel_be_buffer *)buf; } static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) +dri_bo(struct pipe_buffer *buf) { return intel_be_buffer(buf)->driBO; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index cfecebdb8c7..f2412217f36 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, static void intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) { - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); struct pipe_screen *screen = intelScreen->base.screen; struct pipe_texture *texture; struct pipe_texture templat; struct pipe_surface *surface; - struct pipe_buffer *buffer = &be_buf->base; + struct pipe_buffer *buffer; unsigned pitch; assert(intelScreen->front.cpp == 4); - /* XXX create a intel_be function for this */ - { - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, handle); - - memset(be_buf, 0, sizeof(*be_buf)); - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(intelScreen->front.buffer); - be_buf->driBO = intelScreen->front.buffer; - } + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 9c7ff065ffb..e67b49f3ada 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -12,7 +12,7 @@ PIPE_DRIVERS = \ DRIVER_SOURCES = \ intel_swapbuffers.c \ intel_context.c \ - intel_screen.c \ + intel_device.c \ intel_egl.c C_SOURCES = \ diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7205fa4483a..927addb834c 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -27,7 +27,7 @@ #include "i915simple/i915_screen.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; + struct intel_device *device = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_screen = screen; + intel->intel_device = device; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -161,23 +161,37 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes intel->base.hardware_unlock = intel_unlock_hardware; intel->base.hardware_locked = intel_locked_hardware; - intel_be_init_context(&intel->base, &screen->base); + intel_be_init_context(&intel->base, &device->base); #if 0 pipe = intel_create_softpipe(intel, screen->winsys); #else - pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); #endif pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); - screen->dummy = intel; + device->dummy = intel; return TRUE; } +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) { @@ -206,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_device *device = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) @@ -221,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index f05a213ff06..dfa4720b081 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -47,7 +47,7 @@ struct intel_context struct st_context *st; - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* new egl stuff */ struct egl_drm_device *egl_device; @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_screen *screen; + struct intel_device *device; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index 2818b9676c5..b9649cbec71 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -32,7 +32,7 @@ #include "i915simple/i915_screen.h" #include "intel_context.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_batchbuffer.h" #include "intel_egl.h" @@ -41,24 +41,23 @@ extern const struct dri_extension card_extensions[]; int -intel_init_driver(struct egl_drm_device *device) +intel_create_device(struct egl_drm_device *device) { - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* Allocate the private area */ - intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) return FALSE; - device->priv = (void *)intel_screen; - intel_screen->device = device; + device->priv = (void *)intel_device; + intel_device->device = device; - /** TODO JB: ugly hack */ - intel_screen->deviceID = PCI_CHIP_I945_GM; + intel_device->deviceID = device->deviceID; - intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); - intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); /* hack */ driInitExtensions(NULL, card_extensions, GL_FALSE); @@ -67,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device) } int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual) { @@ -76,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; - intelfb->screen = drawable->device->priv; + intelfb->device = drawable->device->priv; if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; @@ -108,6 +120,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable, return GL_FALSE; } - drawable->priv = (void *) intelfb; - return GL_TRUE; + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; } diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_device.h index 9b990b48e77..2f9d4f887e5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_device.h @@ -36,7 +36,7 @@ struct pipe_screen; struct egl_drm_device; struct intel_context; -struct intel_screen +struct intel_device { struct intel_be_device base; struct pipe_screen *pipe; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 6865bfa3d4f..55f4d92afb3 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -13,6 +13,7 @@ #include "eglmode.h" #include "eglscreen.h" #include "eglsurface.h" +#include "egllog.h" #include "intel_egl.h" @@ -23,18 +24,43 @@ #include "state_tracker/st_public.h" -struct egl_drm_device* egl_drm_create_device(int drmFD); +#define MAX_SCREENS 16 -struct egl_drm_device* +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 0; + + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); + file = fopen(path, "r"); + if (!file) { + _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); + return; + } + + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* egl_drm_create_device(int drmFD) { struct egl_drm_device *device = malloc(sizeof(*device)); memset(device, 0, sizeof(*device)); device->drmFD = drmFD; - if (!intel_init_driver(device)) { - printf("EGL: failed to initalize device\n"); + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + + if (!intel_create_device(device)) { free(device); + return NULL; } return device; @@ -42,11 +68,17 @@ egl_drm_create_device(int drmFD) __GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +struct drm_screen; + struct drm_driver { _EGLDriver base; /* base class/object */ drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + struct egl_drm_device *device; }; @@ -68,17 +100,26 @@ struct drm_screen { _EGLScreen base; - /* backing buffer and crtc */ + /* currently only support one connector */ + drmModeConnectorPtr connector; + uint32_t connectorID; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* backing buffer */ drmBO buffer; + + /* framebuffer */ drmModeFBPtr fb; uint32_t fbID; - drmModeCrtcPtr crtc; - /* currently only support one connector */ - drmModeConnectorPtr connector; - drmModeEncoderPtr encoder; - uint32_t connectorID; - uint32_t encoderID; + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; struct drm_mode_modeinfo *mode; @@ -105,28 +146,17 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } -static void -print_modes(drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); - } -} static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { - printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; unsigned count_connectors = 0; + int num_screens = 0; EGLint i; int fd; @@ -147,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) if (res) count_connectors = res->count_connectors; - for(i = 0; i < count_connectors; i++) { + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); if (!connector) continue; - if (connector->connection == DRM_MODE_DISCONNECTED) { + if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector(connector); continue; } @@ -165,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; } + drm_drv->count_screens = num_screens; /* for now we only have one config */ _EGLConfig *config = calloc(1, sizeof(*config)); @@ -184,17 +216,64 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drv->Initialized = EGL_TRUE; *major = 1; - *minor = 0; + *minor = 4; return EGL_TRUE; } +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { - /* TODO: clean up */ - free(drv); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; + + intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); + + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + + _eglCleanupDisplay(_eglLookupDisplay(dpy)); + free(drm_drv); + return EGL_TRUE; } @@ -237,7 +316,9 @@ visual_from_config(_EGLConfig *conf) visual->doubleBufferMode = 1; visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; return visual; } @@ -314,6 +395,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) if (fc->base.IsBound) { fc->base.DeletePending = EGL_TRUE; } else { + intel_destroy_context(fc->context); + free(fc->context); free(fc); } return EGL_TRUE; @@ -333,6 +416,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat return EGL_NO_SURFACE; } + static EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -480,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, size_t size = mode->Height * pitch; int ret; - /* TODO if allready shown take down */ + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | @@ -490,10 +575,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - if (ret) { - printf("failed to create framebuffer (ret %d)\n", ret); + if (ret) return EGL_FALSE; - } prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); @@ -510,10 +593,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, goto err_bo; scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) { - printf("oh noes, no matching mode found\n"); + if (!scrn->mode) goto err_fb; - } ret = drmModeSetCrtc( drm_drv->device->drmFD, @@ -529,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, scrn->front.width = mode->Width; scrn->front.height = mode->Height; + scrn->surf = surf; intel_bind_frontbuffer(surf->drawable, &scrn->front); + scrn->shown = 1; + return EGL_TRUE; err_fb: @@ -549,14 +633,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) if (fs->base.IsBound) { fs->base.DeletePending = EGL_TRUE; } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); free(fs); } return EGL_TRUE; } - - static EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) { @@ -569,12 +654,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re if (!b) return EGL_FALSE; - /* XXX this is where we'd do the hardware context switch */ - (void) drawSurf; - (void) readSurf; - (void) ctx; + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -602,7 +690,6 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; - printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { @@ -626,6 +713,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.SwapBuffers = drm_swap_buffers; drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 18e84e8eeab..1ee27e0847a 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -2,10 +2,15 @@ #ifndef _INTEL_EGL_H_ #define _INTEL_EGL_H_ +#include <xf86drm.h> + struct egl_drm_device { void *priv; int drmFD; + + drmVersionPtr version; + int deviceID; }; struct egl_drm_context @@ -32,9 +37,15 @@ struct egl_drm_frontbuffer #include "GL/internal/glcore.h" -int intel_init_driver(struct egl_drm_device *device); +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); void intel_swap_buffers(struct egl_drm_drawable *draw); void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index bfff6f935fd..2edcbc79fff 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" #include "intel_reg.h" @@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - intel = intel_fb->screen->dummy; + intel = intel_fb->device->dummy; if (!intel) { printf("No dummy context\n"); return; diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 83b8bb95b18..708a58b781f 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) surf->Base.DeletePending = EGL_TRUE; } else { + XFreeGC(surf->Dpy, surf->Gc); st_unreference_framebuffer(&surf->Framebuffer); free(surf); } diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 3cf2146dceb..67cffead00f 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -310,8 +310,10 @@ void driInitSingleExtension( GLcontext * ctx, */ offset = _glapi_add_dispatch( functions, parameter_signature ); if (offset == -1) { +#if 0 /* this causes noise with egl */ fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " "to add %s!\n", functions[0]); +#endif } else if (ext->functions[i].remap_index != -1) { driDispatchRemapTable[ ext->functions[i].remap_index ] = diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 65e665ee39b..70ef7264379 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1821,7 +1821,7 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target, tdfxTexInfo *ti; int memNeeded; - tObj = ctx->Texture.Proxy2D; + tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = TDFX_TEXTURE_DATA(tObj); diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c index 5e0af26a013..3634444c855 100644 --- a/src/mesa/glapi/glapi_getproc.c +++ b/src/mesa/glapi/glapi_getproc.c @@ -411,7 +411,7 @@ add_function_name( const char * funcName ) * \returns * The offset in the dispatch table of the named function. A pointer to the * driver's implementation of the named function should be stored at - * \c dispatch_table[\c offset]. + * \c dispatch_table[\c offset]. Return -1 if error/problem. * * \sa glXGetProcAddress * @@ -460,7 +460,7 @@ _glapi_add_dispatch( const char * const * function_names, */ if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l') - return GL_FALSE; + return -1; /* Determine if the named function already exists. If the function does * exist, it must have the same parameter signature as the function diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 2e6bb76586e..b990369a9e8 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -361,6 +361,7 @@ _mesa_PushAttrib(GLbitfield mask) ctx->Texture.Unit[u].Current1DArray->RefCount++; ctx->Texture.Unit[u].Current2DArray->RefCount++; } + attr = MALLOC_STRUCT( gl_texture_attrib ); MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); /* copy state of the currently bound texture objects */ diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index 610acba3068..97120398f9b 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -30,6 +30,7 @@ #include "image.h" #include "macros.h" #include "state.h" +#include "teximage.h" /** @@ -305,49 +306,6 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; - case GL_PROXY_TEXTURE_1D: - texObj = ctx->Texture.Proxy1D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_2D: - texObj = ctx->Texture.Proxy2D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_3D: - texObj = ctx->Texture.Proxy3D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = ctx->Texture.ProxyCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -396,8 +354,19 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, proxy = GL_TRUE; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + proxy = _mesa_is_proxy_texture(target); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); + return; + } + } } assert(table); @@ -499,26 +468,6 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -547,8 +496,15 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; + /* try texture targets */ + texObj = _mesa_select_tex_object(ctx, texUnit, target); + if (texObj && !_mesa_is_proxy_texture(target)) { + table = &texObj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); + return; + } } assert(table); @@ -636,22 +592,6 @@ _mesa_GetColorTable( GLenum target, GLenum format, } switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -672,8 +612,18 @@ _mesa_GetColorTable( GLenum target, GLenum format, table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj && !_mesa_is_proxy_texture(target)) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); + return; + } + } } ASSERT(table); @@ -781,65 +731,41 @@ _mesa_GetColorTable( GLenum target, GLenum format, void GLAPIENTRY _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) { + GLfloat *scale, *bias; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - if (!ctx->Extensions.SGI_texture_color_table) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; - } - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableScale, params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableBias, params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; + case GL_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; + break; + case GL_TEXTURE_COLOR_TABLE_SGI: + scale = ctx->Pixel.TextureColorTableScale; + bias = ctx->Pixel.TextureColorTableBias; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); + return; + } + + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + COPY_4V(scale, params); + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + COPY_4V(bias, params); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; } ctx->NewState |= _NEW_PIXEL; @@ -879,40 +805,6 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -981,8 +873,19 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameterfv(target)"); + return; + } + } } assert(table); @@ -1029,40 +932,6 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -1161,8 +1030,19 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); - return; + /* Try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameteriv(target)"); + return; + } + } } assert(table); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 33f6d2c0d0c..279880cf401 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -500,19 +500,12 @@ alloc_shared_state( GLcontext *ctx ) if (!ss->Default2DArray) goto cleanup; - /* Effectively bind the default textures to all texture units */ - ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default1DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; + /* sanity check */ + assert(ss->Default1D->RefCount == 1); _glthread_INIT_MUTEX(ss->TexMutex); ss->TextureStateStamp = 0; - #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -522,10 +515,9 @@ alloc_shared_state( GLcontext *ctx ) goto cleanup; #endif - return GL_TRUE; - cleanup: +cleanup: /* Ran out of memory at some point. Free everything and return NULL */ if (ss->DisplayList) _mesa_DeleteHashTable(ss->DisplayList); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index a24021c63fd..7fb0a211d7a 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -870,6 +870,8 @@ struct dd_function_table { GLsizei *length, GLcharARB *sourceOut); void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location, GLfloat *params); + void (*GetUniformiv)(GLcontext *ctx, GLuint program, GLint location, + GLint *params); GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program, const GLcharARB *name); GLboolean (*IsProgram)(GLcontext *ctx, GLuint name); diff --git a/src/mesa/main/execmem.c b/src/mesa/main/execmem.c index 40f66d7da2d..aa40b022051 100644 --- a/src/mesa/main/execmem.c +++ b/src/mesa/main/execmem.c @@ -36,7 +36,7 @@ -#if defined(__linux__) +#if defined(__linux__) || defined(__OpenBSD__) /* * Allocate a large block of memory which can hold code then dole it out @@ -47,6 +47,16 @@ #include <sys/mman.h> #include "mm.h" +#ifdef MESA_SELINUX +#include <selinux/selinux.h> +#endif + + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + + #define EXEC_HEAP_SIZE (10*1024*1024) _glthread_DECLARE_STATIC_MUTEX(exec_mutex); diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index e4ff575e18e..0ae69bdce7a 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -172,22 +172,17 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) { if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - ctx->Driver.DeleteTexture(ctx, att->Texture); - } - else { + if (ctx->Driver.FinishRenderTexture) { /* tell driver that we're done rendering to this texture. */ - if (ctx->Driver.FinishRenderTexture) { - ctx->Driver.FinishRenderTexture(ctx, att); - } + ctx->Driver.FinishRenderTexture(ctx, att); } - att->Texture = NULL; + _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ + ASSERT(!att->Texture); } if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) { - ASSERT(att->Renderbuffer); ASSERT(!att->Texture); - _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */ + ASSERT(!att->Renderbuffer); } att->Type = GL_NONE; att->Complete = GL_TRUE; @@ -213,8 +208,8 @@ _mesa_set_texture_attachment(GLcontext *ctx, /* new attachment */ _mesa_remove_attachment(ctx, att); att->Type = GL_TEXTURE; - att->Texture = texObj; - texObj->RefCount++; + assert(!att->Texture); + _mesa_reference_texobj(&att->Texture, texObj); } /* always update these fields */ diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 96f1b30c9b2..dab449fc09a 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -38,6 +38,7 @@ #include "fbobject.h" #include "framebuffer.h" #include "renderbuffer.h" +#include "texobj.h" @@ -192,17 +193,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); } if (att->Texture) { - /* render to texture */ - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - ctx->Driver.DeleteTexture(ctx, att->Texture); - } - } + _mesa_reference_texobj(&att->Texture, NULL); } + ASSERT(!att->Renderbuffer); + ASSERT(!att->Texture); att->Type = GL_NONE; - att->Texture = NULL; } /* unbind _Depth/_StencilBuffer to decr ref counts */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 00e7d5d395d..2d6be1983c6 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1404,6 +1404,7 @@ struct gl_texture_image */ struct gl_texture_object { + _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ GLuint Name; /**< the user-visible texture object ID */ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ @@ -1578,6 +1579,7 @@ struct gl_texture_attrib struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; +#if 0 struct gl_texture_object *Proxy1D; struct gl_texture_object *Proxy2D; struct gl_texture_object *Proxy3D; @@ -1585,6 +1587,9 @@ struct gl_texture_attrib struct gl_texture_object *ProxyRect; struct gl_texture_object *Proxy1DArray; struct gl_texture_object *Proxy2DArray; +#else + struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; +#endif /** GL_EXT_shared_texture_palette */ GLboolean SharedPalette; diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c index b7b2f791a52..f0db0d2a818 100644 --- a/src/mesa/main/shaders.c +++ b/src/mesa/main/shaders.c @@ -309,11 +309,7 @@ void GLAPIENTRY _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params) { GET_CURRENT_CONTEXT(ctx); - GLfloat fparams[16]; /* XXX is 16 enough? */ - GLuint i; - ctx->Driver.GetUniformfv(ctx, program, location, fparams); - for (i = 0; i < 16; i++) - params[i] = (GLint) fparams[i]; /* XXX correct? */ + ctx->Driver.GetUniformiv(ctx, program, location, params); } diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index eed19375176..36557f19fd4 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -767,15 +767,15 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, case GL_TEXTURE_1D: return texUnit->Current1D; case GL_PROXY_TEXTURE_1D: - return ctx->Texture.Proxy1D; + return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; case GL_TEXTURE_2D: return texUnit->Current2D; case GL_PROXY_TEXTURE_2D: - return ctx->Texture.Proxy2D; + return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; case GL_TEXTURE_3D: return texUnit->Current3D; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.Proxy3D; + return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: @@ -787,25 +787,25 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, ? texUnit->CurrentCubeMap : NULL; case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyCubeMap : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle ? texUnit->CurrentRect : NULL; case GL_PROXY_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle - ? ctx->Texture.ProxyRect : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; case GL_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current1DArray : NULL; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy1DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; case GL_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current2DArray : NULL; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy2DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; default: _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); return NULL; @@ -932,106 +932,106 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level) case GL_PROXY_TEXTURE_1D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_3D: if (level >= ctx->Const.Max3DTextureLevels) return NULL; - texImage = ctx->Texture.Proxy3D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy3D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy3D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_CUBE_MAP: if (level >= ctx->Const.MaxCubeTextureLevels) return NULL; - texImage = ctx->Texture.ProxyCubeMap->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyCubeMap->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyCubeMap; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]; } return texImage; case GL_PROXY_TEXTURE_RECTANGLE_NV: if (level > 0) return NULL; - texImage = ctx->Texture.ProxyRect->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyRect->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyRect; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]; } return texImage; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]; } return texImage; default: @@ -2611,7 +2611,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 1, border)) { /* when error, clear all proxy texture image parameters */ if (texImage) - clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]); + clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]); } else { /* no error, set the tex image parameters */ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 606e62d7a08..b77a00dd15c 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -108,6 +108,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ + _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -155,6 +156,11 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) (void) ctx; + /* Set Target to an invalid value. With some assertions elsewhere + * we can try to detect possible use of deleted textures. + */ + texObj->Target = 0x99; + #if FEATURE_colortable _mesa_free_colortable_data(&texObj->Palette); #endif @@ -168,6 +174,9 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) } } + /* destroy the mutex -- it may have allocated memory (eg on bsd) */ + _glthread_DESTROY_MUTEX(texObj->Mutex); + /* free this object */ _mesa_free(texObj); } @@ -186,6 +195,7 @@ void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ) { + dest->Target = src->Target; dest->Name = src->Name; dest->Priority = src->Priority; dest->BorderColor[0] = src->BorderColor[0]; @@ -218,6 +228,94 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, /** + * Check if the given texture object is valid by examining its Target field. + * For debugging only. + */ +static GLboolean +valid_texture_object(const struct gl_texture_object *tex) +{ + switch (tex->Target) { + case 0: + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: + return GL_TRUE; + case 0x99: + _mesa_problem(NULL, "invalid reference to a deleted texture object"); + return GL_FALSE; + default: + _mesa_problem(NULL, "invalid texture object Target value"); + return GL_FALSE; + } +} + + +/** + * Reference (or unreference) a texture object. + * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero). + * If 'tex' is non-null, increment its refcount. + */ +void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex) +{ + assert(ptr); + if (*ptr == tex) { + /* no change */ + return; + } + + if (*ptr) { + /* Unreference the old texture */ + GLboolean deleteFlag = GL_FALSE; + struct gl_texture_object *oldTex = *ptr; + + assert(valid_texture_object(oldTex)); + + _glthread_LOCK_MUTEX(oldTex->Mutex); + ASSERT(oldTex->RefCount > 0); + oldTex->RefCount--; + + deleteFlag = (oldTex->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldTex->Mutex); + + if (deleteFlag) { + GET_CURRENT_CONTEXT(ctx); + if (ctx) + ctx->Driver.DeleteTexture(ctx, oldTex); + else + _mesa_problem(NULL, "Unable to delete texture, no context"); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (tex) { + /* reference new texture */ + assert(valid_texture_object(tex)); + _glthread_LOCK_MUTEX(tex->Mutex); + if (tex->RefCount == 0) { + /* this texture's being deleted (look just above) */ + /* Not sure this can every really happen. Warn if it does. */ + _mesa_problem(NULL, "referencing deleted texture object"); + *ptr = NULL; + } + else { + tex->RefCount++; + *ptr = tex; + } + _glthread_UNLOCK_MUTEX(tex->Mutex); + } +} + + + +/** * Report why a texture object is incomplete. * * \param t texture object. @@ -613,8 +711,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj) /** * Check if the given texture object is bound to any texture image units and - * unbind it if so. - * XXX all RefCount accesses should be protected by a mutex. + * unbind it if so (revert to default textures). */ static void unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) @@ -623,42 +720,26 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; - struct gl_texture_object **curr = NULL; - if (texObj == unit->Current1D) { - curr = &unit->Current1D; - unit->Current1D = ctx->Shared->Default1D; + _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D); } else if (texObj == unit->Current2D) { - curr = &unit->Current2D; - unit->Current2D = ctx->Shared->Default2D; + _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D); } else if (texObj == unit->Current3D) { - curr = &unit->Current3D; - unit->Current3D = ctx->Shared->Default3D; + _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D); } else if (texObj == unit->CurrentCubeMap) { - curr = &unit->CurrentCubeMap; - unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; + _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); } else if (texObj == unit->CurrentRect) { - curr = &unit->CurrentRect; - unit->CurrentRect = ctx->Shared->DefaultRect; + _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect); } else if (texObj == unit->Current1DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default1DArray; + _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray); } else if (texObj == unit->Current2DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default2DArray; - } - - if (curr) { - (*curr)->RefCount++; - texObj->RefCount--; - if (texObj == unit->_Current) - unit->_Current = *curr; + _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray); } } } @@ -694,8 +775,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { - GLboolean deleted; - _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. @@ -705,10 +784,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) unbind_texobj_from_fbo(ctx, delObj); /* Check if this texture is currently bound to any texture units. - * If so, unbind it and decrement the reference count. + * If so, unbind it. */ unbind_texobj_from_texunits(ctx, delObj); + _mesa_unlock_texture(ctx, delObj); + ctx->NewState |= _NEW_TEXTURE; /* The texture _name_ is now free for re-use. @@ -718,23 +799,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* The actual texture object will not be freed until it's no - * longer bound in any context. - * XXX all RefCount accesses should be protected by a mutex. + /* Unreference the texobj. If refcount hits zero, the texture + * will be deleted. */ - delObj->RefCount--; - deleted = (delObj->RefCount == 0); - _mesa_unlock_texture(ctx, delObj); - - /* We know that refcount went to zero above, so this is - * the only pointer left to delObj, so we don't have to - * worry about locking any more: - */ - if (deleted) { - ASSERT(delObj->Name != 0); /* Never delete default tex objs */ - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)(ctx, delObj); - } + _mesa_reference_texobj(&delObj, NULL); } } } @@ -762,7 +830,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *oldTexObj; struct gl_texture_object *newTexObj = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -771,62 +838,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) _mesa_lookup_enum_by_nr(target), (GLint) texName); /* - * Get pointer to currently bound texture object (oldTexObj) - */ - switch (target) { - case GL_TEXTURE_1D: - oldTexObj = texUnit->Current1D; - break; - case GL_TEXTURE_2D: - oldTexObj = texUnit->Current2D; - break; - case GL_TEXTURE_3D: - oldTexObj = texUnit->Current3D; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentCubeMap; - break; - case GL_TEXTURE_RECTANGLE_NV: - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentRect; - break; - case GL_TEXTURE_1D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current1DArray; - break; - case GL_TEXTURE_2D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current2DArray; - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - - if (oldTexObj->Name == texName) { - /* XXX this might be wrong. If the texobj is in use by another - * context and a texobj parameter was changed, this might be our - * only chance to update this context's hardware state. - * Note that some applications re-bind the same texture a lot so we - * want to handle that case quickly. - */ - return; /* rebinding the same texture- no change */ - } - - /* * Get pointer to new texture object (newTexObj) */ if (texName == 0) { @@ -854,7 +865,8 @@ _mesa_BindTexture( GLenum target, GLuint texName ) newTexObj = ctx->Shared->Default2DArray; break; default: - ; /* Bad targets are caught above */ + _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)"); + return; } } else { @@ -900,28 +912,30 @@ _mesa_BindTexture( GLenum target, GLuint texName ) newTexObj->Target = target; } - /* XXX all RefCount accesses should be protected by a mutex. */ - newTexObj->RefCount++; + assert(valid_texture_object(newTexObj)); - /* do the actual binding, but first flush outstanding vertices: - */ + /* flush before changing binding */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* Do the actual binding. The refcount on the previously bound + * texture object will be decremented. It'll be deleted if the + * count hits zero. + */ switch (target) { case GL_TEXTURE_1D: - texUnit->Current1D = newTexObj; + _mesa_reference_texobj(&texUnit->Current1D, newTexObj); break; case GL_TEXTURE_2D: - texUnit->Current2D = newTexObj; + _mesa_reference_texobj(&texUnit->Current2D, newTexObj); break; case GL_TEXTURE_3D: - texUnit->Current3D = newTexObj; + _mesa_reference_texobj(&texUnit->Current3D, newTexObj); break; case GL_TEXTURE_CUBE_MAP_ARB: - texUnit->CurrentCubeMap = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj); break; case GL_TEXTURE_RECTANGLE_NV: - texUnit->CurrentRect = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj); break; case GL_TEXTURE_1D_ARRAY_EXT: texUnit->Current1DArray = newTexObj; @@ -930,6 +944,7 @@ _mesa_BindTexture( GLenum target, GLuint texName ) texUnit->Current2DArray = newTexObj; break; default: + /* Bad target should be caught above */ _mesa_problem(ctx, "bad target in BindTexture"); return; } @@ -937,18 +952,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) /* Pass BindTexture call to device driver */ if (ctx->Driver.BindTexture) (*ctx->Driver.BindTexture)( ctx, target, newTexObj ); - - /* Decrement the reference count on the old texture and check if it's - * time to delete it. - */ - /* XXX all RefCount accesses should be protected by a mutex. */ - oldTexObj->RefCount--; - ASSERT(oldTexObj->RefCount >= 0); - if (oldTexObj->RefCount == 0) { - ASSERT(oldTexObj->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); - } } diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 2a2bde36017..d5374c5d6c4 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -58,6 +58,10 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ); extern void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex); + +extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 421f9128493..20f9c4512c4 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -62,31 +62,6 @@ static const struct gl_tex_env_combine_state default_combine_state = { }; -/** - * Copy a texture binding. Helper used by _mesa_copy_texture_state(). - */ -static void -copy_texture_binding(const GLcontext *ctx, - struct gl_texture_object **dst, - struct gl_texture_object *src) -{ - /* only copy if names differ (per OpenGL SI) */ - if ((*dst)->Name != src->Name) { - /* unbind/delete dest binding which we're changing */ - (*dst)->RefCount--; - if ((*dst)->RefCount == 0) { - /* time to delete this texture object */ - ASSERT((*dst)->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - /* XXX cast-away const, unfortunately */ - (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst); - } - /* make new binding, incrementing ref count */ - *dst = src; - src->RefCount++; - } -} - /** * Used by glXCopyContext to copy texture state from one context to another. @@ -143,20 +118,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) /* copy texture object bindings, not contents of texture objects */ _mesa_lock_context_textures(dst); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, - src->Texture.Unit[i].Current1D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, - src->Texture.Unit[i].Current2D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current3D, - src->Texture.Unit[i].Current3D); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap, - src->Texture.Unit[i].CurrentCubeMap); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, - src->Texture.Unit[i].CurrentRect); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray, - src->Texture.Unit[i].Current1DArray); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray, - src->Texture.Unit[i].Current2DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, + src->Texture.Unit[i].Current1D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, + src->Texture.Unit[i].Current2D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, + src->Texture.Unit[i].Current3D); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, + src->Texture.Unit[i].CurrentCubeMap); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, + src->Texture.Unit[i].CurrentRect); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray, + src->Texture.Unit[i].Current1DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray, + src->Texture.Unit[i].Current2DArray); _mesa_unlock_context_textures(dst); } @@ -699,52 +674,32 @@ _mesa_update_texture( GLcontext *ctx, GLuint new_state ) static GLboolean alloc_proxy_textures( GLcontext *ctx ) { - ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); - if (!ctx->Texture.Proxy1D) - goto cleanup; - - ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); - if (!ctx->Texture.Proxy2D) - goto cleanup; - - ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); - if (!ctx->Texture.Proxy3D) - goto cleanup; - - ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); - if (!ctx->Texture.ProxyCubeMap) - goto cleanup; - - ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); - if (!ctx->Texture.ProxyRect) - goto cleanup; - - ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT); - if (!ctx->Texture.Proxy1DArray) - goto cleanup; - - ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT); - if (!ctx->Texture.Proxy2DArray) - goto cleanup; + static const GLenum targets[] = { + GL_TEXTURE_1D, + GL_TEXTURE_2D, + GL_TEXTURE_3D, + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_RECTANGLE_NV, + GL_TEXTURE_1D_ARRAY_EXT, + GL_TEXTURE_2D_ARRAY_EXT + }; + GLint tgt; + + ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); + + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + if (!(ctx->Texture.ProxyTex[tgt] + = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { + /* out of memory, free what we did allocate */ + while (--tgt >= 0) { + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + } + return GL_FALSE; + } + } + assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */ return GL_TRUE; - - cleanup: - if (ctx->Texture.Proxy1D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D); - if (ctx->Texture.Proxy2D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D); - if (ctx->Texture.Proxy3D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D); - if (ctx->Texture.ProxyCubeMap) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap); - if (ctx->Texture.ProxyRect) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect); - if (ctx->Texture.Proxy1DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray); - if (ctx->Texture.Proxy2DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray); - return GL_FALSE; } @@ -786,13 +741,14 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); - texUnit->Current1D = ctx->Shared->Default1D; - texUnit->Current2D = ctx->Shared->Default2D; - texUnit->Current3D = ctx->Shared->Default3D; - texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; - texUnit->CurrentRect = ctx->Shared->DefaultRect; - texUnit->Current1DArray = ctx->Shared->Default1DArray; - texUnit->Current2DArray = ctx->Shared->Default2DArray; + /* initialize current texture object ptrs to the shared default objects */ + _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D); + _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D); + _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D); + _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); + _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect); + _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray); + _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray); } @@ -807,25 +763,22 @@ _mesa_init_texture(GLcontext *ctx) assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); - /* Effectively bind the default textures to all texture units */ - ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS; - /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ ctx->Texture._EnabledUnits = 0; - for (i=0; i<MAX_TEXTURE_UNITS; i++) - init_texture_unit( ctx, i ); ctx->Texture.SharedPalette = GL_FALSE; #if FEATURE_colortable _mesa_init_colortable(&ctx->Texture.Palette); #endif + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + init_texture_unit( ctx, i ); + + /* After we're done initializing the context's texture state the default + * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. + */ + assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1); + /* Allocate proxy textures */ if (!alloc_proxy_textures( ctx )) return GL_FALSE; @@ -840,14 +793,24 @@ _mesa_init_texture(GLcontext *ctx) void _mesa_free_texture_data(GLcontext *ctx) { + GLuint u, tgt; + + /* unreference current textures */ + for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + struct gl_texture_unit *unit = ctx->Texture.Unit + u; + _mesa_reference_texobj(&unit->Current1D, NULL); + _mesa_reference_texobj(&unit->Current2D, NULL); + _mesa_reference_texobj(&unit->Current3D, NULL); + _mesa_reference_texobj(&unit->CurrentCubeMap, NULL); + _mesa_reference_texobj(&unit->CurrentRect, NULL); + _mesa_reference_texobj(&unit->Current1DArray, NULL); + _mesa_reference_texobj(&unit->Current2DArray, NULL); + } + /* Free proxy texture objects */ - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray ); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + #if FEATURE_colortable { diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index a6bbdc64f16..ff583352cec 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1133,7 +1133,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, gl_state_index state_tokens[STATE_LENGTH]) { - switch (*(*inst)++) { + GLubyte token = *(*inst)++; + + switch (token) { case STATE_MATERIAL_PARSER: state_tokens[0] = STATE_MATERIAL; state_tokens[1] = parse_face_type (inst); @@ -1318,7 +1320,6 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case STATE_CLIP_PLANE: state_tokens[0] = STATE_CLIPPLANE; - state_tokens[1] = parse_integer (inst, Program); if (parse_clipplane_num (ctx, inst, Program, (GLint *) &state_tokens[1])) return 1; @@ -1770,7 +1771,9 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; GLfloat const_values[4]; - switch (*(*inst)++) { + GLubyte token = *(*inst)++; + + switch (token) { case PARAM_STATE_ELEMENT: if (parse_state_single_item (ctx, inst, Program, state_tokens)) return 1; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 3e28d92fe18..c1fbcde61e4 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -955,12 +955,15 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, } +#define MAX_UNIFORM_ELEMENTS 16 + /** - * Called via ctx->Driver.GetUniformfv(). + * Helper for GetUniformfv(), GetUniformiv() + * Returns number of elements written to 'params' output. */ -static void -_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, - GLfloat *params) +static GLuint +get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); @@ -984,9 +987,13 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, ASSERT(prog); if (prog) { + /* See uniformiv() below */ + assert(prog->Parameters->Parameters[progPos].Size <= MAX_UNIFORM_ELEMENTS); + for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) { params[i] = prog->Parameters->ParameterValues[progPos][i]; } + return prog->Parameters->Parameters[progPos].Size; } } else { @@ -996,6 +1003,35 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, else { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); } + return 0; +} + + +/** + * Called via ctx->Driver.GetUniformfv(). + */ +static void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) +{ + (void) get_uniformfv(ctx, program, location, params); +} + + +/** + * Called via ctx->Driver.GetUniformiv(). + */ +static void +_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location, + GLint *params) +{ + GLfloat fparams[MAX_UNIFORM_ELEMENTS]; + GLuint n = get_uniformfv(ctx, program, location, fparams); + GLuint i; + assert(n <= MAX_UNIFORM_ELEMENTS); + for (i = 0; i < n; i++) { + params[i] = (GLint) fparams[i]; + } } @@ -1011,6 +1047,11 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) if (!shProg) return -1; + if (shProg->LinkStatus == GL_FALSE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); + return -1; + } + /* XXX we should return -1 if the uniform was declared, but not * actually used. */ @@ -1408,6 +1449,7 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver) driver->GetShaderInfoLog = _mesa_get_shader_info_log; driver->GetShaderSource = _mesa_get_shader_source; driver->GetUniformfv = _mesa_get_uniformfv; + driver->GetUniformiv = _mesa_get_uniformiv; driver->GetUniformLocation = _mesa_get_uniform_location; driver->IsProgram = _mesa_is_program; driver->IsShader = _mesa_is_shader; diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 14fa38c3cda..af45dfb2e88 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -924,6 +924,30 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, } +/** + * Recursively traverse 'oper', replacing occurances of 'oldScope' with + * 'newScope' in the oper->locals->outer_scope filed. + * + * This is used after function inlining to update the scoping of + * the newly copied/inlined code so that vars are found in the new, + * inlined scope and not in the original function code. + */ +static void +slang_replace_scope(slang_operation *oper, + slang_variable_scope *oldScope, + slang_variable_scope *newScope) +{ + GLuint i; + if (oper->locals != newScope && + oper->locals->outer_scope == oldScope) { + oper->locals->outer_scope = newScope; + } + for (i = 0; i < oper->num_children; i++) { + slang_replace_scope(&oper->children[i], oldScope, newScope); + } +} + + /** * Produce inline code for a call to an assembly instruction. @@ -985,6 +1009,13 @@ slang_inline_asm_function(slang_assemble_ctx *A, _slang_free(substOld); _slang_free(substNew); +#if 0 + printf("+++++++++++++ inlined asm function %s +++++++++++++\n", + (char *) fun->header.a_name); + slang_print_tree(inlined, 3); + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); +#endif + return inlined; } @@ -1012,6 +1043,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation **substNew; GLuint substCount, numCopyIn, i; slang_function *prevFunction; + slang_variable_scope *newScope = NULL; /* save / push */ prevFunction = A->CurFunction; @@ -1029,7 +1061,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, _slang_alloc(totalArgs * sizeof(slang_operation *)); #if 0 - printf("Inline call to %s (total vars=%d nparams=%d)\n", + printf("\nInline call to %s (total vars=%d nparams=%d)\n", (char *) fun->header.a_name, fun->parameters->num_variables, numArgs); #endif @@ -1179,9 +1211,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation *decl = slang_operation_insert(&inlined->num_children, &inlined->children, numCopyIn); - /* - printf("COPY_IN %s from expr\n", (char*)p->a_name); - */ + decl->type = SLANG_OPER_VARIABLE_DECL; assert(decl->locals); decl->locals->outer_scope = inlined->locals; @@ -1192,6 +1222,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* child[0] is the var's initializer */ slang_operation_copy(&decl->children[0], args + i); + /* add parameter 'p' to the local variable scope here */ + { + slang_variable *pCopy = slang_variable_scope_grow(inlined->locals); + pCopy->type = p->type; + pCopy->a_name = p->a_name; + pCopy->array_len = p->array_len; + } + + newScope = inlined->locals; numCopyIn++; } } @@ -1231,8 +1270,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, _slang_free(substOld); _slang_free(substNew); + /* Update scoping to use the new local vars instead of the + * original function's vars. This is especially important + * for nested inlining. + */ + if (newScope) + slang_replace_scope(inlined, fun->parameters, newScope); + #if 0 - printf("Done Inline call to %s (total vars=%d nparams=%d)\n", + printf("Done Inline call to %s (total vars=%d nparams=%d)\n\n", (char *) fun->header.a_name, fun->parameters->num_variables, numArgs); slang_print_tree(top, 0); @@ -2063,7 +2109,11 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) n = new_node0(IR_VAR_DECL); if (n) { _slang_attach_storage(n, var); - +#if 0 + printf("%s var %p %s store=%p\n", + __FUNCTION__, (void *) var, (char *) var->a_name, + (void *) n->Store); +#endif assert(var->aux); assert(n->Store == var->aux); assert(n->Store); diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index e2117c03e67..ccb04494bf6 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1634,6 +1634,15 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, return 0; } + /* allocate global address space for a variable with a known size */ + if (C->global_scope + && !(var->type.specifier.type == SLANG_SPEC_ARRAY + && var->array_len == 0)) { + if (!calculate_var_size(C, O, var)) + return GL_FALSE; + var->address = slang_var_pool_alloc(O->global_pool, var->size); + } + /* emit code for global var decl */ if (C->global_scope) { slang_assemble_ctx A; @@ -1648,15 +1657,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, return 0; } - /* allocate global address space for a variable with a known size */ - if (C->global_scope - && !(var->type.specifier.type == SLANG_SPEC_ARRAY - && var->array_len == 0)) { - if (!calculate_var_size(C, O, var)) - return GL_FALSE; - var->address = slang_var_pool_alloc(O->global_pool, var->size); - } - /* initialize global variable */ if (C->global_scope) { if (var->initializer != NULL) { @@ -2167,6 +2167,9 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) type = SLANG_UNIT_FRAGMENT_SHADER; } + if (!shader->Source) + return GL_FALSE; + ctx->Shader.MemPool = _slang_new_mempool(1024*1024); /* XXX temporary hack */ diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index 31ad94183c2..16c36aad0c1 100644 --- a/src/mesa/shader/slang/slang_ir.c +++ b/src/mesa/shader/slang/slang_ir.c @@ -218,12 +218,14 @@ storage_string(const slang_ir_storage *st) "NAMED_PARAM", "CONSTANT", "UNIFORM", + "VARYING", "WRITE_ONLY", "ADDRESS", "SAMPLER", "UNDEFINED" }; static char s[100]; + assert(Elements(files) == PROGRAM_FILE_MAX); #if 0 if (st->Size == 1) sprintf(s, "%s[%d]", files[st->File], st->Index); diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c index 4a7d4bbbc74..ff9c62c929e 100644 --- a/src/mesa/shader/slang/slang_print.c +++ b/src/mesa/shader/slang/slang_print.c @@ -171,9 +171,15 @@ static void print_binary(const slang_operation *op, const char *oper, int indent) { assert(op->num_children == 2); + printf("binary at %p locals=%p outer=%p\n", + (void *) op, + (void *) op->locals, + (void *) op->locals->outer_scope); slang_print_tree(&op->children[0], indent + 3); spaces(indent); - printf("%s\n", oper); + printf("%s at %p locals=%p outer=%p\n", + oper, (void *) op, (void *) op->locals, + (void *) op->locals->outer_scope); slang_print_tree(&op->children[1], indent + 3); } @@ -185,11 +191,13 @@ print_generic2(const slang_operation *op, const char *oper, GLuint i; if (oper) { spaces(indent); - printf("[%p locals %p] %s %s\n", (void*) op, (void*) op->locals, oper, s); + printf("%s %s at %p locals=%p outer=%p\n", + oper, s, (void *) op, (void *) op->locals, + (void *) op->locals->outer_scope); } for (i = 0; i < op->num_children; i++) { spaces(indent); - printf("//child %u:\n", i); + printf("//child %u of %u:\n", i, op->num_children); slang_print_tree(&op->children[i], indent); } } @@ -244,7 +252,7 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_BLOCK_NO_NEW_SCOPE: spaces(indent); - printf("{ locals %p outer %p\n", (void*)op->locals, (void*)op->locals->outer_scope); + printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope); print_generic(op, NULL, indent+3); spaces(indent); printf("}\n"); @@ -252,7 +260,14 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_BLOCK_NEW_SCOPE: spaces(indent); - printf("{{ // new scope locals %p\n", (void*)op->locals); + printf("{{ // new scope locals=%p: ", (void*)op->locals); + { + int i; + for (i = 0; i < op->locals->num_variables; i++) { + printf("%s ", (char *) op->locals->variables[i]->a_name); + } + printf("\n"); + } print_generic(op, NULL, indent+3); spaces(indent); printf("}}\n"); @@ -264,14 +279,16 @@ slang_print_tree(const slang_operation *op, int indent) slang_variable *v; v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); if (v) { + const slang_variable_scope *scope; spaces(indent); printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope); print_type(&v->type); printf(" %s (%p)", (char *) op->a_id, (void *) find_var(op->locals, op->a_id)); - printf(" (in scope %p) ", - (void *) find_scope(op->locals, op->a_id)); + scope = find_scope(op->locals, op->a_id); + printf(" (in scope %p) ", (void *) scope); + assert(scope); if (op->num_children == 1) { printf(" :=\n"); slang_print_tree(&op->children[0], indent + 3); @@ -300,8 +317,12 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_ASM: spaces(indent); - printf("ASM: %s\n", (char*) op->a_id); - print_generic(op, NULL, indent+3); + printf("ASM: %s at %p locals=%p outer=%p\n", + (char *) op->a_id, + (void *) op, + (void *) op->locals, + (void *) op->locals->outer_scope); + print_generic(op, "ASM", indent+3); break; case SLANG_OPER_BREAK: @@ -333,7 +354,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_EXPRESSION: spaces(indent); - printf("EXPR: locals %p\n", (void*) op->locals); + printf("EXPR: locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/ slang_print_tree(&op->children[0], indent + 3); break; @@ -422,13 +445,25 @@ slang_print_tree(const slang_operation *op, int indent) break; case SLANG_OPER_IDENTIFIER: - spaces(indent); - if (op->var && op->var->a_name) - printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, - (void *) find_scope(op->locals, op->a_id)); - else - printf("VAR' %s (in scope %p)\n", (char *) op->a_id, - (void *) find_scope(op->locals, op->a_id)); + { + const slang_variable_scope *scope; + spaces(indent); + if (op->var && op->var->a_name) { + scope = find_scope(op->locals, op->var->a_name); + printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, + (void *) scope); + assert(scope); + } + else { + scope = find_scope(op->locals, op->a_id); + printf("VAR' %s (in scope %p) locals=%p outer=%p\n", + (char *) op->a_id, + (void *) scope, + (void *) op->locals, + (void *) op->locals->outer_scope); + assert(scope); + } + } break; case SLANG_OPER_SEQUENCE: @@ -437,7 +472,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_ASSIGN: spaces(indent); - printf("ASSIGNMENT locals %p\n", (void*)op->locals); + printf("ASSIGNMENT locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); print_binary(op, ":=", indent); break; @@ -573,7 +610,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_SUBSCRIPT: spaces(indent); - printf("SLANG_OPER_SUBSCRIPT\n"); + printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); print_generic(op, NULL, indent+3); break; @@ -640,7 +679,8 @@ slang_print_function(const slang_function *f, GLboolean body) print_variable(f->parameters->variables[i], 3); } - printf(")\n"); + printf(") param scope = %p\n", (void *) f->parameters); + if (body && f->body) slang_print_tree(f->body, 0); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 7245798d0da..8406bf247fc 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -422,7 +422,8 @@ st_finish_render_texture(GLcontext *ctx, struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer); - assert(strb); + if (!strb) + return; ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 21911774d79..a57d7b6a7aa 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -300,9 +300,8 @@ st_draw_vbo(GLcontext *ctx, vbuffer[attr].buffer = NULL; pipe_reference_buffer(pipe, &vbuffer[attr].buffer, stobj->buffer); - vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */ - velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr; - assert(velements[attr].src_offset <= 2048); /* 11-bit field */ + vbuffer[attr].buffer_offset = (unsigned) arrays[mesaAttr]->Ptr; + velements[attr].src_offset = 0; } else { /* attribute data is in user-space memory, not a VBO */ @@ -323,6 +322,8 @@ st_draw_vbo(GLcontext *ctx, velements[attr].src_offset = 0; } + assert(velements[attr].src_offset <= 2048); /* 11-bit field */ + /* common-case setup */ vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */ vbuffer[attr].max_index = max_index; @@ -335,6 +336,25 @@ st_draw_vbo(GLcontext *ctx, assert(velements[attr].src_format); } +#if 0 + { + GLuint i; + char buf[100]; + for (i = 0; i < vp->num_inputs; i++) { + printf("buffers[%d].pitch = %u\n", i, vbuffer[i].pitch); + printf("buffers[%d].max_index = %u\n", i, vbuffer[i].max_index); + printf("buffers[%d].buffer_offset = %u\n", i, vbuffer[i].buffer_offset); + printf("buffers[%d].buffer = %p\n", i, (void*) vbuffer[i].buffer); + } + for (i = 0; i < vp->num_inputs; i++) { + printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset); + printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index); + printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components); + printf("vlements[%d].format = %s\n", i, pf_sprint_name(buf, velements[i].src_format)); + } + } +#endif + pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer); pipe->set_vertex_elements(pipe, vp->num_inputs, velements); diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 03ec558a367..50a06868dfc 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -362,7 +362,10 @@ st_choose_format(struct pipe_context *pipe, GLint internalFormat, case GL_RGBA12: return default_rgba_format( screen, surfType ); case GL_RGBA16: - return default_deep_rgba_format( screen, surfType ); + if (surfType == PIPE_SURFACE) + return default_deep_rgba_format( screen, surfType ); + else + return default_rgba_format( screen, surfType ); case GL_RGBA4: case GL_RGBA2: diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 59cd7f6984d..5362226c2f9 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -120,19 +120,19 @@ void vbo_use_buffer_objects(GLcontext *ctx); void vbo_set_draw_func(GLcontext *ctx, vbo_draw_func func); -void +void GLAPIENTRY _vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a); -void +void GLAPIENTRY _vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z); -void +void GLAPIENTRY _vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -void +void GLAPIENTRY _vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params); -void +void GLAPIENTRY _vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); #endif diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 2c2e66dd0b7..579bbeb4f31 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -770,34 +770,34 @@ static void reset_attrfv( struct vbo_exec_context *exec ) } -void +void GLAPIENTRY _vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { vbo_Color4f(r, g, b, a); } -void +void GLAPIENTRY _vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z) { vbo_Normal3f(x, y, z); } -void +void GLAPIENTRY _vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { vbo_MultiTexCoord4f(target, s, t, r, q); } -void +void GLAPIENTRY _vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params) { vbo_Materialfv(face, pname, params); } -void +void GLAPIENTRY _vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { vbo_VertexAttrib4fARB(index, x, y, z, w); |