Compare commits
	
		
			63 Commits
		
	
	
		
			embedded-1
			...
			embedded-1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f221b8df75 | ||
|  | 45bd335b1c | ||
|  | 6127672e26 | ||
|  | bb3752a434 | ||
|  | 56c896a2b8 | ||
|  | afc72872be | ||
|  | e511f40795 | ||
|  | a53f53ece3 | ||
|  | 24812b3eaa | ||
|  | 42e0f2ec95 | ||
|  | e4fcab7a35 | ||
|  | cd6d79a82c | ||
|  | a428744286 | ||
|  | ccc6ef28ca | ||
|  | 3100749dd0 | ||
|  | 980e98d324 | ||
|  | 2204d5bb46 | ||
|  | 67d3c57c46 | ||
|  | 9e24ff7a0a | ||
|  | e014d794f2 | ||
|  | a9bd5a6860 | ||
|  | 94643c4780 | ||
|  | 993502aebc | ||
|  | 932e26e8f4 | ||
|  | 54f4c8d1a3 | ||
|  | 277d7a2a85 | ||
|  | 0a98671051 | ||
|  | a47745e9fd | ||
|  | 69ce6b7db0 | ||
|  | 5d3ab07110 | ||
|  | 1613d48989 | ||
|  | 5a610a1974 | ||
|  | afb339bf75 | ||
|  | 16ca6f8e93 | ||
|  | 41b5963f8d | ||
|  | 99199c0ece | ||
|  | 368d95a7dc | ||
|  | 0218da1433 | ||
|  | 6cb2411250 | ||
|  | 0d3a504b94 | ||
|  | bde16645ca | ||
|  | 301f7e4408 | ||
|  | 173441d1a6 | ||
|  | 64b3e2fa16 | ||
|  | 6919c50029 | ||
|  | a8512f7dda | ||
|  | 70217c70be | ||
|  | 9d4857a816 | ||
|  | 3f00e34097 | ||
|  | 3e48e6fce4 | ||
|  | d1fa9af224 | ||
|  | c20d946424 | ||
|  | ff6068b217 | ||
|  | ed1b6e98e2 | ||
|  | b52901eb89 | ||
|  | cff70d16aa | ||
|  | bafbdcb703 | ||
|  | 50d1c2c921 | ||
|  | a1fd12ab84 | ||
|  | 360bec8a6f | ||
|  | 6440630d79 | ||
|  | 02a6f4b56a | ||
|  | f828410458 | 
| @@ -1,7 +1,9 @@ | ||||
| *.tag | ||||
| array_cache | ||||
| core | ||||
| core_subset | ||||
| math | ||||
| math_subset | ||||
| miniglx | ||||
| radeon_subset | ||||
| swrast | ||||
|   | ||||
| @@ -6,4 +6,5 @@ See http://www.doxygen.org/ for more info. | ||||
| Either run 'make' (Unix) or 'doxy.bat' (Windows) to run doxygen | ||||
| and generate souce code documentation. | ||||
|  | ||||
| Then, load doxy/core/index.html into your web browser. | ||||
| Then, load either doxy/core/index.html or doxy/core_subset/index.html into | ||||
| your web browser. | ||||
|   | ||||
| @@ -55,7 +55,7 @@ INPUT                  = ../src/ | ||||
| FILE_PATTERNS          = *.c *.h | ||||
| RECURSIVE              = NO | ||||
| EXCLUDE                = ../src/glapitemp.h ../src/glapioffsets.h | ||||
| EXCLUDE_PATTERNS       =  | ||||
| EXCLUDE_PATTERNS       = subset_* | ||||
| EXAMPLE_PATH           =  | ||||
| EXAMPLE_PATTERNS       =  | ||||
| EXAMPLE_RECURSIVE      = NO | ||||
| @@ -132,13 +132,13 @@ GENERATE_AUTOGEN_DEF   = NO | ||||
| # Configuration options related to the preprocessor    | ||||
| #--------------------------------------------------------------------------- | ||||
| ENABLE_PREPROCESSING   = YES | ||||
| MACRO_EXPANSION        = NO | ||||
| EXPAND_ONLY_PREDEF     = NO | ||||
| MACRO_EXPANSION        = YES | ||||
| EXPAND_ONLY_PREDEF     = YES | ||||
| SEARCH_INCLUDES        = YES | ||||
| INCLUDE_PATH           = ../include/ | ||||
| INCLUDE_FILE_PATTERNS  =  | ||||
| PREDEFINED             =  | ||||
| EXPAND_AS_DEFINED      =  | ||||
| PREDEFINED             = _HAVE_FULL_GL=1 | ||||
| EXPAND_AS_DEFINED      = _glthread_DECLARE_STATIC_MUTEX | ||||
| SKIP_FUNCTION_MACROS   = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to external references    | ||||
| @@ -148,8 +148,7 @@ TAGFILES		= tnl_dd.tag=../tnl_dd \ | ||||
|                          math.tag=../math \ | ||||
|                          swrast.tag=../swrast \ | ||||
|                          swrast_setup.tag=../swrast_setup \ | ||||
|                          tnl.tag=../tnl \ | ||||
| 			 miniglx.tag=../miniglx | ||||
|                          tnl.tag=../tnl | ||||
| GENERATE_TAGFILE       = core.tag | ||||
| ALLEXTERNALS           = NO | ||||
| PERL_PATH              =  | ||||
|   | ||||
							
								
								
									
										226
									
								
								doxygen/core_subset.doxy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								doxygen/core_subset.doxy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,226 @@ | ||||
| # Doxyfile 0.1 | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
| # General configuration options | ||||
| #--------------------------------------------------------------------------- | ||||
| PROJECT_NAME           = "Mesa Core" | ||||
| PROJECT_NUMBER         =  | ||||
| OUTPUT_DIRECTORY       =  | ||||
| OUTPUT_LANGUAGE        = English | ||||
| EXTRACT_ALL            = NO | ||||
| EXTRACT_PRIVATE        = NO | ||||
| EXTRACT_STATIC         = YES | ||||
| EXTRACT_LOCAL_CLASSES  = YES | ||||
| HIDE_UNDOC_MEMBERS     = NO | ||||
| HIDE_UNDOC_CLASSES     = NO | ||||
| BRIEF_MEMBER_DESC      = YES | ||||
| REPEAT_BRIEF           = YES | ||||
| ALWAYS_DETAILED_SEC    = NO | ||||
| INLINE_INHERITED_MEMB  = NO | ||||
| FULL_PATH_NAMES        = NO | ||||
| STRIP_FROM_PATH        =  | ||||
| INTERNAL_DOCS          = YES | ||||
| STRIP_CODE_COMMENTS    = YES | ||||
| CASE_SENSE_NAMES       = YES | ||||
| SHORT_NAMES            = NO | ||||
| HIDE_SCOPE_NAMES       = NO | ||||
| VERBATIM_HEADERS       = YES | ||||
| SHOW_INCLUDE_FILES     = YES | ||||
| JAVADOC_AUTOBRIEF      = NO | ||||
| INHERIT_DOCS           = YES | ||||
| INLINE_INFO            = YES | ||||
| SORT_MEMBER_DOCS       = NO | ||||
| DISTRIBUTE_GROUP_DOC   = NO | ||||
| TAB_SIZE               = 8 | ||||
| GENERATE_TODOLIST      = YES | ||||
| GENERATE_TESTLIST      = YES | ||||
| GENERATE_BUGLIST       = YES | ||||
| ALIASES                =  | ||||
| ENABLED_SECTIONS       = subset | ||||
| MAX_INITIALIZER_LINES  = 30 | ||||
| OPTIMIZE_OUTPUT_FOR_C  = NO | ||||
| SHOW_USED_FILES        = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to warning and progress messages | ||||
| #--------------------------------------------------------------------------- | ||||
| QUIET                  = YES | ||||
| WARNINGS               = YES | ||||
| WARN_IF_UNDOCUMENTED   = NO | ||||
| WARN_FORMAT            =  | ||||
| WARN_LOGFILE           =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the input files | ||||
| #--------------------------------------------------------------------------- | ||||
| INPUT                  = ../src/ | ||||
| FILE_PATTERNS          = \ | ||||
| 			accum.h \ | ||||
| 			attrib.h \ | ||||
| 			blend.[ch] \ | ||||
| 			buffers.[ch] \ | ||||
| 			dd.h \ | ||||
| 			debug.h \ | ||||
| 			depth.h \ | ||||
| 			dlist.h \ | ||||
| 			context.[ch] \ | ||||
| 			config.h \ | ||||
| 			colormac.h \ | ||||
| 			colortab.h \ | ||||
| 			enable.h \ | ||||
| 			enums.h \ | ||||
| 			eval.h \ | ||||
| 			extensions.h \ | ||||
| 			feedback.[ch] \ | ||||
| 			fog.h \ | ||||
| 			get.h \ | ||||
| 			glheader.h \ | ||||
| 			glthread.h \ | ||||
| 			hash.[ch] \ | ||||
| 			hint.h \ | ||||
| 			histogram.h \ | ||||
| 			image.[ch] \ | ||||
| 			imports.[ch] \ | ||||
| 			lines.[ch] \ | ||||
| 			light.h \ | ||||
| 			matrix.[ch] \ | ||||
| 			macros.h \ | ||||
| 			mmath.h \ | ||||
| 			mtypes.h \ | ||||
| 			pixel.h \ | ||||
| 			points.[ch] \ | ||||
| 			polygon.[ch] \ | ||||
| 			rastpos.[ch] \ | ||||
| 			simple_list.h \ | ||||
| 			state.[ch] \ | ||||
| 			stencil.[ch] \ | ||||
| 			subset_*.c \ | ||||
| 			texformat.h \ | ||||
| 			teximage.h \ | ||||
| 			texstate.h \ | ||||
| 			texstore.h \ | ||||
| 			texobj.[ch] \ | ||||
| 			texutil_tmp.h \ | ||||
| 			varray.h | ||||
| RECURSIVE              = NO | ||||
| EXCLUDE                =  | ||||
| EXCLUDE_PATTERNS       =  | ||||
| EXAMPLE_PATH           =  | ||||
| EXAMPLE_PATTERNS       =  | ||||
| EXAMPLE_RECURSIVE      = NO | ||||
| IMAGE_PATH             =  | ||||
| INPUT_FILTER           =  | ||||
| FILTER_SOURCE_FILES    = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to source browsing | ||||
| #--------------------------------------------------------------------------- | ||||
| SOURCE_BROWSER         = YES | ||||
| INLINE_SOURCES         = NO | ||||
| REFERENCED_BY_RELATION = YES | ||||
| REFERENCES_RELATION    = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the alphabetical class index | ||||
| #--------------------------------------------------------------------------- | ||||
| ALPHABETICAL_INDEX     = NO | ||||
| COLS_IN_ALPHA_INDEX    = 5 | ||||
| IGNORE_PREFIX          =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the HTML output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_HTML          = YES | ||||
| HTML_OUTPUT            = core_subset | ||||
| HTML_HEADER            = header_subset.html | ||||
| HTML_FOOTER            =  | ||||
| HTML_STYLESHEET        =  | ||||
| HTML_ALIGN_MEMBERS     = YES | ||||
| GENERATE_HTMLHELP      = NO | ||||
| GENERATE_CHI           = NO | ||||
| BINARY_TOC             = NO | ||||
| TOC_EXPAND             = NO | ||||
| DISABLE_INDEX          = NO | ||||
| ENUM_VALUES_PER_LINE   = 4 | ||||
| GENERATE_TREEVIEW      = NO | ||||
| TREEVIEW_WIDTH         = 250 | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the LaTeX output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_LATEX         = NO | ||||
| LATEX_OUTPUT           =  | ||||
| COMPACT_LATEX          = NO | ||||
| PAPER_TYPE             = a4wide | ||||
| EXTRA_PACKAGES         =  | ||||
| LATEX_HEADER           =  | ||||
| PDF_HYPERLINKS         = NO | ||||
| USE_PDFLATEX           = NO | ||||
| LATEX_BATCHMODE        = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the RTF output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_RTF           = NO | ||||
| RTF_OUTPUT             =  | ||||
| COMPACT_RTF            = NO | ||||
| RTF_HYPERLINKS         = NO | ||||
| RTF_STYLESHEET_FILE    =  | ||||
| RTF_EXTENSIONS_FILE    =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the man page output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_MAN           = NO | ||||
| MAN_OUTPUT             =  | ||||
| MAN_EXTENSION          =  | ||||
| MAN_LINKS              = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the XML output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_XML           = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options for the AutoGen Definitions output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_AUTOGEN_DEF   = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration options related to the preprocessor    | ||||
| #--------------------------------------------------------------------------- | ||||
| ENABLE_PREPROCESSING   = YES | ||||
| MACRO_EXPANSION        = NO | ||||
| EXPAND_ONLY_PREDEF     = NO | ||||
| SEARCH_INCLUDES        = YES | ||||
| INCLUDE_PATH           = ../include/ | ||||
| INCLUDE_FILE_PATTERNS  =  | ||||
| PREDEFINED             =  | ||||
| EXPAND_AS_DEFINED      =  | ||||
| SKIP_FUNCTION_MACROS   = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to external references    | ||||
| #--------------------------------------------------------------------------- | ||||
| TAGFILES		= \ | ||||
| 			 math_subset.tag=../math_subset \ | ||||
| 			 miniglx.tag=../miniglx | ||||
| GENERATE_TAGFILE       = core_subset.tag | ||||
| ALLEXTERNALS           = NO | ||||
| PERL_PATH              =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration options related to the dot tool    | ||||
| #--------------------------------------------------------------------------- | ||||
| CLASS_DIAGRAMS         = NO | ||||
| HAVE_DOT               = NO | ||||
| CLASS_GRAPH            = YES | ||||
| COLLABORATION_GRAPH    = YES | ||||
| TEMPLATE_RELATIONS     = YES | ||||
| HIDE_UNDOC_RELATIONS   = YES | ||||
| INCLUDE_GRAPH          = YES | ||||
| INCLUDED_BY_GRAPH      = YES | ||||
| GRAPHICAL_HIERARCHY    = YES | ||||
| DOT_PATH               =  | ||||
| DOTFILE_DIRS           =  | ||||
| MAX_DOT_GRAPH_WIDTH    = 1024 | ||||
| MAX_DOT_GRAPH_HEIGHT   = 1024 | ||||
| GENERATE_LEGEND        = YES | ||||
| DOT_CLEANUP            = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to the search engine    | ||||
| #--------------------------------------------------------------------------- | ||||
| SEARCHENGINE           = NO | ||||
| CGI_NAME               =  | ||||
| CGI_URL                =  | ||||
| DOC_URL                =  | ||||
| DOC_ABSPATH            =  | ||||
| BIN_ABSPATH            =  | ||||
| EXT_DOC_PATHS          =  | ||||
| @@ -3,12 +3,10 @@ | ||||
| </head> | ||||
| <body><center> | ||||
| <a href="../core/index.html">Mesa Core</a>  | ||||
| <a href="../miniglx/index.html">MiniGLX</a>  | ||||
| <a href="../array_cache/index.html">array_cache</a>  | ||||
| <a href="../math/index.html">math</a>  | ||||
| <a href="../swrast/index.html">swrast</a>  | ||||
| <a href="../swrast_setup/index.html">swrast_setup</a>  | ||||
| <a href="../tnl/index.html">tnl</a>  | ||||
| <a href="../tnl_dd/index.html">tnl_dd</a>  | ||||
| <a href="../radeon_subset/index.html">radeon_subset</a>  | ||||
| </center> | ||||
| </center> | ||||
|   | ||||
							
								
								
									
										9
									
								
								doxygen/header_subset.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								doxygen/header_subset.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <html><head><title>Mesa Source Code Documentation</title> | ||||
| <link href="doxygen.css" rel="stylesheet" type="text/css"> | ||||
| </head> | ||||
| <body><center> | ||||
| <a href="../core_subset/index.html">Mesa Core</a>  | ||||
| <a href="../math_subset/index.html">math</a>  | ||||
| <a href="../miniglx/index.html">MiniGLX</a>  | ||||
| <a href="../radeon_subset/index.html">radeon_subset</a>  | ||||
| </center> | ||||
| @@ -1,11 +1,12 @@ | ||||
| default: | ||||
| default: subset | ||||
|  | ||||
| full: | ||||
| 	doxygen tnl_dd.doxy | ||||
| 	doxygen array_cache.doxy | ||||
| 	doxygen math.doxy | ||||
| 	doxygen swrast.doxy | ||||
| 	doxygen swrast_setup.doxy | ||||
| 	doxygen tnl.doxy | ||||
| 	doxygen miniglx.doxy | ||||
| 	doxygen core.doxy | ||||
| 	echo "Building again, to resolve tags" | ||||
| 	doxygen tnl_dd.doxy | ||||
| @@ -14,11 +15,30 @@ default: | ||||
| 	doxygen swrast.doxy | ||||
| 	doxygen swrast_setup.doxy | ||||
| 	doxygen tnl.doxy | ||||
| 	doxygen core.doxy | ||||
|  | ||||
| subset: | ||||
| 	doxygen core_subset.doxy | ||||
| 	doxygen math_subset.doxy | ||||
| 	doxygen miniglx.doxy | ||||
| 	echo "Building again, to resolve tags" | ||||
| 	doxygen core_subset.doxy | ||||
| 	doxygen math_subset.doxy | ||||
| 	doxygen miniglx.doxy | ||||
| 	doxygen radeon_subset.doxy | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx radeon_subset | ||||
| 	rm -rf \ | ||||
| 		array_cache \ | ||||
| 		core \ | ||||
| 		core_subset \ | ||||
| 		math \ | ||||
| 		math_subset \ | ||||
| 		swrast \ | ||||
| 		swrast_setup \ | ||||
| 		tnl_dd \ | ||||
| 		tnl \ | ||||
| 		miniglx \ | ||||
| 		radeon_subset | ||||
| 	rm -rf *.tag | ||||
|  | ||||
|   | ||||
							
								
								
									
										177
									
								
								doxygen/math_subset.doxy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								doxygen/math_subset.doxy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| # Doxyfile 0.1 | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
| # General configuration options | ||||
| #--------------------------------------------------------------------------- | ||||
| PROJECT_NAME           = "Mesa math module" | ||||
| PROJECT_NUMBER         =  | ||||
| OUTPUT_DIRECTORY       = . | ||||
| OUTPUT_LANGUAGE        = English | ||||
| EXTRACT_ALL            = NO | ||||
| EXTRACT_PRIVATE        = NO | ||||
| EXTRACT_STATIC         = YES | ||||
| EXTRACT_LOCAL_CLASSES  = YES | ||||
| HIDE_UNDOC_MEMBERS     = NO | ||||
| HIDE_UNDOC_CLASSES     = NO | ||||
| BRIEF_MEMBER_DESC      = YES | ||||
| REPEAT_BRIEF           = YES | ||||
| ALWAYS_DETAILED_SEC    = NO | ||||
| INLINE_INHERITED_MEMB  = NO | ||||
| FULL_PATH_NAMES        = NO | ||||
| STRIP_FROM_PATH        =  | ||||
| INTERNAL_DOCS          = NO | ||||
| STRIP_CODE_COMMENTS    = YES | ||||
| CASE_SENSE_NAMES       = YES | ||||
| SHORT_NAMES            = NO | ||||
| HIDE_SCOPE_NAMES       = NO | ||||
| VERBATIM_HEADERS       = YES | ||||
| SHOW_INCLUDE_FILES     = YES | ||||
| JAVADOC_AUTOBRIEF      = NO | ||||
| INHERIT_DOCS           = YES | ||||
| INLINE_INFO            = YES | ||||
| SORT_MEMBER_DOCS       = NO | ||||
| DISTRIBUTE_GROUP_DOC   = NO | ||||
| TAB_SIZE               = 8 | ||||
| GENERATE_TODOLIST      = YES | ||||
| GENERATE_TESTLIST      = YES | ||||
| GENERATE_BUGLIST       = YES | ||||
| ALIASES                =  | ||||
| ENABLED_SECTIONS       =  | ||||
| MAX_INITIALIZER_LINES  = 30 | ||||
| OPTIMIZE_OUTPUT_FOR_C  = YES | ||||
| SHOW_USED_FILES        = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to warning and progress messages | ||||
| #--------------------------------------------------------------------------- | ||||
| QUIET                  = YES | ||||
| WARNINGS               = YES | ||||
| WARN_IF_UNDOCUMENTED   = YES | ||||
| WARN_FORMAT            =  | ||||
| WARN_LOGFILE           =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the input files | ||||
| #--------------------------------------------------------------------------- | ||||
| INPUT                  = ../src/math/ | ||||
| FILE_PATTERNS          = m_matrix.[ch] | ||||
| RECURSIVE              = NO | ||||
| EXCLUDE                =  | ||||
| EXCLUDE_PATTERNS       =  | ||||
| EXAMPLE_PATH           =  | ||||
| EXAMPLE_PATTERNS       =  | ||||
| EXAMPLE_RECURSIVE      = NO | ||||
| IMAGE_PATH             =  | ||||
| INPUT_FILTER           =  | ||||
| FILTER_SOURCE_FILES    = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to source browsing | ||||
| #--------------------------------------------------------------------------- | ||||
| SOURCE_BROWSER         = NO | ||||
| INLINE_SOURCES         = NO | ||||
| REFERENCED_BY_RELATION = YES | ||||
| REFERENCES_RELATION    = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the alphabetical class index | ||||
| #--------------------------------------------------------------------------- | ||||
| ALPHABETICAL_INDEX     = NO | ||||
| COLS_IN_ALPHA_INDEX    = 5 | ||||
| IGNORE_PREFIX          =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the HTML output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_HTML          = YES | ||||
| HTML_OUTPUT            = math_subset | ||||
| HTML_HEADER            = header_subset.html | ||||
| HTML_FOOTER            =  | ||||
| HTML_STYLESHEET        =  | ||||
| HTML_ALIGN_MEMBERS     = YES | ||||
| GENERATE_HTMLHELP      = NO | ||||
| GENERATE_CHI           = NO | ||||
| BINARY_TOC             = NO | ||||
| TOC_EXPAND             = NO | ||||
| DISABLE_INDEX          = NO | ||||
| ENUM_VALUES_PER_LINE   = 4 | ||||
| GENERATE_TREEVIEW      = NO | ||||
| TREEVIEW_WIDTH         = 250 | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the LaTeX output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_LATEX         = NO | ||||
| LATEX_OUTPUT           =  | ||||
| COMPACT_LATEX          = NO | ||||
| PAPER_TYPE             = a4wide | ||||
| EXTRA_PACKAGES         =  | ||||
| LATEX_HEADER           =  | ||||
| PDF_HYPERLINKS         = NO | ||||
| USE_PDFLATEX           = NO | ||||
| LATEX_BATCHMODE        = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the RTF output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_RTF           = NO | ||||
| RTF_OUTPUT             =  | ||||
| COMPACT_RTF            = NO | ||||
| RTF_HYPERLINKS         = NO | ||||
| RTF_STYLESHEET_FILE    =  | ||||
| RTF_EXTENSIONS_FILE    =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the man page output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_MAN           = NO | ||||
| MAN_OUTPUT             =  | ||||
| MAN_EXTENSION          =  | ||||
| MAN_LINKS              = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options related to the XML output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_XML           = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # configuration options for the AutoGen Definitions output | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_AUTOGEN_DEF   = NO | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration options related to the preprocessor    | ||||
| #--------------------------------------------------------------------------- | ||||
| ENABLE_PREPROCESSING   = YES | ||||
| MACRO_EXPANSION        = NO | ||||
| EXPAND_ONLY_PREDEF     = NO | ||||
| SEARCH_INCLUDES        = YES | ||||
| INCLUDE_PATH           =  | ||||
| INCLUDE_FILE_PATTERNS  =  | ||||
| PREDEFINED             =  | ||||
| EXPAND_AS_DEFINED      =  | ||||
| SKIP_FUNCTION_MACROS   = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to external references    | ||||
| #--------------------------------------------------------------------------- | ||||
| TAGFILES               = core_subset.tag=../core_subset | ||||
| GENERATE_TAGFILE       = math_subset.tag | ||||
| ALLEXTERNALS           = NO | ||||
| PERL_PATH              =  | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration options related to the dot tool    | ||||
| #--------------------------------------------------------------------------- | ||||
| CLASS_DIAGRAMS         = YES | ||||
| HAVE_DOT               = NO | ||||
| CLASS_GRAPH            = YES | ||||
| COLLABORATION_GRAPH    = YES | ||||
| TEMPLATE_RELATIONS     = YES | ||||
| HIDE_UNDOC_RELATIONS   = YES | ||||
| INCLUDE_GRAPH          = YES | ||||
| INCLUDED_BY_GRAPH      = YES | ||||
| GRAPHICAL_HIERARCHY    = YES | ||||
| DOT_PATH               =  | ||||
| DOTFILE_DIRS           =  | ||||
| MAX_DOT_GRAPH_WIDTH    = 1024 | ||||
| MAX_DOT_GRAPH_HEIGHT   = 1024 | ||||
| GENERATE_LEGEND        = YES | ||||
| DOT_CLEANUP            = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to the search engine    | ||||
| #--------------------------------------------------------------------------- | ||||
| SEARCHENGINE           = NO | ||||
| CGI_NAME               =  | ||||
| CGI_URL                =  | ||||
| DOC_URL                =  | ||||
| DOC_ABSPATH            =  | ||||
| BIN_ABSPATH            =  | ||||
| EXT_DOC_PATHS          =  | ||||
| @@ -80,7 +80,7 @@ IGNORE_PREFIX          = | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_HTML          = YES | ||||
| HTML_OUTPUT            = miniglx | ||||
| HTML_HEADER            = header.html | ||||
| HTML_HEADER            = header_subset.html | ||||
| HTML_FOOTER            =  | ||||
| HTML_STYLESHEET        =  | ||||
| HTML_ALIGN_MEMBERS     = YES | ||||
| @@ -143,14 +143,9 @@ SKIP_FUNCTION_MACROS   = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to external references    | ||||
| #--------------------------------------------------------------------------- | ||||
| TAGFILES		= core.tag=../core \ | ||||
| 			 tnl_dd.tag=../tnl_dd \ | ||||
| 			 array_cache.tag=../array_cache \ | ||||
|                          math.tag=../math \ | ||||
|                          swrast.tag=../swrast \ | ||||
|                          swrast_setup.tag=../swrast_setup \ | ||||
|                          tnl.tag=../tnl \ | ||||
|                          array_cache.tag=array_cache | ||||
| TAGFILES		= \ | ||||
| 			 core_subset.tag=../core_subset \ | ||||
|                          math_subset.tag=../math_subset | ||||
| GENERATE_TAGFILE       = miniglx.tag | ||||
| ALLEXTERNALS           = NO | ||||
| PERL_PATH              =  | ||||
|   | ||||
| @@ -103,7 +103,7 @@ IGNORE_PREFIX          = | ||||
| #--------------------------------------------------------------------------- | ||||
| GENERATE_HTML          = YES | ||||
| HTML_OUTPUT            = radeon_subset | ||||
| HTML_HEADER            = header.html | ||||
| HTML_HEADER            = header_subset.html | ||||
| HTML_FOOTER            =  | ||||
| HTML_STYLESHEET        =  | ||||
| HTML_ALIGN_MEMBERS     = YES | ||||
| @@ -166,15 +166,10 @@ SKIP_FUNCTION_MACROS   = YES | ||||
| #--------------------------------------------------------------------------- | ||||
| # Configuration::addtions related to external references    | ||||
| #--------------------------------------------------------------------------- | ||||
| TAGFILES		= core.tag=../core \ | ||||
| 			 tnl_dd.tag=../tnl_dd \ | ||||
| 			 array_cache.tag=../array_cache \ | ||||
|                          math.tag=../math \ | ||||
|                          swrast.tag=../swrast \ | ||||
|                          swrast_setup.tag=../swrast_setup \ | ||||
|                          tnl.tag=../tnl \ | ||||
|                          miniglx.tag=../miniglx \ | ||||
|                          array_cache.tag=array_cache | ||||
| TAGFILES		= \ | ||||
| 			 core_subset.tag=../core_subset \ | ||||
|                          math_subset.tag=../math_subset \ | ||||
|                          miniglx.tag=../miniglx | ||||
| GENERATE_TAGFILE       = radeon_subset.tag | ||||
| ALLEXTERNALS           = NO | ||||
| PERL_PATH              =  | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| /* $Id: gl.h,v 1.72 2002/10/17 19:39:31 kschultz Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  4.1 | ||||
|  * Version:  5.0.1 | ||||
|  * | ||||
|  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved. | ||||
|  * Copyright (C) 1999-2003  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"), | ||||
| @@ -2646,6 +2645,13 @@ GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid | ||||
| #endif /* GL_APPLE_ycbcr_422 */ | ||||
|  | ||||
|  | ||||
| #ifndef GL_ATI_texture_env_combine3 | ||||
| #define GL_ATI_texture_env_combine3 1 | ||||
| #define GL_MODULATE_ADD_ATI               0x8744 | ||||
| #define GL_MODULATE_SIGNED_ADD_ATI        0x8745 | ||||
| #define GL_MODULATE_SUBTRACT_ATI          0x8746 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /********************************************************************** | ||||
|  * Begin system-specific stuff | ||||
|   | ||||
| @@ -2423,6 +2423,11 @@ extern "C" { | ||||
| #define GL_ACTIVE_STENCIL_FACE_EXT        0x8911 | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_ATI_texture_env_combine3 | ||||
| #define GL_MODULATE_ADD_ATI               0x8744 | ||||
| #define GL_MODULATE_SIGNED_ADD_ATI        0x8745 | ||||
| #define GL_MODULATE_SUBTRACT_ATI          0x8746 | ||||
| #endif | ||||
|  | ||||
| /*************************************************************/ | ||||
|  | ||||
| @@ -5016,6 +5021,9 @@ GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); | ||||
| typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); | ||||
| #endif | ||||
|  | ||||
| #ifndef GL_ATI_texture_env_combine3 | ||||
| #define GL_ATI_texture_env_combine3 1 | ||||
| #endif | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|   | ||||
| @@ -14,12 +14,12 @@ PROGS = gears \ | ||||
|  | ||||
| # make executable from .c file: | ||||
| .c: $(LIB_DEP) | ||||
| 	gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lm -o $@ | ||||
| 	gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lGLU -lm -o $@ | ||||
|  | ||||
|  | ||||
| default: $(PROGS) | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	-rm *.o *~ | ||||
| 	-rm -f *.o *~ $(PROGS) | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: bounce.c,v 1.3.8.1 2003/02/23 19:25:07 keithw Exp $ */ | ||||
| /* $Id: bounce.c,v 1.3.8.2 2003/03/22 08:40:35 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Bouncing ball demo. | ||||
| @@ -115,15 +115,15 @@ draw(void) | ||||
|   glColor3f(0, 1, 1); | ||||
|   glBegin(GL_LINES); | ||||
|   for (i = -5; i <= 5; i++) { | ||||
|     glVertex2i(i, -5); | ||||
|     glVertex2i(i, 5); | ||||
|     glVertex2f(i, -5); | ||||
|     glVertex2f(i, 5); | ||||
|   } | ||||
|   for (i = -5; i <= 5; i++) { | ||||
|     glVertex2i(-5, i); | ||||
|     glVertex2i(5, i); | ||||
|     glVertex2f(-5, i); | ||||
|     glVertex2f(5, i); | ||||
|   } | ||||
|   for (i = -5; i <= 5; i++) { | ||||
|     glVertex2i(i, -5); | ||||
|     glVertex2f(i, -5); | ||||
|     glVertex2f(i * 1.15, -5.9); | ||||
|   } | ||||
|   glVertex2f(-5.3, -5.35); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: isosurf.c,v 1.15.4.1 2003/02/23 21:04:25 keithw Exp $ */ | ||||
| /* $Id: isosurf.c,v 1.15.4.2 2003/03/22 08:40:35 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Display an isosurface of 3-D wind speed volume. | ||||
| @@ -37,7 +37,7 @@ | ||||
| #define GL_GLEXT_LEGACY | ||||
| #include "GL/glut.h" | ||||
|  | ||||
| #include "readtex.c"   /* I know, this is a hack.  KW: me too. */ | ||||
| #include "readtex.c"    | ||||
| #define TEXTURE_FILE "../images/reflect.rgb" | ||||
|  | ||||
| #define LIT		0x00000001 | ||||
| @@ -805,10 +805,10 @@ static void Init(int argc, char *argv[]) | ||||
| 	 expand_arrays(); | ||||
| 	 make_tri_indices(); | ||||
|  | ||||
| 	 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { | ||||
| 	    printf("Error: couldn't load texture image\n"); | ||||
| 	    exit(1); | ||||
| 	 } | ||||
| /* 	 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { */ | ||||
| /* 	    printf("Error: couldn't load texture image\n"); */ | ||||
| /* 	    exit(1); */ | ||||
| /* 	 } */ | ||||
|       } | ||||
|    } | ||||
|  | ||||
|   | ||||
| @@ -680,18 +680,13 @@ loadpic(void) | ||||
|    } | ||||
|  | ||||
|    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
|    if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA, | ||||
| 				   GL_UNSIGNED_BYTE, | ||||
| 				   (GLvoid *) (&terrainpic[0][0])))) { | ||||
|       fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); | ||||
|       exit(-1); | ||||
|    } | ||||
|    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_RGBA, 256, 256, GL_RGBA, | ||||
| 		GL_UNSIGNED_BYTE, (GLvoid *) terrainpic); | ||||
|  | ||||
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | ||||
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | ||||
|  | ||||
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | ||||
| 		   GL_LINEAR_MIPMAP_LINEAR); | ||||
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|  | ||||
|    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: texobj.c,v 1.6.6.1 2003/02/23 19:25:07 keithw Exp $ */ | ||||
| /* $Id: texobj.c,v 1.6.6.2 2003/03/22 08:40:35 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Example of using the 1.1 texture object functions. | ||||
| @@ -50,7 +50,7 @@ static void draw( void ) | ||||
| #endif | ||||
|    } | ||||
|    else { | ||||
|       glCallList( TexObj[0] ); | ||||
| /*       glCallList( TexObj[0] ); */ | ||||
|    } | ||||
|    glBegin( GL_POLYGON ); | ||||
|    glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 ); | ||||
| @@ -70,7 +70,7 @@ static void draw( void ) | ||||
| #endif | ||||
|    } | ||||
|    else { | ||||
|       glCallList( TexObj[1] ); | ||||
| /*       glCallList( TexObj[1] ); */ | ||||
|    } | ||||
|    glBegin( GL_POLYGON ); | ||||
|    glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 ); | ||||
| @@ -166,8 +166,8 @@ static void init( void ) | ||||
| #endif | ||||
|    } | ||||
|    else { | ||||
|       TexObj[0] = glGenLists(2); | ||||
|       TexObj[1] = TexObj[0]+1; | ||||
| /*       TexObj[0] = glGenLists(2); */ | ||||
| /*       TexObj[1] = TexObj[0]+1; */ | ||||
|    } | ||||
|  | ||||
|    /* setup first texture object */ | ||||
| @@ -178,7 +178,7 @@ static void init( void ) | ||||
| #endif | ||||
|    } | ||||
|    else { | ||||
|       glNewList( TexObj[0], GL_COMPILE ); | ||||
| /*       glNewList( TexObj[0], GL_COMPILE ); */ | ||||
|    } | ||||
|    /* red on white */ | ||||
|    for (i=0;i<height;i++) { | ||||
| @@ -201,7 +201,7 @@ static void init( void ) | ||||
|    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); | ||||
|    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); | ||||
|    if (!UseObj) { | ||||
|       glEndList(); | ||||
| /*       glEndList(); */ | ||||
|    } | ||||
|    /* end of texture object */ | ||||
|  | ||||
| @@ -214,7 +214,7 @@ static void init( void ) | ||||
| /*       assert(!glIsTexture(TexObj[1] + 999)); */ | ||||
|    } | ||||
|    else { | ||||
|       glNewList( TexObj[1], GL_COMPILE ); | ||||
| /*       glNewList( TexObj[1], GL_COMPILE ); */ | ||||
|    } | ||||
|    /* green on blue */ | ||||
|    for (i=0;i<height;i++) { | ||||
| @@ -235,7 +235,7 @@ static void init( void ) | ||||
|    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); | ||||
|    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); | ||||
|    if (!UseObj) { | ||||
|       glEndList(); | ||||
| /*       glEndList(); */ | ||||
|    } | ||||
|    /* end texture object */ | ||||
|  | ||||
|   | ||||
| @@ -17,12 +17,14 @@ PROGS = prim \ | ||||
|  | ||||
| # make executable from .c file: | ||||
| .c: $(LIB_DEP) | ||||
| 	gcc -I../include -g $< -L../lib -lglut -lGL -lm -o $@ | ||||
| 	gcc -I../include -g $< -L../lib -lglut -lGL -lGLU -lm -o $@ | ||||
|  | ||||
|  | ||||
| default: $(PROGS) | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	-rm *.o *~ | ||||
| clean: clean_here | ||||
|  | ||||
| clean_here: | ||||
| 	rm -f *.o *~ $(PROGS) | ||||
|  | ||||
|   | ||||
| @@ -62,7 +62,7 @@ static void Init(void) | ||||
|     GLint i; | ||||
|  | ||||
|     glClearColor(0.0, 0.0, 0.0, 0.0); | ||||
|     glClearIndex(0.0); | ||||
| /*     glClearIndex(0.0); */ | ||||
|  | ||||
|     if (!rgb) { | ||||
| 	for (i = 0; i < 16; i++) { | ||||
| @@ -71,7 +71,7 @@ static void Init(void) | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     glPolygonStipple(stippleBits); | ||||
| /*     glPolygonStipple(stippleBits); */ | ||||
|  | ||||
|     antiAlias = GL_FALSE; | ||||
|     stipple = GL_FALSE; | ||||
| @@ -135,11 +135,11 @@ static void Draw(void) | ||||
|     } | ||||
|  | ||||
|     glBegin(GL_TRIANGLES); | ||||
| 	(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexi(ci1); | ||||
|         glColor3fv(RGBMap[COLOR_BLUE]); | ||||
| 	glVertex3f( 0.9, -0.9, -30.0); | ||||
| 	glVertex3f( 0.9,  0.9, -30.0); | ||||
| 	glVertex3f(-0.9,  0.0, -30.0); | ||||
| 	(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexi(ci2); | ||||
| 	glColor3fv(RGBMap[COLOR_GREEN]); | ||||
| 	glVertex3f(-0.9, -0.9, -40.0); | ||||
| 	glVertex3f(-0.9,  0.9, -40.0); | ||||
| 	glVertex3f( 0.9,  0.0, -25.0); | ||||
|   | ||||
| @@ -141,7 +141,7 @@ static void Draw(void) | ||||
|     for (i = 0; i < 360; i += 5) { | ||||
| 	glRotatef(5.0, 0,0,1); | ||||
|  | ||||
| 	(rgb) ? glColor3f(1.0, 1.0, 0.0) : glIndexi(ci); | ||||
| 	glColor3f(1.0, 1.0, 0.0); | ||||
| 	glBegin(GL_LINE_STRIP); | ||||
| 	    glVertex3fv(pntA); | ||||
| 	    glVertex3fv(pntB); | ||||
| @@ -199,7 +199,7 @@ int main(int argc, char **argv) | ||||
|  | ||||
|     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300); | ||||
|  | ||||
|     windType = (rgb) ? GLUT_RGB : GLUT_INDEX; | ||||
|     windType = GLUT_RGB; | ||||
|     windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; | ||||
|     glutInitDisplayMode(windType); | ||||
|  | ||||
|   | ||||
| @@ -153,9 +153,9 @@ static void Draw(void) | ||||
|  | ||||
| /*     glPointSize(size); */ | ||||
|     if (mode) { | ||||
| 	(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED); | ||||
|        glColor3f(1.0, 0.0, 0.0); | ||||
|     } else { | ||||
| 	(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_RED); | ||||
|        glColor3f(1.0, 0.0, 0.0); | ||||
|     } | ||||
|     glBegin(GL_POINTS); | ||||
| 	glVertex3fv(point); | ||||
|   | ||||
| @@ -126,18 +126,18 @@ static void Point(void) | ||||
|  | ||||
|     glBegin(GL_POINTS); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
| 	for (i = 1; i < 8; i++) { | ||||
| 	    GLint j = i * 2; | ||||
| 	    SetColor(COLOR_BLACK+i); | ||||
| 	    glVertex2i(-j, -j); | ||||
| 	    glVertex2i(-j, 0); | ||||
| 	    glVertex2i(-j, j); | ||||
| 	    glVertex2i(0, j); | ||||
| 	    glVertex2i(j, j); | ||||
| 	    glVertex2i(j, 0); | ||||
| 	    glVertex2i(j, -j); | ||||
| 	    glVertex2i(0, -j); | ||||
| 	    glVertex2f(-j, -j); | ||||
| 	    glVertex2f(-j, 0); | ||||
| 	    glVertex2f(-j, j); | ||||
| 	    glVertex2f(0, j); | ||||
| 	    glVertex2f(j, j); | ||||
| 	    glVertex2f(j, 0); | ||||
| 	    glVertex2f(j, -j); | ||||
| 	    glVertex2f(0, -j); | ||||
| 	} | ||||
|     glEnd(); | ||||
| } | ||||
| @@ -152,8 +152,8 @@ static void Lines(void) | ||||
|     for (i = 1; i < 8; i++) { | ||||
| 	SetColor(COLOR_BLACK+i); | ||||
| 	glBegin(GL_LINES); | ||||
| 	    glVertex2i(-boxW/4, -boxH/4); | ||||
| 	    glVertex2i(boxW/4, boxH/4); | ||||
| 	    glVertex2f(-boxW/4, -boxH/4); | ||||
| 	    glVertex2f(boxW/4, boxH/4); | ||||
| 	glEnd(); | ||||
| 	glTranslatef(4, 0, 0); | ||||
|     } | ||||
| @@ -161,7 +161,7 @@ static void Lines(void) | ||||
|     glPopMatrix(); | ||||
|  | ||||
|     glBegin(GL_LINES); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -180,7 +180,7 @@ static void LineStrip(void) | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_LINE_STRIP); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -218,11 +218,11 @@ static void LineLoop(void) | ||||
|  | ||||
|     SetColor(COLOR_GREEN); | ||||
|     glBegin(GL_POINTS); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_LINE_LOOP); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -231,16 +231,16 @@ static void Bitmap(void) | ||||
|  | ||||
|     glBegin(GL_LINES); | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/2, 0); | ||||
| 	glVertex2i(boxW/2, 0); | ||||
| 	glVertex2i(0, -boxH/2); | ||||
| 	glVertex2i(0, boxH/2); | ||||
| 	glVertex2f(-boxW/2, 0); | ||||
| 	glVertex2f(boxW/2, 0); | ||||
| 	glVertex2f(0, -boxH/2); | ||||
| 	glVertex2f(0, boxH/2); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(0, -3); | ||||
| 	glVertex2i(0, -3+OPENGL_HEIGHT); | ||||
| 	glVertex2f(0, -3); | ||||
| 	glVertex2f(0, -3+OPENGL_HEIGHT); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(0, -3); | ||||
| 	glVertex2i(OPENGL_WIDTH, -3); | ||||
| 	glVertex2f(0, -3); | ||||
| 	glVertex2f(OPENGL_WIDTH, -3); | ||||
|     glEnd(); | ||||
|  | ||||
|     SetColor(COLOR_GREEN); | ||||
| @@ -257,23 +257,23 @@ static void Triangles(void) | ||||
|  | ||||
|     glBegin(GL_TRIANGLES); | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, -boxH/4); | ||||
| 	glVertex2f(-boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/8, -boxH/16); | ||||
| 	glVertex2f(-boxW/8, -boxH/16); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(boxW/8, -boxH/16); | ||||
| 	glVertex2f(boxW/8, -boxH/16); | ||||
|  | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, boxH/4); | ||||
| 	glVertex2f(-boxW/4, boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/8, boxH/16); | ||||
| 	glVertex2f(-boxW/8, boxH/16); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(boxW/8, boxH/16); | ||||
| 	glVertex2f(boxW/8, boxH/16); | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_TRIANGLES); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(-100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(-100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -282,28 +282,28 @@ static void TriangleStrip(void) | ||||
|  | ||||
|     glBegin(GL_TRIANGLE_STRIP); | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, -boxH/4); | ||||
| 	glVertex2f(-boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/4, boxH/4); | ||||
| 	glVertex2f(-boxW/4, boxH/4); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(0, -boxH/4); | ||||
| 	glVertex2f(0, -boxH/4); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(0, boxH/4); | ||||
| 	glVertex2f(0, boxH/4); | ||||
| 	SetColor(COLOR_CYAN); | ||||
| 	glVertex2i(boxW/4, -boxH/4); | ||||
| 	glVertex2f(boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_YELLOW); | ||||
| 	glVertex2i(boxW/4, boxH/4); | ||||
| 	glVertex2f(boxW/4, boxH/4); | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_TRIANGLE_STRIP); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(-100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(-100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| static void TriangleFan(void) | ||||
| { | ||||
|     GLint vx[8][2]; | ||||
|     GLfloat vx[8][2]; | ||||
|     GLint x0, y0, x1, y1, x2, y2, x3, y3; | ||||
|     GLint i; | ||||
|  | ||||
| @@ -327,16 +327,16 @@ static void TriangleFan(void) | ||||
|  | ||||
|     glBegin(GL_TRIANGLE_FAN); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2f(0, 0); | ||||
| 	for (i = 0; i < 8; i++) { | ||||
| 	    SetColor(COLOR_WHITE-i); | ||||
| 	    glVertex2iv(vx[i]); | ||||
| 	    glVertex2fv(vx[i]); | ||||
| 	} | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_TRIANGLE_FAN); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(-100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(-100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -349,7 +349,7 @@ static void Rect(void) | ||||
|  | ||||
| static void PolygonFunc(void) | ||||
| { | ||||
|     GLint vx[8][2]; | ||||
|     GLfloat vx[8][2]; | ||||
|     GLint x0, y0, x1, y1, x2, y2, x3, y3; | ||||
|     GLint i; | ||||
|  | ||||
| @@ -374,13 +374,13 @@ static void PolygonFunc(void) | ||||
|     glBegin(GL_POLYGON); | ||||
| 	for (i = 0; i < 8; i++) { | ||||
| 	    SetColor(COLOR_WHITE-i); | ||||
| 	    glVertex2iv(vx[i]); | ||||
| 	    glVertex2fv(vx[i]); | ||||
| 	} | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_POLYGON); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -389,28 +389,28 @@ static void Quads(void) | ||||
|  | ||||
|     glBegin(GL_QUADS); | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, -boxH/4); | ||||
| 	glVertex2f(-boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/8, -boxH/16); | ||||
| 	glVertex2f(-boxW/8, -boxH/16); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(boxW/8, -boxH/16); | ||||
| 	glVertex2f(boxW/8, -boxH/16); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(boxW/4, -boxH/4); | ||||
| 	glVertex2f(boxW/4, -boxH/4); | ||||
|  | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, boxH/4); | ||||
| 	glVertex2f(-boxW/4, boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/8, boxH/16); | ||||
| 	glVertex2f(-boxW/8, boxH/16); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(boxW/8, boxH/16); | ||||
| 	glVertex2f(boxW/8, boxH/16); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(boxW/4, boxH/4); | ||||
| 	glVertex2f(boxW/4, boxH/4); | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_QUADS); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(100, 100); | ||||
| 	glVertex2i(-100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(100, 100); | ||||
| 	glVertex2f(-100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| @@ -419,29 +419,30 @@ static void QuadStrip(void) | ||||
|  | ||||
|     glBegin(GL_QUAD_STRIP); | ||||
| 	SetColor(COLOR_GREEN); | ||||
| 	glVertex2i(-boxW/4, -boxH/4); | ||||
| 	glVertex2f(-boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_RED); | ||||
| 	glVertex2i(-boxW/4, boxH/4); | ||||
| 	glVertex2f(-boxW/4, boxH/4); | ||||
| 	SetColor(COLOR_BLUE); | ||||
| 	glVertex2i(0, -boxH/4); | ||||
| 	glVertex2f(0, -boxH/4); | ||||
| 	SetColor(COLOR_WHITE); | ||||
| 	glVertex2i(0, boxH/4); | ||||
| 	glVertex2f(0, boxH/4); | ||||
| 	SetColor(COLOR_CYAN); | ||||
| 	glVertex2i(boxW/4, -boxH/4); | ||||
| 	glVertex2f(boxW/4, -boxH/4); | ||||
| 	SetColor(COLOR_YELLOW); | ||||
| 	glVertex2i(boxW/4, boxH/4); | ||||
| 	glVertex2f(boxW/4, boxH/4); | ||||
|     glEnd(); | ||||
|  | ||||
|     glBegin(GL_QUAD_STRIP); | ||||
| 	glVertex2i(0, 0); | ||||
| 	glVertex2i(100, 100); | ||||
| 	glVertex2i(-100, 100); | ||||
| 	glVertex2f(0, 0); | ||||
| 	glVertex2f(100, 100); | ||||
| 	glVertex2f(-100, 100); | ||||
|     glEnd(); | ||||
| } | ||||
|  | ||||
| static void Draw(void) | ||||
| { | ||||
|  | ||||
|    fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|     | ||||
|     glViewport(0, 0, windW, windH); | ||||
|     glDisable(GL_SCISSOR_TEST); | ||||
|  | ||||
|   | ||||
| @@ -255,7 +255,6 @@ static void Key(unsigned char key, int x, int y) | ||||
|  | ||||
| void Draw(void) | ||||
| { | ||||
|  | ||||
|     MoveStars(); | ||||
|     ShowStars(); | ||||
|     if (nitro > 0) { | ||||
|   | ||||
| @@ -26,8 +26,8 @@ static void SetColor(int c) | ||||
| { | ||||
|     if (glutGet(GLUT_WINDOW_RGBA)) | ||||
|         glColor3fv(RGBMap[c]); | ||||
|     else | ||||
|         glIndexf(c); | ||||
| /*     else */ | ||||
| /*         glIndexf(c); */ | ||||
| } | ||||
|  | ||||
| static void InitMap(void) | ||||
|   | ||||
| @@ -278,11 +278,11 @@ static void Draw(void) | ||||
| 	EndPrim(); | ||||
|  | ||||
| 	if (showVerticies) { | ||||
| 	    (rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1); | ||||
| 	    glColor3fv(RGBMap[COLOR_RED]); | ||||
| /* 	    glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2); */ | ||||
| 	    (rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2); | ||||
| 	    glColor3fv(RGBMap[COLOR_GREEN]); | ||||
| /* 	    glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2); */ | ||||
| 	    (rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3); | ||||
| 	    glColor3fv(RGBMap[COLOR_BLUE]); | ||||
| /* 	    glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2); */ | ||||
| 	} | ||||
|  | ||||
| @@ -314,11 +314,11 @@ static void Draw(void) | ||||
|  | ||||
|     SetColor(COLOR_RED); | ||||
|     BeginPrim(); | ||||
| 	(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1); | ||||
| 	glColor3fv(RGBMap[COLOR_RED]); | ||||
| 	glVertex3fv(p0); | ||||
| 	(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2); | ||||
| 	glColor3fv(RGBMap[COLOR_GREEN]); | ||||
| 	glVertex3fv(p1); | ||||
| 	(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3); | ||||
| 	glColor3fv(RGBMap[COLOR_BLUE]); | ||||
| 	glVertex3fv(p2); | ||||
|     EndPrim(); | ||||
|  | ||||
|   | ||||
| @@ -6,9 +6,9 @@ | ||||
|  | ||||
| CC = gcc | ||||
| CFLAGS = -g -I../include | ||||
| LIBS = -L../lib -lGL -lglut -lm | ||||
| LIBS = -L../lib -lGL -lGLU -lglut -lm | ||||
|  | ||||
| PROGS = miniglxtest miniglxsample manytex  | ||||
| PROGS = miniglxtest miniglxsample manytex texline | ||||
|  | ||||
|  | ||||
| ##### RULES ##### | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: manytex.c,v 1.4 2002/10/18 17:47:36 kschultz Exp $ */ | ||||
| /* $Id: manytex.c,v 1.4.4.1 2003/03/22 08:46:22 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * test handling of many texture maps | ||||
| @@ -191,8 +191,8 @@ static void Init( void ) | ||||
|  | ||||
|       glBindTexture(GL_TEXTURE_2D, TextureID[i]); | ||||
|  | ||||
|       if (i < LowPriorityCount) | ||||
|          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); | ||||
| /*       if (i < LowPriorityCount) */ | ||||
| /*          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); */ | ||||
|  | ||||
|       if (RandomSize) { | ||||
| #if 0 | ||||
|   | ||||
| @@ -79,6 +79,8 @@ MakeWindow(Display * dpy, unsigned int width, unsigned int height) | ||||
|    /* Bind the rendering context and window */ | ||||
|    glXMakeCurrent(dpy, win, ctx); | ||||
|  | ||||
|    glViewport(0, 0, width, height); | ||||
|  | ||||
|    return win; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: miniglxtest.c,v 1.1.4.7 2003/02/21 22:18:24 keithw Exp $ */ | ||||
| /* $Id: miniglxtest.c,v 1.1.4.9 2003/03/24 18:46:57 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Test the mini GLX interface. | ||||
| @@ -122,6 +122,8 @@ static Window make_rgb_db_window( Display *dpy, | ||||
|  | ||||
|    glXMakeCurrent( dpy, win, ctx ); | ||||
|  | ||||
|    glViewport(0, 0, width, height); | ||||
|  | ||||
|    return win; | ||||
| } | ||||
|  | ||||
| @@ -161,7 +163,6 @@ int foo( ) | ||||
|  | ||||
|    XMapWindow( dpy, win ); | ||||
|  | ||||
| #if !USE_MINI_GLX | ||||
|    { | ||||
|       XEvent e; | ||||
|       while (1) { | ||||
| @@ -171,8 +172,6 @@ int foo( ) | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|    event_loop( dpy, win ); | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: texline.c,v 1.4 2002/08/17 00:30:36 brianp Exp $ */ | ||||
| /* $Id: texline.c,v 1.4.6.1 2003/03/22 08:46:22 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Test textured lines. | ||||
| @@ -59,7 +59,7 @@ static void Display( void ) | ||||
|             y = t * 2.0 - 1.0; | ||||
|             if (!Texture) | ||||
|                glColor3f(1, 0, 1); | ||||
|             glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s); | ||||
| /*             glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s); */ | ||||
|             glTexCoord2f(s, t); | ||||
|             glVertex2f(x, y); | ||||
|          } | ||||
| @@ -73,12 +73,12 @@ static void Display( void ) | ||||
|          if (!Texture) | ||||
|             glColor3f(1, 0, 1); | ||||
|          glTexCoord2f(t, 0.0); | ||||
|          glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t); | ||||
| /*          glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t); */ | ||||
|          glVertex2f(x, -1.0); | ||||
|          if (!Texture) | ||||
|             glColor3f(0, 1, 0); | ||||
|          glTexCoord2f(t, 1.0); | ||||
|          glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t); | ||||
| /*          glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t); */ | ||||
|          glVertex2f(x, 1.0); | ||||
|       } | ||||
|       glEnd(); | ||||
| @@ -127,22 +127,22 @@ static void Key( unsigned char key, int x, int y ) | ||||
|          if (Texture > 2) | ||||
|             Texture = 0; | ||||
|          if (Texture == 0) { | ||||
|             glActiveTextureARB(GL_TEXTURE0_ARB); | ||||
|             glDisable(GL_TEXTURE_2D); | ||||
|             glActiveTextureARB(GL_TEXTURE1_ARB); | ||||
| /*             glActiveTextureARB(GL_TEXTURE0_ARB); */ | ||||
|             glDisable(GL_TEXTURE_2D); | ||||
| /*             glActiveTextureARB(GL_TEXTURE1_ARB); */ | ||||
| /*             glDisable(GL_TEXTURE_2D); */ | ||||
|          } | ||||
|          else if (Texture == 1) { | ||||
|             glActiveTextureARB(GL_TEXTURE0_ARB); | ||||
| /*             glActiveTextureARB(GL_TEXTURE0_ARB); */ | ||||
|             glEnable(GL_TEXTURE_2D); | ||||
|             glActiveTextureARB(GL_TEXTURE1_ARB); | ||||
|             glDisable(GL_TEXTURE_2D); | ||||
| /*             glActiveTextureARB(GL_TEXTURE1_ARB); */ | ||||
| /*             glDisable(GL_TEXTURE_2D); */ | ||||
|          } | ||||
|          else { | ||||
|             glActiveTextureARB(GL_TEXTURE0_ARB); | ||||
|             glEnable(GL_TEXTURE_2D); | ||||
|             glActiveTextureARB(GL_TEXTURE1_ARB); | ||||
| /*             glActiveTextureARB(GL_TEXTURE0_ARB); */ | ||||
|             glEnable(GL_TEXTURE_2D); | ||||
| /*             glActiveTextureARB(GL_TEXTURE1_ARB); */ | ||||
| /*             glEnable(GL_TEXTURE_2D); */ | ||||
|          } | ||||
|          break; | ||||
|       case 'w': | ||||
| @@ -212,8 +212,8 @@ static void SpecialKey( int key, int x, int y ) | ||||
| static void Init( int argc, char *argv[] ) | ||||
| { | ||||
|    GLuint u; | ||||
|    for (u = 0; u < 2; u++) { | ||||
|       glActiveTextureARB(GL_TEXTURE0_ARB + u); | ||||
|    for (u = 0; u < 1; u++) { | ||||
| /*       glActiveTextureARB(GL_TEXTURE0_ARB + u); */ | ||||
|       glBindTexture(GL_TEXTURE_2D, 10+u); | ||||
|       if (u == 0) | ||||
|          glEnable(GL_TEXTURE_2D); | ||||
|   | ||||
							
								
								
									
										7
									
								
								src/glu/mini/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/glu/mini/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| .deps | ||||
| .libs | ||||
| Makefile.in | ||||
| *.lo | ||||
| *.o | ||||
| *.la | ||||
| depend | ||||
							
								
								
									
										46
									
								
								src/glu/mini/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/glu/mini/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
|  | ||||
|  | ||||
| MESA = ../.. | ||||
| default: libGLU.so.1.1 install  | ||||
| include $(MESA)/Makefile.include | ||||
|  | ||||
| LIBDIR = $(MESA)/lib | ||||
|  | ||||
| INCLUDES = -I$(MESA)/include  | ||||
| CFLAGS = -c -g $(INCLUDES) -MD  | ||||
|  | ||||
| SOURCES = glu.c \ | ||||
| 	mipmap.c \ | ||||
| 	nurbs.c \ | ||||
| 	polytest.c \ | ||||
| 	project.c \ | ||||
| 	quadric.c \ | ||||
| 	tess.c \ | ||||
| 	tesselat.c | ||||
|  | ||||
|  | ||||
| OBJS = $(addsuffix .o,$(basename $(SOURCES))) | ||||
|  | ||||
| LIBS=-L$(MESA)/lib -lGL -lm | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| libGLU.so.1.1: $(OBJS) Makefile | ||||
| 	gcc -shared -Wl,-soname,libGLU.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@  | ||||
|  | ||||
| install: | ||||
| 	rm -f $(MESA)/lib/libGLU.so* | ||||
| 	install -D libGLU.so.1.1 $(MESA)/lib/libGLU.so.1.1 | ||||
| 	ln -s libGLU.so.1.1 $(MESA)/lib/libGLU.so.1 | ||||
| 	ln -s libGLU.so.1 $(MESA)/lib/libGLU.so | ||||
|  | ||||
|  | ||||
| clean: clean_here | ||||
|  | ||||
| clean_here: | ||||
| 	rm -f ../lib/libGLU.so* | ||||
|  | ||||
|  | ||||
| -include $(SOURCES:.c=.d) | ||||
							
								
								
									
										55
									
								
								src/glu/mini/all.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/glu/mini/all.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* $Id: all.h,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file includes all .h files needed for the GLU source code for | ||||
|  * the purpose of precompiled headers. | ||||
|  * | ||||
|  * If the preprocessor symbol PCH is defined at compile time then each | ||||
|  * of the .c files will #include "all.h" only, instead of a bunch of | ||||
|  * individual .h files. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef GLU_ALL_H | ||||
| #define GLU_ALL_H | ||||
|  | ||||
|  | ||||
| #ifndef PC_HEADER | ||||
| This is an error.  all.h should be included only if PCH is defined. | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include "GL/gl.h" | ||||
| #include "GL/glu.h" | ||||
| #include "gluP.h" | ||||
| #include "nurbs.h" | ||||
| #include "tess.h" | ||||
|  | ||||
|  | ||||
| #endif /*GLU_ALL_H */ | ||||
							
								
								
									
										417
									
								
								src/glu/mini/glu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										417
									
								
								src/glu/mini/glu.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,417 @@ | ||||
| /* $Id: glu.c,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.5 | ||||
|  * Copyright (C) 1995-2001  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <assert.h> | ||||
| #include <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include "gluP.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Miscellaneous utility functions | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef M_PI | ||||
| #define M_PI 3.1415926536 | ||||
| #endif | ||||
| #define EPS 0.00001 | ||||
|  | ||||
| #ifndef GLU_INCOMPATIBLE_GL_VERSION | ||||
| #define GLU_INCOMPATIBLE_GL_VERSION     100903 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, | ||||
| 	  GLdouble centerx, GLdouble centery, GLdouble centerz, | ||||
| 	  GLdouble upx, GLdouble upy, GLdouble upz) | ||||
| { | ||||
|    GLfloat m[16]; | ||||
|    GLfloat x[3], y[3], z[3]; | ||||
|    GLfloat mag; | ||||
|  | ||||
|    /* Make rotation matrix */ | ||||
|  | ||||
|    /* Z vector */ | ||||
|    z[0] = eyex - centerx; | ||||
|    z[1] = eyey - centery; | ||||
|    z[2] = eyez - centerz; | ||||
|    mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); | ||||
|    if (mag) {			/* mpichler, 19950515 */ | ||||
|       z[0] /= mag; | ||||
|       z[1] /= mag; | ||||
|       z[2] /= mag; | ||||
|    } | ||||
|  | ||||
|    /* Y vector */ | ||||
|    y[0] = upx; | ||||
|    y[1] = upy; | ||||
|    y[2] = upz; | ||||
|  | ||||
|    /* X vector = Y cross Z */ | ||||
|    x[0] = y[1] * z[2] - y[2] * z[1]; | ||||
|    x[1] = -y[0] * z[2] + y[2] * z[0]; | ||||
|    x[2] = y[0] * z[1] - y[1] * z[0]; | ||||
|  | ||||
|    /* Recompute Y = Z cross X */ | ||||
|    y[0] = z[1] * x[2] - z[2] * x[1]; | ||||
|    y[1] = -z[0] * x[2] + z[2] * x[0]; | ||||
|    y[2] = z[0] * x[1] - z[1] * x[0]; | ||||
|  | ||||
|    /* mpichler, 19950515 */ | ||||
|    /* cross product gives area of parallelogram, which is < 1.0 for | ||||
|     * non-perpendicular unit-length vectors; so normalize x, y here | ||||
|     */ | ||||
|  | ||||
|    mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); | ||||
|    if (mag) { | ||||
|       x[0] /= mag; | ||||
|       x[1] /= mag; | ||||
|       x[2] /= mag; | ||||
|    } | ||||
|  | ||||
|    mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); | ||||
|    if (mag) { | ||||
|       y[0] /= mag; | ||||
|       y[1] /= mag; | ||||
|       y[2] /= mag; | ||||
|    } | ||||
|  | ||||
| #define M(row,col)  m[col*4+row] | ||||
|    M(0, 0) = x[0]; | ||||
|    M(0, 1) = x[1]; | ||||
|    M(0, 2) = x[2]; | ||||
|    M(0, 3) = 0.0; | ||||
|    M(1, 0) = y[0]; | ||||
|    M(1, 1) = y[1]; | ||||
|    M(1, 2) = y[2]; | ||||
|    M(1, 3) = 0.0; | ||||
|    M(2, 0) = z[0]; | ||||
|    M(2, 1) = z[1]; | ||||
|    M(2, 2) = z[2]; | ||||
|    M(2, 3) = 0.0; | ||||
|    M(3, 0) = 0.0; | ||||
|    M(3, 1) = 0.0; | ||||
|    M(3, 2) = 0.0; | ||||
|    M(3, 3) = 1.0; | ||||
| #undef M | ||||
|    glMultMatrixf(m); | ||||
|  | ||||
|    /* Translate Eye to Origin */ | ||||
|    glTranslatef(-eyex, -eyey, -eyez); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) | ||||
| { | ||||
|    glOrtho(left, right, bottom, top, -1.0, 1.0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void | ||||
| frustum(GLfloat left, GLfloat right, | ||||
|         GLfloat bottom, GLfloat top,  | ||||
|         GLfloat nearval, GLfloat farval) | ||||
| { | ||||
|    GLfloat x, y, a, b, c, d; | ||||
|    GLfloat m[16]; | ||||
|  | ||||
|    x = (2.0 * nearval) / (right - left); | ||||
|    y = (2.0 * nearval) / (top - bottom); | ||||
|    a = (right + left) / (right - left); | ||||
|    b = (top + bottom) / (top - bottom); | ||||
|    c = -(farval + nearval) / ( farval - nearval); | ||||
|    d = -(2.0 * farval * nearval) / (farval - nearval); | ||||
|  | ||||
| #define M(row,col)  m[col*4+row] | ||||
|    M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F; | ||||
|    M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F; | ||||
|    M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d; | ||||
|    M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F; | ||||
| #undef M | ||||
|  | ||||
|    glMultMatrixf(m); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) | ||||
| { | ||||
|    GLfloat xmin, xmax, ymin, ymax; | ||||
|  | ||||
|    ymax = zNear * tan(fovy * M_PI / 360.0); | ||||
|    ymin = -ymax; | ||||
|    xmin = ymin * aspect; | ||||
|    xmax = ymax * aspect; | ||||
|  | ||||
|    /* don't call glFrustum() because of error semantics (covglu) */ | ||||
|    frustum(xmin, xmax, ymin, ymax, zNear, zFar); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluPickMatrix(GLdouble x, GLdouble y, | ||||
| 	      GLdouble width, GLdouble height, GLint viewport[4]) | ||||
| { | ||||
|    GLfloat m[16]; | ||||
|    GLfloat sx, sy; | ||||
|    GLfloat tx, ty; | ||||
|  | ||||
|    sx = viewport[2] / width; | ||||
|    sy = viewport[3] / height; | ||||
|    tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width; | ||||
|    ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height; | ||||
|  | ||||
| #define M(row,col)  m[col*4+row] | ||||
|    M(0, 0) = sx; | ||||
|    M(0, 1) = 0.0; | ||||
|    M(0, 2) = 0.0; | ||||
|    M(0, 3) = tx; | ||||
|    M(1, 0) = 0.0; | ||||
|    M(1, 1) = sy; | ||||
|    M(1, 2) = 0.0; | ||||
|    M(1, 3) = ty; | ||||
|    M(2, 0) = 0.0; | ||||
|    M(2, 1) = 0.0; | ||||
|    M(2, 2) = 1.0; | ||||
|    M(2, 3) = 0.0; | ||||
|    M(3, 0) = 0.0; | ||||
|    M(3, 1) = 0.0; | ||||
|    M(3, 2) = 0.0; | ||||
|    M(3, 3) = 1.0; | ||||
| #undef M | ||||
|  | ||||
|    glMultMatrixf(m); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| const GLubyte *GLAPIENTRY | ||||
| gluErrorString(GLenum errorCode) | ||||
| { | ||||
|    static char *tess_error[] = { | ||||
|       "missing gluBeginPolygon", | ||||
|       "missing gluBeginContour", | ||||
|       "missing gluEndPolygon", | ||||
|       "missing gluEndContour", | ||||
|       "misoriented or self-intersecting loops", | ||||
|       "coincident vertices", | ||||
|       "colinear vertices", | ||||
|       "FIST recovery process fatal error" | ||||
|    }; | ||||
|    static char *nurbs_error[] = { | ||||
|       "spline order un-supported", | ||||
|       "too few knots", | ||||
|       "valid knot range is empty", | ||||
|       "decreasing knot sequence knot", | ||||
|       "knot multiplicity greater than order of spline", | ||||
|       "endcurve() must follow bgncurve()", | ||||
|       "bgncurve() must precede endcurve()", | ||||
|       "missing or extra geometric data", | ||||
|       "can't draw pwlcurves", | ||||
|       "missing bgncurve()", | ||||
|       "missing bgnsurface()", | ||||
|       "endtrim() must precede endsurface()", | ||||
|       "bgnsurface() must precede endsurface()", | ||||
|       "curve of improper type passed as trim curve", | ||||
|       "bgnsurface() must precede bgntrim()", | ||||
|       "endtrim() must follow bgntrim()", | ||||
|       "bgntrim() must precede endtrim()", | ||||
|       "invalid or missing trim curve", | ||||
|       "bgntrim() must precede pwlcurve()", | ||||
|       "pwlcurve referenced twice", | ||||
|       "pwlcurve and nurbscurve mixed", | ||||
|       "improper usage of trim data type", | ||||
|       "nurbscurve referenced twice", | ||||
|       "nurbscurve and pwlcurve mixed", | ||||
|       "nurbssurface referenced twice", | ||||
|       "invalid property", | ||||
|       "endsurface() must follow bgnsurface()", | ||||
|       "misoriented trim curves", | ||||
|       "intersecting trim curves", | ||||
|       "UNUSED", | ||||
|       "unconnected trim curves", | ||||
|       "unknown knot error", | ||||
|       "negative vertex count encountered", | ||||
|       "negative byte-stride encountered", | ||||
|       "unknown type descriptor", | ||||
|       "null control array or knot vector", | ||||
|       "duplicate point on pwlcurve" | ||||
|    }; | ||||
|  | ||||
|    /* GL Errors */ | ||||
|    if (errorCode == GL_NO_ERROR) { | ||||
|       return (GLubyte *) "no error"; | ||||
|    } | ||||
|    else if (errorCode == GL_INVALID_VALUE) { | ||||
|       return (GLubyte *) "invalid value"; | ||||
|    } | ||||
|    else if (errorCode == GL_INVALID_ENUM) { | ||||
|       return (GLubyte *) "invalid enum"; | ||||
|    } | ||||
|    else if (errorCode == GL_INVALID_OPERATION) { | ||||
|       return (GLubyte *) "invalid operation"; | ||||
|    } | ||||
|    else if (errorCode == GL_STACK_OVERFLOW) { | ||||
|       return (GLubyte *) "stack overflow"; | ||||
|    } | ||||
|    else if (errorCode == GL_STACK_UNDERFLOW) { | ||||
|       return (GLubyte *) "stack underflow"; | ||||
|    } | ||||
|    else if (errorCode == GL_OUT_OF_MEMORY) { | ||||
|       return (GLubyte *) "out of memory"; | ||||
|    } | ||||
|    /* GLU Errors */ | ||||
|    else if (errorCode == GLU_NO_ERROR) { | ||||
|       return (GLubyte *) "no error"; | ||||
|    } | ||||
|    else if (errorCode == GLU_INVALID_ENUM) { | ||||
|       return (GLubyte *) "invalid enum"; | ||||
|    } | ||||
|    else if (errorCode == GLU_INVALID_VALUE) { | ||||
|       return (GLubyte *) "invalid value"; | ||||
|    } | ||||
|    else if (errorCode == GLU_OUT_OF_MEMORY) { | ||||
|       return (GLubyte *) "out of memory"; | ||||
|    } | ||||
|    else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) { | ||||
|       return (GLubyte *) "incompatible GL version"; | ||||
|    } | ||||
|    else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) { | ||||
|       return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1]; | ||||
|    } | ||||
|    else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) { | ||||
|       return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1]; | ||||
|    } | ||||
|    else { | ||||
|       return NULL; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * New in GLU 1.1 | ||||
|  */ | ||||
|  | ||||
| const GLubyte *GLAPIENTRY | ||||
| gluGetString(GLenum name) | ||||
| { | ||||
|    static char *extensions = "GL_EXT_abgr"; | ||||
|    static char *version = "1.1 Mesa 3.5"; | ||||
|  | ||||
|    switch (name) { | ||||
|    case GLU_EXTENSIONS: | ||||
|       return (GLubyte *) extensions; | ||||
|    case GLU_VERSION: | ||||
|       return (GLubyte *) version; | ||||
|    default: | ||||
|       return NULL; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| #if 0				/* gluGetProcAddressEXT not finalized yet! */ | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|    /* for BeOS R4.5 */ | ||||
| void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...) | ||||
| #else | ||||
| void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) () | ||||
| #endif | ||||
| { | ||||
|    struct proc | ||||
|    { | ||||
|       const char *name; | ||||
|       void *address; | ||||
|    }; | ||||
|    static struct proc procTable[] = { | ||||
|       {"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT},	/* me! */ | ||||
|  | ||||
|       /* new 1.1 functions */ | ||||
|       {"gluGetString", (void *) gluGetString}, | ||||
|  | ||||
|       /* new 1.2 functions */ | ||||
|       {"gluTessBeginPolygon", (void *) gluTessBeginPolygon}, | ||||
|       {"gluTessBeginContour", (void *) gluTessBeginContour}, | ||||
|       {"gluTessEndContour", (void *) gluTessEndContour}, | ||||
|       {"gluTessEndPolygon", (void *) gluTessEndPolygon}, | ||||
|       {"gluGetTessProperty", (void *) gluGetTessProperty}, | ||||
|  | ||||
|       /* new 1.3 functions */ | ||||
|  | ||||
|       {NULL, NULL} | ||||
|    }; | ||||
|    GLuint i; | ||||
|  | ||||
|    for (i = 0; procTable[i].address; i++) { | ||||
|       if (strcmp((const char *) procName, procTable[i].name) == 0) | ||||
| 	 return (void (GLAPIENTRY *) ()) procTable[i].address; | ||||
|    } | ||||
|  | ||||
|    return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * New in GLU 1.3 | ||||
|  */ | ||||
| #ifdef GLU_VERSION_1_3 | ||||
| GLboolean GLAPIENTRY | ||||
| gluCheckExtension(const GLubyte *extName, const GLubyte * extString) | ||||
| { | ||||
|    assert(extName); | ||||
|    assert(extString); | ||||
|    { | ||||
|       const int len = strlen((const char *) extName); | ||||
|       const char *start = (const char *) extString; | ||||
|  | ||||
|       while (1) { | ||||
| 	 const char *c = strstr(start, (const char *) extName); | ||||
| 	 if (!c) | ||||
| 	    return GL_FALSE; | ||||
|  | ||||
| 	 if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0)) | ||||
| 	    return GL_TRUE; | ||||
|  | ||||
| 	 start = c + len; | ||||
|       } | ||||
|    } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										142
									
								
								src/glu/mini/gluP.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/glu/mini/gluP.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| /* $Id: gluP.h,v 1.1.2.1 2003/03/21 13:02:10 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file allows the GLU code to be compiled either with the Mesa | ||||
|  * headers or with the real OpenGL headers. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef GLUP_H | ||||
| #define GLUP_H | ||||
|  | ||||
|  | ||||
| #include <GL/gl.h> | ||||
| #include <GL/glu.h> | ||||
| #include <string.h> | ||||
|  | ||||
|  | ||||
| #if defined(_WIN32) && !defined(__WIN32__) | ||||
| #	define __WIN32__ | ||||
| #endif | ||||
|  | ||||
| #if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN__)) | ||||
| #  pragma warning( disable : 4068 ) /* unknown pragma */ | ||||
| #  pragma warning( disable : 4710 ) /* function 'foo' not inlined */ | ||||
| #  pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */ | ||||
| #  pragma warning( disable : 4127 ) /* conditional expression is constant */ | ||||
| #  if defined(MESA_MINWARN) | ||||
| #    pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */ | ||||
| #    pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */ | ||||
| #    pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */ | ||||
| #    pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */ | ||||
| #    pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */ | ||||
| #  endif | ||||
| #  if defined(_MSC_VER) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ | ||||
| #    define GLAPI __declspec(dllexport) | ||||
| #    define WGLAPI __declspec(dllexport) | ||||
| #  elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ | ||||
| #    define GLAPI __declspec(dllimport) | ||||
| #    define WGLAPI __declspec(dllimport) | ||||
| #  else /* for use with static link lib build of Win32 edition only */ | ||||
| #    define GLAPI extern | ||||
| #    define WGLAPI __declspec(dllimport) | ||||
| #  endif /* _STATIC_MESA support */ | ||||
| #  define GLAPIENTRY __stdcall | ||||
| #  define GLAPIENTRYP __stdcall * | ||||
| #  define GLCALLBACK __stdcall | ||||
| #  define GLCALLBACKP __stdcall * | ||||
| #  if defined(__CYGWIN__) | ||||
| #    define GLCALLBACKPCAST * | ||||
| #  else | ||||
| #    define GLCALLBACKPCAST __stdcall * | ||||
| #  endif | ||||
| #  define GLWINAPI __stdcall | ||||
| #  define GLWINAPIV __cdecl | ||||
| #else | ||||
| /* non-Windows compilation */ | ||||
| #  define GLAPI extern | ||||
| #  define GLAPIENTRY | ||||
| #  define GLAPIENTRYP * | ||||
| #  define GLCALLBACK | ||||
| #  define GLCALLBACKP * | ||||
| #  define GLCALLBACKPCAST * | ||||
| #  define GLWINAPI | ||||
| #  define GLWINAPIV | ||||
| #endif /* WIN32 / CYGWIN bracket */ | ||||
|  | ||||
| /* compatability guard so we don't need to change client code */ | ||||
|  | ||||
| #if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP) | ||||
| #	define CALLBACK GLCALLBACK | ||||
| typedef int (GLAPIENTRY *PROC)(); | ||||
| typedef void *HGLRC; | ||||
| typedef void *HDC; | ||||
| typedef unsigned long COLORREF; | ||||
| #endif | ||||
|  | ||||
| #if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) | ||||
| #	define WGL_FONT_LINES      0 | ||||
| #	define WGL_FONT_POLYGONS   1 | ||||
| #ifndef _GNU_H_WINDOWS32_FUNCTIONS | ||||
| #	ifdef UNICODE | ||||
| #		define wglUseFontBitmaps  wglUseFontBitmapsW | ||||
| #		define wglUseFontOutlines  wglUseFontOutlinesW | ||||
| #	else | ||||
| #		define wglUseFontBitmaps  wglUseFontBitmapsA | ||||
| #		define wglUseFontOutlines  wglUseFontOutlinesA | ||||
| #	endif /* !UNICODE */ | ||||
| #endif /* _GNU_H_WINDOWS32_FUNCTIONS */ | ||||
| typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR; | ||||
| typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT; | ||||
| typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR; | ||||
| #include <gl/mesa_wgl.h> | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifndef GLU_TESS_ERROR9 | ||||
|    /* If we're using the real OpenGL header files... */ | ||||
| #  define GLU_TESS_ERROR9	100159 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #define GLU_NO_ERROR		GL_NO_ERROR | ||||
|  | ||||
|  | ||||
| /* for Sun: */ | ||||
| #ifdef SUNOS4 | ||||
| #define MEMCPY( DST, SRC, BYTES) \ | ||||
| 	memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) ) | ||||
| #else | ||||
| #define MEMCPY( DST, SRC, BYTES) \ | ||||
| 	memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) ) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifndef NULL | ||||
| #  define NULL 0 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										764
									
								
								src/glu/mini/mipmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										764
									
								
								src/glu/mini/mipmap.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,764 @@ | ||||
| /* $Id: mipmap.c,v 1.1.2.1 2003/03/21 13:02:12 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.4 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <assert.h> | ||||
| #include <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include "gluP.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Compute ceiling of integer quotient of A divided by B: | ||||
|  */ | ||||
| #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifdef EPSILON | ||||
| #undef EPSILON | ||||
| #endif | ||||
| #define EPSILON 0.001 | ||||
|  | ||||
|  | ||||
| /* To work around optimizer bug in MSVC4.1 */ | ||||
| #if defined(__WIN32__) && !defined(OPENSTEP) | ||||
| void | ||||
| dummy(GLuint j, GLuint k) | ||||
| { | ||||
| } | ||||
| #else | ||||
| #define dummy(J, K) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| GLint GLAPIENTRY | ||||
| gluScaleImage(GLenum format, | ||||
| 	      GLsizei widthin, GLsizei heightin, | ||||
| 	      GLenum typein, const void *datain, | ||||
| 	      GLsizei widthout, GLsizei heightout, | ||||
| 	      GLenum typeout, void *dataout) | ||||
| { | ||||
|    GLint components, i, j, k; | ||||
|    GLfloat *tempin, *tempout, f; | ||||
|    GLfloat sx, sy; | ||||
|    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels; | ||||
|    GLint packrowlength, packalignment, packskiprows, packskippixels; | ||||
|    GLint sizein, sizeout; | ||||
|    GLint rowstride, rowlen; | ||||
|  | ||||
|  | ||||
|    /* Determine number of components per pixel */ | ||||
|    switch (format) { | ||||
|    case GL_COLOR_INDEX: | ||||
|    case GL_STENCIL_INDEX: | ||||
|    case GL_DEPTH_COMPONENT: | ||||
|    case GL_RED: | ||||
|    case GL_GREEN: | ||||
|    case GL_BLUE: | ||||
|    case GL_ALPHA: | ||||
|    case GL_LUMINANCE: | ||||
|       components = 1; | ||||
|       break; | ||||
|    case GL_LUMINANCE_ALPHA: | ||||
|       components = 2; | ||||
|       break; | ||||
|    case GL_RGB: | ||||
|    case GL_BGR: | ||||
|       components = 3; | ||||
|       break; | ||||
|    case GL_RGBA: | ||||
|    case GL_BGRA: | ||||
| #ifdef GL_EXT_abgr | ||||
|    case GL_ABGR_EXT: | ||||
| #endif | ||||
|       components = 4; | ||||
|       break; | ||||
|    default: | ||||
|       return GLU_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|    /* Determine bytes per input datum */ | ||||
|    switch (typein) { | ||||
|    case GL_UNSIGNED_BYTE: | ||||
|       sizein = sizeof(GLubyte); | ||||
|       break; | ||||
|    case GL_BYTE: | ||||
|       sizein = sizeof(GLbyte); | ||||
|       break; | ||||
|    case GL_UNSIGNED_SHORT: | ||||
|       sizein = sizeof(GLushort); | ||||
|       break; | ||||
|    case GL_SHORT: | ||||
|       sizein = sizeof(GLshort); | ||||
|       break; | ||||
|    case GL_UNSIGNED_INT: | ||||
|       sizein = sizeof(GLuint); | ||||
|       break; | ||||
|    case GL_INT: | ||||
|       sizein = sizeof(GLint); | ||||
|       break; | ||||
|    case GL_FLOAT: | ||||
|       sizein = sizeof(GLfloat); | ||||
|       break; | ||||
|    case GL_BITMAP: | ||||
|       /* not implemented yet */ | ||||
|    default: | ||||
|       return GL_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|    /* Determine bytes per output datum */ | ||||
|    switch (typeout) { | ||||
|    case GL_UNSIGNED_BYTE: | ||||
|       sizeout = sizeof(GLubyte); | ||||
|       break; | ||||
|    case GL_BYTE: | ||||
|       sizeout = sizeof(GLbyte); | ||||
|       break; | ||||
|    case GL_UNSIGNED_SHORT: | ||||
|       sizeout = sizeof(GLushort); | ||||
|       break; | ||||
|    case GL_SHORT: | ||||
|       sizeout = sizeof(GLshort); | ||||
|       break; | ||||
|    case GL_UNSIGNED_INT: | ||||
|       sizeout = sizeof(GLuint); | ||||
|       break; | ||||
|    case GL_INT: | ||||
|       sizeout = sizeof(GLint); | ||||
|       break; | ||||
|    case GL_FLOAT: | ||||
|       sizeout = sizeof(GLfloat); | ||||
|       break; | ||||
|    case GL_BITMAP: | ||||
|       /* not implemented yet */ | ||||
|    default: | ||||
|       return GL_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|    /* Get glPixelStore state */ | ||||
|    glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f; | ||||
|    glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f; | ||||
|    glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f; | ||||
|    glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f; | ||||
|    glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f; | ||||
|  | ||||
|    /* Allocate storage for intermediate images */ | ||||
|    tempin = (GLfloat *) malloc(widthin * heightin | ||||
| 			       * components * sizeof(GLfloat)); | ||||
|    if (!tempin) { | ||||
|       return GLU_OUT_OF_MEMORY; | ||||
|    } | ||||
|    tempout = (GLfloat *) malloc(widthout * heightout | ||||
| 				* components * sizeof(GLfloat)); | ||||
|    if (!tempout) { | ||||
|       free(tempin); | ||||
|       return GLU_OUT_OF_MEMORY; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    /* | ||||
|     * Unpack the pixel data and convert to floating point | ||||
|     */ | ||||
|  | ||||
|    if (unpackrowlength > 0) { | ||||
|       rowlen = unpackrowlength; | ||||
|    } | ||||
|    else { | ||||
|       rowlen = widthin; | ||||
|    } | ||||
|    if (sizein >= unpackalignment) { | ||||
|       rowstride = components * rowlen; | ||||
|    } | ||||
|    else { | ||||
|       rowstride = unpackalignment / sizein | ||||
| 	 * CEILING(components * rowlen * sizein, unpackalignment); | ||||
|    } | ||||
|  | ||||
|    switch (typein) { | ||||
|    case GL_UNSIGNED_BYTE: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLubyte *ubptr = (GLubyte *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * ubptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_BYTE: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLbyte *bptr = (GLbyte *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * bptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_UNSIGNED_SHORT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLushort *usptr = (GLushort *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * usptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_SHORT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLshort *sptr = (GLshort *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * sptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_UNSIGNED_INT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLuint *uiptr = (GLuint *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * uiptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_INT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLint *iptr = (GLint *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = (GLfloat) * iptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_FLOAT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightin; i++) { | ||||
| 	 GLfloat *fptr = (GLfloat *) datain | ||||
| 	    + i * rowstride | ||||
| 	    + unpackskiprows * rowstride + unpackskippixels * components; | ||||
| 	 for (j = 0; j < widthin * components; j++) { | ||||
| 	    dummy(j, k); | ||||
| 	    tempin[k++] = *fptr++; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    default: | ||||
|       return GLU_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    /* | ||||
|     * Scale the image! | ||||
|     */ | ||||
|  | ||||
|    if (widthout > 1) | ||||
|       sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1); | ||||
|    else | ||||
|       sx = (GLfloat) (widthin - 1); | ||||
|    if (heightout > 1) | ||||
|       sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1); | ||||
|    else | ||||
|       sy = (GLfloat) (heightin - 1); | ||||
|  | ||||
| /*#define POINT_SAMPLE*/ | ||||
| #ifdef POINT_SAMPLE | ||||
|    for (i = 0; i < heightout; i++) { | ||||
|       GLint ii = i * sy; | ||||
|       for (j = 0; j < widthout; j++) { | ||||
| 	 GLint jj = j * sx; | ||||
|  | ||||
| 	 GLfloat *src = tempin + (ii * widthin + jj) * components; | ||||
| 	 GLfloat *dst = tempout + (i * widthout + j) * components; | ||||
|  | ||||
| 	 for (k = 0; k < components; k++) { | ||||
| 	    *dst++ = *src++; | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
| #else | ||||
|    if (sx < 1.0 && sy < 1.0) { | ||||
|       /* magnify both width and height:  use weighted sample of 4 pixels */ | ||||
|       GLint i0, i1, j0, j1; | ||||
|       GLfloat alpha, beta; | ||||
|       GLfloat *src00, *src01, *src10, *src11; | ||||
|       GLfloat s1, s2; | ||||
|       GLfloat *dst; | ||||
|  | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 i0 = i * sy; | ||||
| 	 i1 = i0 + 1; | ||||
| 	 if (i1 >= heightin) | ||||
| 	    i1 = heightin - 1; | ||||
| /*	 i1 = (i+1) * sy - EPSILON;*/ | ||||
| 	 alpha = i * sy - i0; | ||||
| 	 for (j = 0; j < widthout; j++) { | ||||
| 	    j0 = j * sx; | ||||
| 	    j1 = j0 + 1; | ||||
| 	    if (j1 >= widthin) | ||||
| 	       j1 = widthin - 1; | ||||
| /*	    j1 = (j+1) * sx - EPSILON; */ | ||||
| 	    beta = j * sx - j0; | ||||
|  | ||||
| 	    /* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */ | ||||
| 	    src00 = tempin + (i0 * widthin + j0) * components; | ||||
| 	    src01 = tempin + (i0 * widthin + j1) * components; | ||||
| 	    src10 = tempin + (i1 * widthin + j0) * components; | ||||
| 	    src11 = tempin + (i1 * widthin + j1) * components; | ||||
|  | ||||
| 	    dst = tempout + (i * widthout + j) * components; | ||||
|  | ||||
| 	    for (k = 0; k < components; k++) { | ||||
| 	       s1 = *src00++ * (1.0 - beta) + *src01++ * beta; | ||||
| 	       s2 = *src10++ * (1.0 - beta) + *src11++ * beta; | ||||
| 	       *dst++ = s1 * (1.0 - alpha) + s2 * alpha; | ||||
| 	    } | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* shrink width and/or height:  use an unweighted box filter */ | ||||
|       GLint i0, i1; | ||||
|       GLint j0, j1; | ||||
|       GLint ii, jj; | ||||
|       GLfloat sum, *dst; | ||||
|  | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 i0 = i * sy; | ||||
| 	 i1 = i0 + 1; | ||||
| 	 if (i1 >= heightin) | ||||
| 	    i1 = heightin - 1; | ||||
| /*	 i1 = (i+1) * sy - EPSILON; */ | ||||
| 	 for (j = 0; j < widthout; j++) { | ||||
| 	    j0 = j * sx; | ||||
| 	    j1 = j0 + 1; | ||||
| 	    if (j1 >= widthin) | ||||
| 	       j1 = widthin - 1; | ||||
| /*	    j1 = (j+1) * sx - EPSILON; */ | ||||
|  | ||||
| 	    dst = tempout + (i * widthout + j) * components; | ||||
|  | ||||
| 	    /* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */ | ||||
| 	    for (k = 0; k < components; k++) { | ||||
| 	       sum = 0.0; | ||||
| 	       for (ii = i0; ii <= i1; ii++) { | ||||
| 		  for (jj = j0; jj <= j1; jj++) { | ||||
| 		     sum += *(tempin + (ii * widthin + jj) * components + k); | ||||
| 		  } | ||||
| 	       } | ||||
| 	       sum /= (j1 - j0 + 1) * (i1 - i0 + 1); | ||||
| 	       *dst++ = sum; | ||||
| 	    } | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|    /* | ||||
|     * Return output image | ||||
|     */ | ||||
|  | ||||
|    if (packrowlength > 0) { | ||||
|       rowlen = packrowlength; | ||||
|    } | ||||
|    else { | ||||
|       rowlen = widthout; | ||||
|    } | ||||
|    if (sizeout >= packalignment) { | ||||
|       rowstride = components * rowlen; | ||||
|    } | ||||
|    else { | ||||
|       rowstride = packalignment / sizeout | ||||
| 	 * CEILING(components * rowlen * sizeout, packalignment); | ||||
|    } | ||||
|  | ||||
|    switch (typeout) { | ||||
|    case GL_UNSIGNED_BYTE: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLubyte *ubptr = (GLubyte *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *ubptr++ = (GLubyte) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_BYTE: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLbyte *bptr = (GLbyte *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *bptr++ = (GLbyte) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_UNSIGNED_SHORT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLushort *usptr = (GLushort *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *usptr++ = (GLushort) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_SHORT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLshort *sptr = (GLshort *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *sptr++ = (GLshort) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_UNSIGNED_INT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLuint *uiptr = (GLuint *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *uiptr++ = (GLuint) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_INT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLint *iptr = (GLint *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *iptr++ = (GLint) tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    case GL_FLOAT: | ||||
|       k = 0; | ||||
|       for (i = 0; i < heightout; i++) { | ||||
| 	 GLfloat *fptr = (GLfloat *) dataout | ||||
| 	    + i * rowstride | ||||
| 	    + packskiprows * rowstride + packskippixels * components; | ||||
| 	 for (j = 0; j < widthout * components; j++) { | ||||
| 	    dummy(j, k + i); | ||||
| 	    *fptr++ = tempout[k++]; | ||||
| 	 } | ||||
|       } | ||||
|       break; | ||||
|    default: | ||||
|       return GLU_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    /* free temporary image storage */ | ||||
|    free(tempin); | ||||
|    free(tempout); | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Return the largest k such that 2^k <= n. | ||||
|  */ | ||||
| static GLint | ||||
| ilog2(GLint n) | ||||
| { | ||||
|    GLint k; | ||||
|  | ||||
|    if (n <= 0) | ||||
|       return 0; | ||||
|    for (k = 0; n >>= 1; k++); | ||||
|    return k; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Find the value nearest to n which is also a power of two. | ||||
|  */ | ||||
| static GLint | ||||
| round2(GLint n) | ||||
| { | ||||
|    GLint m; | ||||
|  | ||||
|    for (m = 1; m < n; m *= 2); | ||||
|  | ||||
|    /* m>=n */ | ||||
|    if (m - n <= n - m / 2) { | ||||
|       return m; | ||||
|    } | ||||
|    else { | ||||
|       return m / 2; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Given an pixel format and datatype, return the number of bytes to | ||||
|  * store one pixel. | ||||
|  */ | ||||
| static GLint | ||||
| bytes_per_pixel(GLenum format, GLenum type) | ||||
| { | ||||
|    GLint n, m; | ||||
|  | ||||
|    switch (format) { | ||||
|    case GL_COLOR_INDEX: | ||||
|    case GL_STENCIL_INDEX: | ||||
|    case GL_DEPTH_COMPONENT: | ||||
|    case GL_RED: | ||||
|    case GL_GREEN: | ||||
|    case GL_BLUE: | ||||
|    case GL_ALPHA: | ||||
|    case GL_LUMINANCE: | ||||
|       n = 1; | ||||
|       break; | ||||
|    case GL_LUMINANCE_ALPHA: | ||||
|       n = 2; | ||||
|       break; | ||||
|    case GL_RGB: | ||||
|    case GL_BGR: | ||||
|       n = 3; | ||||
|       break; | ||||
|    case GL_RGBA: | ||||
|    case GL_BGRA: | ||||
| #ifdef GL_EXT_abgr | ||||
|    case GL_ABGR_EXT: | ||||
| #endif | ||||
|       n = 4; | ||||
|       break; | ||||
|    default: | ||||
|       n = 0; | ||||
|    } | ||||
|  | ||||
|    switch (type) { | ||||
|    case GL_UNSIGNED_BYTE: | ||||
|       m = sizeof(GLubyte); | ||||
|       break; | ||||
|    case GL_BYTE: | ||||
|       m = sizeof(GLbyte); | ||||
|       break; | ||||
|    case GL_BITMAP: | ||||
|       m = 1; | ||||
|       break; | ||||
|    case GL_UNSIGNED_SHORT: | ||||
|       m = sizeof(GLushort); | ||||
|       break; | ||||
|    case GL_SHORT: | ||||
|       m = sizeof(GLshort); | ||||
|       break; | ||||
|    case GL_UNSIGNED_INT: | ||||
|       m = sizeof(GLuint); | ||||
|       break; | ||||
|    case GL_INT: | ||||
|       m = sizeof(GLint); | ||||
|       break; | ||||
|    case GL_FLOAT: | ||||
|       m = sizeof(GLfloat); | ||||
|       break; | ||||
|    default: | ||||
|       m = 0; | ||||
|    } | ||||
|  | ||||
|    return n * m; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * WARNING: This function isn't finished and has never been tested!!!! | ||||
|  */ | ||||
| GLint GLAPIENTRY | ||||
| gluBuild1DMipmaps(GLenum target, GLint components, | ||||
| 		  GLsizei width, GLenum format, GLenum type, const void *data) | ||||
| { | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| GLint GLAPIENTRY | ||||
| gluBuild2DMipmaps(GLenum target, GLint components, | ||||
| 		  GLsizei width, GLsizei height, GLenum format, | ||||
| 		  GLenum type, const void *data) | ||||
| { | ||||
|    GLint w, h; | ||||
|    GLint maxsize; | ||||
|    void *image, *newimage; | ||||
|    GLint neww, newh, level, bpp; | ||||
|    int error; | ||||
|    GLboolean done; | ||||
|    GLint retval = 0; | ||||
|    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels; | ||||
|    GLint packrowlength, packalignment, packskiprows, packskippixels; | ||||
|    GLfloat f; | ||||
|  | ||||
|    if (width < 1 || height < 1) | ||||
|       return GLU_INVALID_VALUE; | ||||
|  | ||||
|    glGetFloatv(GL_MAX_TEXTURE_SIZE, &f); maxsize = (int)f; | ||||
|  | ||||
|    w = round2(width); | ||||
|    if (w > maxsize) { | ||||
|       w = maxsize; | ||||
|    } | ||||
|    h = round2(height); | ||||
|    if (h > maxsize) { | ||||
|       h = maxsize; | ||||
|    } | ||||
|  | ||||
|    bpp = bytes_per_pixel(format, type); | ||||
|    if (bpp == 0) { | ||||
|       /* probably a bad format or type enum */ | ||||
|       return GLU_INVALID_ENUM; | ||||
|    } | ||||
|  | ||||
|    /* Get current glPixelStore values */ | ||||
|    glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f; | ||||
|    glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f; | ||||
|    glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f; | ||||
|    glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f; | ||||
|    glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f; | ||||
|    glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f; | ||||
|  | ||||
|    /* set pixel packing */ | ||||
|    glPixelStorei(GL_PACK_ROW_LENGTH, 0); | ||||
|    glPixelStorei(GL_PACK_ALIGNMENT, 1); | ||||
|    glPixelStorei(GL_PACK_SKIP_ROWS, 0); | ||||
|    glPixelStorei(GL_PACK_SKIP_PIXELS, 0); | ||||
|  | ||||
|    done = GL_FALSE; | ||||
|  | ||||
|    if (w != width || h != height) { | ||||
|       /* must rescale image to get "top" mipmap texture image */ | ||||
|       image = malloc((w + 4) * h * bpp); | ||||
|       if (!image) { | ||||
| 	 return GLU_OUT_OF_MEMORY; | ||||
|       } | ||||
|       error = gluScaleImage(format, width, height, type, data, | ||||
| 			    w, h, type, image); | ||||
|       if (error) { | ||||
| 	 retval = error; | ||||
| 	 done = GL_TRUE; | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       image = (void *) data; | ||||
|    } | ||||
|  | ||||
|    level = 0; | ||||
|    while (!done) { | ||||
|       if (image != data) { | ||||
| 	 /* set pixel unpacking */ | ||||
| 	 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||||
| 	 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
| 	 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | ||||
| 	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | ||||
|       } | ||||
|  | ||||
|       glTexImage2D(target, level, components, w, h, 0, format, type, image); | ||||
|  | ||||
|       if (w == 1 && h == 1) | ||||
| 	 break; | ||||
|  | ||||
|       neww = (w < 2) ? 1 : w / 2; | ||||
|       newh = (h < 2) ? 1 : h / 2; | ||||
|       newimage = malloc((neww + 4) * newh * bpp); | ||||
|       if (!newimage) { | ||||
| 	 return GLU_OUT_OF_MEMORY; | ||||
|       } | ||||
|  | ||||
|       error = gluScaleImage(format, w, h, type, image, | ||||
| 			    neww, newh, type, newimage); | ||||
|       if (error) { | ||||
| 	 retval = error; | ||||
| 	 done = GL_TRUE; | ||||
|       } | ||||
|  | ||||
|       if (image != data) { | ||||
| 	 free(image); | ||||
|       } | ||||
|       image = newimage; | ||||
|  | ||||
|       w = neww; | ||||
|       h = newh; | ||||
|       level++; | ||||
|    } | ||||
|  | ||||
|    if (image != data) { | ||||
|       free(image); | ||||
|    } | ||||
|  | ||||
|    /* Restore original glPixelStore state */ | ||||
|    glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength); | ||||
|    glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment); | ||||
|    glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows); | ||||
|    glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels); | ||||
|    glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength); | ||||
|    glPixelStorei(GL_PACK_ALIGNMENT, packalignment); | ||||
|    glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows); | ||||
|    glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels); | ||||
|  | ||||
|    return retval; | ||||
| } | ||||
							
								
								
									
										158
									
								
								src/glu/mini/nurbs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/glu/mini/nurbs.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| /* $Id: nurbs.c,v 1.1.2.1 2003/03/21 13:02:13 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it) | ||||
|  * See README2 for more info. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include "gluP.h" | ||||
| #include "nurbs.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| void | ||||
| call_user_error(GLUnurbsObj * nobj, GLenum error) | ||||
| { | ||||
|    nobj->error = error; | ||||
|    if (nobj->error_callback != NULL) { | ||||
|       (*(nobj->error_callback)) (error); | ||||
|    } | ||||
|    else { | ||||
|       printf("NURBS error %d %s\n", error, (char *) gluErrorString(error)); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| GLUnurbsObj *GLAPIENTRY | ||||
| gluNewNurbsRenderer(void) | ||||
| { | ||||
|    GLUnurbsObj *n; | ||||
|    GLfloat tmp_viewport[4]; | ||||
|    GLint i, j; | ||||
|  | ||||
|    n = (GLUnurbsObj *) malloc(sizeof(GLUnurbsObj)); | ||||
|    return n; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluDeleteNurbsRenderer(GLUnurbsObj * nobj) | ||||
| { | ||||
|    if (nobj) { | ||||
|       free(nobj); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluLoadSamplingMatrices(GLUnurbsObj * nobj, | ||||
| 			const GLfloat modelMatrix[16], | ||||
| 			const GLfloat projMatrix[16], const GLint viewport[4]) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat value) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluGetNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat * value) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluBeginCurve(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluEndCurve(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot, | ||||
| 	      GLint stride, GLfloat * ctlarray, GLint order, GLenum type) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluBeginSurface(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluEndSurface(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluNurbsSurface(GLUnurbsObj * nobj, | ||||
| 		GLint sknot_count, GLfloat * sknot, | ||||
| 		GLint tknot_count, GLfloat * tknot, | ||||
| 		GLint s_stride, GLint t_stride, | ||||
| 		GLfloat * ctrlarray, GLint sorder, GLint torder, GLenum type) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluNurbsCallback(GLUnurbsObj * nobj, GLenum which, void (GLCALLBACK * fn) ()) | ||||
| { | ||||
| } | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluBeginTrim(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluPwlCurve(GLUnurbsObj * nobj, GLint count, GLfloat * array, GLint stride, | ||||
| 	    GLenum type) | ||||
| { | ||||
| } | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluEndTrim(GLUnurbsObj * nobj) | ||||
| { | ||||
| } | ||||
							
								
								
									
										253
									
								
								src/glu/mini/nurbs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/glu/mini/nurbs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,253 @@ | ||||
| /* $Id: nurbs.h,v 1.1.2.1 2003/03/21 13:02:14 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it) | ||||
|  * See README2 for more info. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef NURBS_H | ||||
| #define NURBS_H | ||||
|  | ||||
|  | ||||
| #define EPSILON 1e-06		/* epsilon for double precision compares */ | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|    GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM, | ||||
|    GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE | ||||
| } | ||||
| GLU_nurbs_enum; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|    GLU_TRIM_NURBS, GLU_TRIM_PWL | ||||
| } | ||||
| GLU_trim_enum; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLint sknot_count; | ||||
|    GLfloat *sknot; | ||||
|    GLint tknot_count; | ||||
|    GLfloat *tknot; | ||||
|    GLint s_stride; | ||||
|    GLint t_stride; | ||||
|    GLfloat *ctrlarray; | ||||
|    GLint sorder; | ||||
|    GLint torder; | ||||
|    GLint dim; | ||||
|    GLenum type; | ||||
| } | ||||
| surface_attribs; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    surface_attribs geom; | ||||
|    surface_attribs color; | ||||
|    surface_attribs texture; | ||||
|    surface_attribs normal; | ||||
| } | ||||
| nurbs_surface; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLint knot_count; | ||||
|    GLfloat *knot; | ||||
|    GLint stride; | ||||
|    GLfloat *ctrlarray; | ||||
|    GLint order; | ||||
|    GLint dim; | ||||
|    GLenum type; | ||||
| } | ||||
| curve_attribs; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLint pt_count; | ||||
|    GLfloat *ctrlarray; | ||||
|    GLint stride; | ||||
|    GLint dim; | ||||
|    GLenum type; | ||||
| } | ||||
| pwl_curve_attribs; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    curve_attribs geom; | ||||
|    curve_attribs color; | ||||
|    curve_attribs texture; | ||||
|    curve_attribs normal; | ||||
| } | ||||
| nurbs_curve; | ||||
|  | ||||
| typedef struct trim_list_str | ||||
| { | ||||
|    GLU_trim_enum trim_type; | ||||
|    union | ||||
|    { | ||||
|       pwl_curve_attribs pwl_curve; | ||||
|       curve_attribs nurbs_curve; | ||||
|    } | ||||
|    curve; | ||||
|    struct trim_list_str *next; | ||||
| } | ||||
| trim_list; | ||||
|  | ||||
| typedef struct seg_trim_str | ||||
| { | ||||
|    GLfloat *points; | ||||
|    GLint pt_cnt, seg_array_len; | ||||
|    struct seg_trim_str *next; | ||||
| } | ||||
| trim_segments; | ||||
|  | ||||
| typedef struct nurbs_trim_str | ||||
| { | ||||
|    trim_list *trim_loop; | ||||
|    trim_segments *segments; | ||||
|    struct nurbs_trim_str *next; | ||||
| } | ||||
| nurbs_trim; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLfloat model[16], proj[16], viewport[4]; | ||||
| } | ||||
| culling_and_sampling_str; | ||||
|  | ||||
| struct GLUnurbs | ||||
| { | ||||
|    GLboolean culling; | ||||
|    GLenum error; | ||||
|    void (GLCALLBACK * error_callback) (GLenum err); | ||||
|    GLenum display_mode; | ||||
|    GLU_nurbs_enum nurbs_type; | ||||
|    GLboolean auto_load_matrix; | ||||
|      culling_and_sampling_str sampling_matrices; | ||||
|    GLenum sampling_method; | ||||
|    GLfloat sampling_tolerance; | ||||
|    GLfloat parametric_tolerance; | ||||
|    GLint u_step, v_step; | ||||
|    nurbs_surface surface; | ||||
|    nurbs_curve curve; | ||||
|    nurbs_trim *trim; | ||||
| }; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLfloat *knot; | ||||
|    GLint nknots; | ||||
|    GLfloat *unified_knot; | ||||
|    GLint unified_nknots; | ||||
|    GLint order; | ||||
|    GLint t_min, t_max; | ||||
|    GLint delta_nknots; | ||||
|    GLboolean open_at_begin, open_at_end; | ||||
|    GLfloat *new_knot; | ||||
|    GLfloat *alpha; | ||||
| } | ||||
| knot_str_type; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|    GLfloat *geom_ctrl; | ||||
|    GLint geom_s_stride, geom_t_stride; | ||||
|    GLfloat **geom_offsets; | ||||
|    GLint geom_s_pt_cnt, geom_t_pt_cnt; | ||||
|    GLfloat *color_ctrl; | ||||
|    GLint color_s_stride, color_t_stride; | ||||
|    GLfloat **color_offsets; | ||||
|    GLint color_s_pt_cnt, color_t_pt_cnt; | ||||
|    GLfloat *normal_ctrl; | ||||
|    GLint normal_s_stride, normal_t_stride; | ||||
|    GLfloat **normal_offsets; | ||||
|    GLint normal_s_pt_cnt, normal_t_pt_cnt; | ||||
|    GLfloat *texture_ctrl; | ||||
|    GLint texture_s_stride, texture_t_stride; | ||||
|    GLfloat **texture_offsets; | ||||
|    GLint texture_s_pt_cnt, texture_t_pt_cnt; | ||||
|    GLint s_bezier_cnt, t_bezier_cnt; | ||||
| } | ||||
| new_ctrl_type; | ||||
|  | ||||
| extern void call_user_error(GLUnurbsObj * nobj, GLenum error); | ||||
|  | ||||
| extern GLenum test_knot(GLint nknots, GLfloat * knot, GLint order); | ||||
|  | ||||
| extern GLenum explode_knot(knot_str_type * the_knot); | ||||
|  | ||||
| extern GLenum calc_alphas(knot_str_type * the_knot); | ||||
|  | ||||
| extern GLenum calc_new_ctrl_pts(GLfloat * ctrl, GLint stride, | ||||
| 				knot_str_type * the_knot, GLint dim, | ||||
| 				GLfloat ** new_ctrl, GLint * ncontrol); | ||||
|  | ||||
| extern GLenum glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * new_ctrl, | ||||
| 				  GLint n_ctrl, GLint order, GLint dim, | ||||
| 				  GLint ** factors); | ||||
|  | ||||
| extern GLenum glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, | ||||
| 				 int **sfactors, GLint ** tfactors); | ||||
|  | ||||
| extern GLenum glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, | ||||
| 				 int **sfactors, GLint ** tfactors); | ||||
|  | ||||
| extern GLenum glu_do_sampling_param_3D(GLUnurbsObj * nobj, | ||||
| 				       new_ctrl_type * new_ctrl, | ||||
| 				       int **sfactors, GLint ** tfactors); | ||||
|  | ||||
| extern GLboolean fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * ctrl, | ||||
| 				      GLint n_ctrl, GLint stride, GLint dim); | ||||
|  | ||||
| extern GLboolean fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * ctrl, | ||||
| 				      GLint s_n_ctrl, GLint t_n_ctrl, | ||||
| 				      GLint s_stride, GLint t_stride, | ||||
| 				      GLint dim); | ||||
|  | ||||
| extern void do_nurbs_curve(GLUnurbsObj * nobj); | ||||
|  | ||||
| extern void do_nurbs_surface(GLUnurbsObj * nobj); | ||||
|  | ||||
| extern GLenum patch_trimming(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, | ||||
| 			     GLint * sfactors, GLint * tfactors); | ||||
|  | ||||
| extern void collect_unified_knot(knot_str_type * dest, knot_str_type * src, | ||||
| 				 GLfloat maximal_min_knot, | ||||
| 				 GLfloat minimal_max_knot); | ||||
|  | ||||
| extern GLenum select_knot_working_range(GLUnurbsObj * nobj, | ||||
| 					knot_str_type * geom_knot, | ||||
| 					knot_str_type * color_knot, | ||||
| 					knot_str_type * normal_knot, | ||||
| 					knot_str_type * texture_knot); | ||||
|  | ||||
| extern void free_unified_knots(knot_str_type * geom_knot, | ||||
| 			       knot_str_type * color_knot, | ||||
| 			       knot_str_type * normal_knot, | ||||
| 			       knot_str_type * texture_knot); | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										133
									
								
								src/glu/mini/nurbscrv.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/glu/mini/nurbscrv.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| /* $Id: nurbscrv.c,v 1.1.2.1 2003/03/21 13:02:16 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it) | ||||
|  * See README2 for more info. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| #include "gluP.h" | ||||
| #include "nurbs.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /* main NURBS curve procedure */ | ||||
| void | ||||
| do_nurbs_curve(GLUnurbsObj * nobj) | ||||
| { | ||||
|    GLint geom_order, color_order = 0, normal_order = 0, texture_order = 0; | ||||
|    GLenum geom_type; | ||||
|    GLint n_ctrl; | ||||
|    GLfloat *new_geom_ctrl, *new_color_ctrl, *new_normal_ctrl, | ||||
|       *new_texture_ctrl; | ||||
|    GLfloat *geom_ctrl = 0, *color_ctrl = 0, *normal_ctrl = 0, *texture_ctrl = 0; | ||||
|    GLint *factors; | ||||
|    GLint i, j; | ||||
|    GLint geom_dim, color_dim = 0, normal_dim = 0, texture_dim = 0; | ||||
|  | ||||
|    /* test the user supplied data */ | ||||
|    if (test_nurbs_curves(nobj) != GLU_NO_ERROR) | ||||
|       return; | ||||
|  | ||||
|    if (convert_curves(nobj, &new_geom_ctrl, &n_ctrl, &new_color_ctrl, | ||||
| 		      &new_normal_ctrl, &new_texture_ctrl) != GLU_NO_ERROR) | ||||
|       return; | ||||
|  | ||||
|    geom_order = nobj->curve.geom.order; | ||||
|    geom_type = nobj->curve.geom.type; | ||||
|    geom_dim = nobj->curve.geom.dim; | ||||
|  | ||||
|    if (glu_do_sampling_crv(nobj, new_geom_ctrl, n_ctrl, geom_order, geom_dim, | ||||
| 			   &factors) != GLU_NO_ERROR) { | ||||
|       free(new_geom_ctrl); | ||||
|       if (new_color_ctrl) | ||||
| 	 free(new_color_ctrl); | ||||
|       if (new_normal_ctrl) | ||||
| 	 free(new_normal_ctrl); | ||||
|       if (new_texture_ctrl) | ||||
| 	 free(new_texture_ctrl); | ||||
|       return; | ||||
|    } | ||||
|    glEnable(geom_type); | ||||
|    if (new_color_ctrl) { | ||||
|       glEnable(nobj->curve.color.type); | ||||
|       color_dim = nobj->curve.color.dim; | ||||
|       color_ctrl = new_color_ctrl; | ||||
|       color_order = nobj->curve.color.order; | ||||
|    } | ||||
|    if (new_normal_ctrl) { | ||||
|       glEnable(nobj->curve.normal.type); | ||||
|       normal_dim = nobj->curve.normal.dim; | ||||
|       normal_ctrl = new_normal_ctrl; | ||||
|       normal_order = nobj->curve.normal.order; | ||||
|    } | ||||
|    if (new_texture_ctrl) { | ||||
|       glEnable(nobj->curve.texture.type); | ||||
|       texture_dim = nobj->curve.texture.dim; | ||||
|       texture_ctrl = new_texture_ctrl; | ||||
|       texture_order = nobj->curve.texture.order; | ||||
|    } | ||||
|    for (i = 0, j = 0, geom_ctrl = new_geom_ctrl; | ||||
| 	i < n_ctrl; i += geom_order, j++, geom_ctrl += geom_order * geom_dim) { | ||||
|       if (fine_culling_test_2D | ||||
| 	  (nobj, geom_ctrl, geom_order, geom_dim, geom_dim)) { | ||||
| 	 color_ctrl += color_order * color_dim; | ||||
| 	 normal_ctrl += normal_order * normal_dim; | ||||
| 	 texture_ctrl += texture_order * texture_dim; | ||||
| 	 continue; | ||||
|       } | ||||
|       glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl); | ||||
|       if (new_color_ctrl) { | ||||
| 	 glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim, | ||||
| 		 color_order, color_ctrl); | ||||
| 	 color_ctrl += color_order * color_dim; | ||||
|       } | ||||
|       if (new_normal_ctrl) { | ||||
| 	 glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim, | ||||
| 		 normal_order, normal_ctrl); | ||||
| 	 normal_ctrl += normal_order * normal_dim; | ||||
|       } | ||||
|       if (new_texture_ctrl) { | ||||
| 	 glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim, | ||||
| 		 texture_order, texture_ctrl); | ||||
| 	 texture_ctrl += texture_order * texture_dim; | ||||
|       } | ||||
|       glMapGrid1f(factors[j], 0.0, 1.0); | ||||
|       glEvalMesh1(GL_LINE, 0, factors[j]); | ||||
|    } | ||||
|    free(new_geom_ctrl); | ||||
|    free(factors); | ||||
|    if (new_color_ctrl) | ||||
|       free(new_color_ctrl); | ||||
|    if (new_normal_ctrl) | ||||
|       free(new_normal_ctrl); | ||||
|    if (new_texture_ctrl) | ||||
|       free(new_texture_ctrl); | ||||
| } | ||||
							
								
								
									
										938
									
								
								src/glu/mini/polytest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										938
									
								
								src/glu/mini/polytest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,938 @@ | ||||
| /* $Id: polytest.c,v 1.1.2.1 2003/03/21 13:02:17 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file is part of the polygon tesselation code contributed by | ||||
|  * Bogdan Sikorski | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| #include "gluP.h" | ||||
| #include "tess.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLenum store_polygon_as_contour(GLUtriangulatorObj *); | ||||
| static void free_current_polygon(tess_polygon *); | ||||
| static void prepare_projection_info(GLUtriangulatorObj *); | ||||
| static GLdouble twice_the_polygon_area(tess_vertex *, tess_vertex *); | ||||
| static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *); | ||||
| void tess_find_contour_hierarchies(GLUtriangulatorObj *); | ||||
| static GLenum test_for_overlapping_contours(GLUtriangulatorObj *); | ||||
| static GLenum contours_overlap(tess_contour *, tess_polygon *); | ||||
| static GLenum is_contour_contained_in(tess_contour *, tess_contour *); | ||||
| static void add_new_exterior(GLUtriangulatorObj *, tess_contour *); | ||||
| static void add_new_interior(GLUtriangulatorObj *, tess_contour *, | ||||
| 			     tess_contour *); | ||||
| static void add_interior_with_hierarchy_check(GLUtriangulatorObj *, | ||||
| 					      tess_contour *, tess_contour *); | ||||
| static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *, | ||||
| 					       tess_contour *, | ||||
| 					       tess_contour *); | ||||
| static GLboolean point_in_polygon(tess_contour *, GLdouble, GLdouble); | ||||
| static void shift_interior_to_exterior(GLUtriangulatorObj *, tess_contour *); | ||||
| static void add_exterior_with_check(GLUtriangulatorObj *, tess_contour *, | ||||
| 				    tess_contour *); | ||||
| static GLenum cut_out_hole(GLUtriangulatorObj *, tess_contour *, | ||||
| 			   tess_contour *); | ||||
| static GLenum merge_hole_with_contour(GLUtriangulatorObj *, | ||||
| 				      tess_contour *, tess_contour *, | ||||
| 				      tess_vertex *, tess_vertex *); | ||||
|  | ||||
| static GLenum | ||||
| find_normal(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_vertex *va, *vb, *vc; | ||||
|    GLdouble A, B, C; | ||||
|    GLdouble A0, A1, A2, B0, B1, B2; | ||||
|  | ||||
|    va = polygon->vertices; | ||||
|    vb = va->next; | ||||
|    A0 = vb->location[0] - va->location[0]; | ||||
|    A1 = vb->location[1] - va->location[1]; | ||||
|    A2 = vb->location[2] - va->location[2]; | ||||
|    for (vc = vb->next; vc != va; vc = vc->next) { | ||||
|       B0 = vc->location[0] - va->location[0]; | ||||
|       B1 = vc->location[1] - va->location[1]; | ||||
|       B2 = vc->location[2] - va->location[2]; | ||||
|       A = A1 * B2 - A2 * B1; | ||||
|       B = A2 * B0 - A0 * B2; | ||||
|       C = A0 * B1 - A1 * B0; | ||||
|       if (fabs(A) > EPSILON || fabs(B) > EPSILON || fabs(C) > EPSILON) { | ||||
| 	 polygon->A = A; | ||||
| 	 polygon->B = B; | ||||
| 	 polygon->C = C; | ||||
| 	 polygon->D = | ||||
| 	    -A * va->location[0] - B * va->location[1] - C * va->location[2]; | ||||
| 	 return GLU_NO_ERROR; | ||||
|       } | ||||
|    } | ||||
|    tess_call_user_error(tobj, GLU_TESS_ERROR7); | ||||
|    return GLU_ERROR; | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_test_polygon(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|  | ||||
|    /* any vertices defined? */ | ||||
|    if (polygon->vertex_cnt < 3) { | ||||
|       free_current_polygon(polygon); | ||||
|       return; | ||||
|    } | ||||
|    /* wrap pointers */ | ||||
|    polygon->last_vertex->next = polygon->vertices; | ||||
|    polygon->vertices->previous = polygon->last_vertex; | ||||
|    /* determine the normal */ | ||||
|    if (find_normal(tobj) == GLU_ERROR) | ||||
|       return; | ||||
|    /* compare the normals of previously defined contours and this one */ | ||||
|    /* first contour define ? */ | ||||
|    if (tobj->contours == NULL) { | ||||
|       tobj->A = polygon->A; | ||||
|       tobj->B = polygon->B; | ||||
|       tobj->C = polygon->C; | ||||
|       tobj->D = polygon->D; | ||||
|       /* determine the best projection to use */ | ||||
|       if (fabs(polygon->A) > fabs(polygon->B)) | ||||
| 	 if (fabs(polygon->A) > fabs(polygon->C)) | ||||
| 	    tobj->projection = OYZ; | ||||
| 	 else | ||||
| 	    tobj->projection = OXY; | ||||
|       else if (fabs(polygon->B) > fabs(polygon->C)) | ||||
| 	 tobj->projection = OXZ; | ||||
|       else | ||||
| 	 tobj->projection = OXY; | ||||
|    } | ||||
|    else { | ||||
|       GLdouble a[3], b[3]; | ||||
|       tess_vertex *vertex = polygon->vertices; | ||||
|  | ||||
|       a[0] = tobj->A; | ||||
|       a[1] = tobj->B; | ||||
|       a[2] = tobj->C; | ||||
|       b[0] = polygon->A; | ||||
|       b[1] = polygon->B; | ||||
|       b[2] = polygon->C; | ||||
|  | ||||
|       /* compare the normals */ | ||||
|       if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON || | ||||
| 	  fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON || | ||||
| 	  fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) { | ||||
| 	 /* not coplanar */ | ||||
| 	 tess_call_user_error(tobj, GLU_TESS_ERROR9); | ||||
| 	 return; | ||||
|       } | ||||
|       /* the normals are parallel - test for plane equation */ | ||||
|       if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] + | ||||
| 	       a[2] * vertex->location[2] + tobj->D) > EPSILON) { | ||||
| 	 /* not the same plane */ | ||||
| 	 tess_call_user_error(tobj, GLU_TESS_ERROR9); | ||||
| 	 return; | ||||
|       } | ||||
|    } | ||||
|    prepare_projection_info(tobj); | ||||
|    if (verify_edge_vertex_intersections(tobj) == GLU_ERROR) | ||||
|       return; | ||||
|    if (test_for_overlapping_contours(tobj) == GLU_ERROR) | ||||
|       return; | ||||
|    if (store_polygon_as_contour(tobj) == GLU_ERROR) | ||||
|       return; | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| test_for_overlapping_contours(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_contour *contour; | ||||
|    tess_polygon *polygon; | ||||
|  | ||||
|    polygon = tobj->current_polygon; | ||||
|    for (contour = tobj->contours; contour != NULL; contour = contour->next) | ||||
|       if (contours_overlap(contour, polygon) != GLU_NO_ERROR) { | ||||
| 	 tess_call_user_error(tobj, GLU_TESS_ERROR5); | ||||
| 	 return GLU_ERROR; | ||||
|       } | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| store_polygon_as_contour(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_contour *contour = tobj->contours; | ||||
|  | ||||
|    /* the first contour defined */ | ||||
|    if (contour == NULL) { | ||||
|       if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) { | ||||
| 	 tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
| 	 free_current_polygon(polygon); | ||||
| 	 return GLU_ERROR; | ||||
|       } | ||||
|       tobj->contours = tobj->last_contour = contour; | ||||
|       contour->next = contour->previous = NULL; | ||||
|    } | ||||
|    else { | ||||
|       if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) { | ||||
| 	 tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
| 	 free_current_polygon(polygon); | ||||
| 	 return GLU_ERROR; | ||||
|       } | ||||
|       contour->previous = tobj->last_contour; | ||||
|       tobj->last_contour->next = contour; | ||||
|       tobj->last_contour = contour; | ||||
|       contour->next = NULL; | ||||
|    } | ||||
|    /* mark all vertices in new contour as not special */ | ||||
|    /* and all are boundary edges */ | ||||
|    { | ||||
|       tess_vertex *vertex; | ||||
|       GLuint vertex_cnt, i; | ||||
|  | ||||
|       for (vertex = polygon->vertices, i = 0, vertex_cnt = | ||||
| 	   polygon->vertex_cnt; i < vertex_cnt; vertex = vertex->next, i++) { | ||||
| 	 vertex->shadow_vertex = NULL; | ||||
| 	 vertex->edge_flag = GL_TRUE; | ||||
|       } | ||||
|    } | ||||
|    contour->vertex_cnt = polygon->vertex_cnt; | ||||
|    contour->area = polygon->area; | ||||
|    contour->orientation = polygon->orientation; | ||||
|    contour->type = GLU_UNKNOWN; | ||||
|    contour->vertices = polygon->vertices; | ||||
|    contour->last_vertex = polygon->last_vertex; | ||||
|    polygon->vertices = polygon->last_vertex = NULL; | ||||
|    polygon->vertex_cnt = 0; | ||||
|    ++(tobj->contour_cnt); | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static void | ||||
| free_current_polygon(tess_polygon * polygon) | ||||
| { | ||||
|    tess_vertex *vertex, *vertex_tmp; | ||||
|    GLuint i; | ||||
|  | ||||
|    /* free current_polygon structures */ | ||||
|    for (vertex = polygon->vertices, i = 0; i < polygon->vertex_cnt; i++) { | ||||
|       vertex_tmp = vertex->next; | ||||
|       free(vertex); | ||||
|       vertex = vertex_tmp; | ||||
|    } | ||||
|    polygon->vertices = polygon->last_vertex = NULL; | ||||
|    polygon->vertex_cnt = 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| prepare_projection_info(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_vertex *vertex, *last_vertex_ptr; | ||||
|    GLdouble area; | ||||
|  | ||||
|    last_vertex_ptr = polygon->last_vertex; | ||||
|    switch (tobj->projection) { | ||||
|    case OXY: | ||||
|       for (vertex = polygon->vertices; vertex != last_vertex_ptr; | ||||
| 	   vertex = vertex->next) { | ||||
| 	 vertex->x = vertex->location[0]; | ||||
| 	 vertex->y = vertex->location[1]; | ||||
|       } | ||||
|       last_vertex_ptr->x = last_vertex_ptr->location[0]; | ||||
|       last_vertex_ptr->y = last_vertex_ptr->location[1]; | ||||
|       break; | ||||
|    case OXZ: | ||||
|       for (vertex = polygon->vertices; vertex != last_vertex_ptr; | ||||
| 	   vertex = vertex->next) { | ||||
| 	 vertex->x = vertex->location[0]; | ||||
| 	 vertex->y = vertex->location[2]; | ||||
|       } | ||||
|       last_vertex_ptr->x = last_vertex_ptr->location[0]; | ||||
|       last_vertex_ptr->y = last_vertex_ptr->location[2]; | ||||
|       break; | ||||
|    case OYZ: | ||||
|       for (vertex = polygon->vertices; vertex != last_vertex_ptr; | ||||
| 	   vertex = vertex->next) { | ||||
| 	 vertex->x = vertex->location[1]; | ||||
| 	 vertex->y = vertex->location[2]; | ||||
|       } | ||||
|       last_vertex_ptr->x = last_vertex_ptr->location[1]; | ||||
|       last_vertex_ptr->y = last_vertex_ptr->location[2]; | ||||
|       break; | ||||
|    } | ||||
|    area = twice_the_polygon_area(polygon->vertices, polygon->last_vertex); | ||||
|    if (area >= 0.0) { | ||||
|       polygon->orientation = GLU_CCW; | ||||
|       polygon->area = area; | ||||
|    } | ||||
|    else { | ||||
|       polygon->orientation = GLU_CW; | ||||
|       polygon->area = -area; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static GLdouble | ||||
| twice_the_polygon_area(tess_vertex * vertex, tess_vertex * last_vertex) | ||||
| { | ||||
|    tess_vertex *next; | ||||
|    GLdouble area, x, y; | ||||
|  | ||||
|    area = 0.0; | ||||
|    x = vertex->x; | ||||
|    y = vertex->y; | ||||
|    vertex = vertex->next; | ||||
|    for (; vertex != last_vertex; vertex = vertex->next) { | ||||
|       next = vertex->next; | ||||
|       area += | ||||
| 	 (vertex->x - x) * (next->y - y) - (vertex->y - y) * (next->x - x); | ||||
|    } | ||||
|    return area; | ||||
| } | ||||
|  | ||||
| /* test if edges ab and cd intersect */ | ||||
| /* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */ | ||||
| /* else if adjacent return GLU_TESS_ERROR4 */ | ||||
| static GLenum | ||||
| edge_edge_intersect(tess_vertex * a, | ||||
| 		    tess_vertex * b, tess_vertex * c, tess_vertex * d) | ||||
| { | ||||
|    GLdouble denom, r, s; | ||||
|    GLdouble xba, ydc, yba, xdc, yac, xac; | ||||
|  | ||||
|    xba = b->x - a->x; | ||||
|    yba = b->y - a->y; | ||||
|    xdc = d->x - c->x; | ||||
|    ydc = d->y - c->y; | ||||
|    xac = a->x - c->x; | ||||
|    yac = a->y - c->y; | ||||
|    denom = xba * ydc - yba * xdc; | ||||
|    r = yac * xdc - xac * ydc; | ||||
|    /* parallel? */ | ||||
|    if (fabs(denom) < EPSILON) { | ||||
|       if (fabs(r) < EPSILON) { | ||||
| 	 /* colinear */ | ||||
| 	 if (fabs(xba) < EPSILON) { | ||||
| 	    /* compare the Y coordinate */ | ||||
| 	    if (yba > 0.0) { | ||||
| 	       if ( | ||||
| 		   (fabs(a->y - c->y) < EPSILON | ||||
| 		    && fabs(c->y - b->y) < EPSILON) | ||||
| 		   || (fabs(a->y - d->y) < EPSILON | ||||
| 		       && fabs(d->y - b->y) < | ||||
| 		       EPSILON)) return GLU_TESS_ERROR4; | ||||
|  | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       if ( | ||||
| 		   (fabs(b->y - c->y) < EPSILON | ||||
| 		    && fabs(c->y - a->y) < EPSILON) | ||||
| 		   || (fabs(b->y - d->y) < EPSILON | ||||
| 		       && fabs(d->y - a->y) < | ||||
| 		       EPSILON)) return GLU_TESS_ERROR4; | ||||
| 	    } | ||||
| 	 } | ||||
| 	 else { | ||||
| 	    /* compare the X coordinate */ | ||||
| 	    if (xba > 0.0) { | ||||
| 	       if ( | ||||
| 		   (fabs(a->x - c->x) < EPSILON | ||||
| 		    && fabs(c->x - b->x) < EPSILON) | ||||
| 		   || (fabs(a->x - d->x) < EPSILON | ||||
| 		       && fabs(d->x - b->x) < | ||||
| 		       EPSILON)) return GLU_TESS_ERROR4; | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       if ( | ||||
| 		   (fabs(b->x - c->x) < EPSILON | ||||
| 		    && fabs(c->x - a->x) < EPSILON) | ||||
| 		   || (fabs(b->x - d->x) < EPSILON | ||||
| 		       && fabs(d->x - a->x) < | ||||
| 		       EPSILON)) return GLU_TESS_ERROR4; | ||||
| 	    } | ||||
| 	 } | ||||
|       } | ||||
|       return GLU_NO_ERROR; | ||||
|    } | ||||
|    r /= denom; | ||||
|    s = (yac * xba - xac * yba) / denom; | ||||
|    /* test if one vertex lies on other edge */ | ||||
|    if (((fabs(r) < EPSILON || (r < 1.0 + EPSILON && r > 1.0 - EPSILON)) && | ||||
| 	s > -EPSILON && s < 1.0 + EPSILON) || | ||||
|        ((fabs(s) < EPSILON || (s < 1.0 + EPSILON && s > 1.0 - EPSILON)) && | ||||
| 	r > -EPSILON && r < 1.0 + EPSILON)) { | ||||
|       return GLU_TESS_ERROR4; | ||||
|    } | ||||
|    /* test for crossing */ | ||||
|    if (r > -EPSILON && r < 1.0 + EPSILON && s > -EPSILON && s < 1.0 + EPSILON) { | ||||
|       return GLU_TESS_ERROR8; | ||||
|    } | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| verify_edge_vertex_intersections(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_vertex *vertex1, *last_vertex, *vertex2; | ||||
|    GLenum test; | ||||
|  | ||||
|    last_vertex = polygon->last_vertex; | ||||
|    vertex1 = last_vertex; | ||||
|    for (vertex2 = vertex1->next->next; | ||||
| 	vertex2->next != last_vertex; vertex2 = vertex2->next) { | ||||
|       test = edge_edge_intersect(vertex1, vertex1->next, vertex2, | ||||
| 				 vertex2->next); | ||||
|       if (test != GLU_NO_ERROR) { | ||||
| 	 tess_call_user_error(tobj, test); | ||||
| 	 return GLU_ERROR; | ||||
|       } | ||||
|    } | ||||
|    for (vertex1 = polygon->vertices; | ||||
| 	vertex1->next->next != last_vertex; vertex1 = vertex1->next) { | ||||
|       for (vertex2 = vertex1->next->next; | ||||
| 	   vertex2 != last_vertex; vertex2 = vertex2->next) { | ||||
| 	 test = edge_edge_intersect(vertex1, vertex1->next, vertex2, | ||||
| 				    vertex2->next); | ||||
| 	 if (test != GLU_NO_ERROR) { | ||||
| 	    tess_call_user_error(tobj, test); | ||||
| 	    return GLU_ERROR; | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static int | ||||
| #ifdef WIN32 | ||||
|   __cdecl | ||||
| #endif | ||||
| area_compare(const void *a, const void *b) | ||||
| { | ||||
|    GLdouble area1, area2; | ||||
|  | ||||
|    area1 = (*((tess_contour **) a))->area; | ||||
|    area2 = (*((tess_contour **) b))->area; | ||||
|    if (area1 < area2) | ||||
|       return 1; | ||||
|    if (area1 > area2) | ||||
|       return -1; | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_find_contour_hierarchies(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_contour **contours;	/* dinamic array of pointers */ | ||||
|    tess_contour *tmp_contour_ptr = tobj->contours; | ||||
|    GLuint cnt, i; | ||||
|    GLenum result; | ||||
|    GLboolean hierarchy_changed; | ||||
|  | ||||
|    /* any contours? */ | ||||
|    if (tobj->contour_cnt < 2) { | ||||
|       tobj->contours->type = GLU_EXTERIOR; | ||||
|       return; | ||||
|    } | ||||
|    if ((contours = (tess_contour **) | ||||
| 	malloc(sizeof(tess_contour *) * (tobj->contour_cnt))) == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
|       return; | ||||
|    } | ||||
|    for (tmp_contour_ptr = tobj->contours, cnt = 0; | ||||
| 	tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) | ||||
|       contours[cnt++] = tmp_contour_ptr; | ||||
|    /* now sort the contours in decreasing area size order */ | ||||
|    qsort((void *) contours, (size_t) cnt, (size_t) sizeof(tess_contour *), | ||||
| 	 area_compare); | ||||
|    /* we leave just the first contour - remove others from list */ | ||||
|    tobj->contours = contours[0]; | ||||
|    tobj->contours->next = tobj->contours->previous = NULL; | ||||
|    tobj->last_contour = tobj->contours; | ||||
|    tobj->contour_cnt = 1; | ||||
|    /* first contour is the one with greatest area */ | ||||
|    /* must be EXTERIOR */ | ||||
|    tobj->contours->type = GLU_EXTERIOR; | ||||
|    tmp_contour_ptr = tobj->contours; | ||||
|    /* now we play! */ | ||||
|    for (i = 1; i < cnt; i++) { | ||||
|       hierarchy_changed = GL_FALSE; | ||||
|       for (tmp_contour_ptr = tobj->contours; | ||||
| 	   tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) { | ||||
| 	 if (tmp_contour_ptr->type == GLU_EXTERIOR) { | ||||
| 	    /* check if contour completely contained in EXTERIOR */ | ||||
| 	    result = is_contour_contained_in(tmp_contour_ptr, contours[i]); | ||||
| 	    switch (result) { | ||||
| 	    case GLU_INTERIOR: | ||||
| 	       /* now we have to check if contour is inside interiors */ | ||||
| 	       /* or not */ | ||||
| 	       /* any interiors? */ | ||||
| 	       if (tmp_contour_ptr->next != NULL && | ||||
| 		   tmp_contour_ptr->next->type == GLU_INTERIOR) { | ||||
| 		  /* for all interior, check if inside any of them */ | ||||
| 		  /* if not inside any of interiors, its another */ | ||||
| 		  /* interior */ | ||||
| 		  /* or it may contain some interiors, then change */ | ||||
| 		  /* the contained interiors to exterior ones */ | ||||
| 		  add_interior_with_hierarchy_check(tobj, | ||||
| 						    tmp_contour_ptr, | ||||
| 						    contours[i]); | ||||
| 	       } | ||||
| 	       else { | ||||
| 		  /* not in interior, add as new interior contour */ | ||||
| 		  add_new_interior(tobj, tmp_contour_ptr, contours[i]); | ||||
| 	       } | ||||
| 	       hierarchy_changed = GL_TRUE; | ||||
| 	       break; | ||||
| 	    case GLU_EXTERIOR: | ||||
| 	       /* ooops, the marked as EXTERIOR (contours[i]) is */ | ||||
| 	       /* actually an interior of tmp_contour_ptr */ | ||||
| 	       /*  reverse the local hierarchy */ | ||||
| 	       reverse_hierarchy_and_add_exterior(tobj, tmp_contour_ptr, | ||||
| 						  contours[i]); | ||||
| 	       hierarchy_changed = GL_TRUE; | ||||
| 	       break; | ||||
| 	    case GLU_NO_ERROR: | ||||
| 	       break; | ||||
| 	    default: | ||||
| 	       abort(); | ||||
| 	    } | ||||
| 	 } | ||||
| 	 if (hierarchy_changed) | ||||
| 	    break;		/* break from for loop */ | ||||
|       } | ||||
|       if (hierarchy_changed == GL_FALSE) { | ||||
| 	 /* disjoint with all contours, add to contour list */ | ||||
| 	 add_new_exterior(tobj, contours[i]); | ||||
|       } | ||||
|    } | ||||
|    free(contours); | ||||
| } | ||||
|  | ||||
| /* returns GLU_INTERIOR if inner is completey enclosed within outer */ | ||||
| /* returns GLU_EXTERIOR if outer is completely enclosed within inner */ | ||||
| /* returns GLU_NO_ERROR if contours are disjoint */ | ||||
| static GLenum | ||||
| is_contour_contained_in(tess_contour * outer, tess_contour * inner) | ||||
| { | ||||
|    GLenum relation_flag; | ||||
|  | ||||
|    /* set relation_flag to relation of containment of first inner vertex */ | ||||
|    /* regarding outer contour */ | ||||
|    if (point_in_polygon(outer, inner->vertices->x, inner->vertices->y)) | ||||
|       relation_flag = GLU_INTERIOR; | ||||
|    else | ||||
|       relation_flag = GLU_EXTERIOR; | ||||
|    if (relation_flag == GLU_INTERIOR) | ||||
|       return GLU_INTERIOR; | ||||
|    if (point_in_polygon(inner, outer->vertices->x, outer->vertices->y)) | ||||
|       return GLU_EXTERIOR; | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| point_in_polygon(tess_contour * contour, GLdouble x, GLdouble y) | ||||
| { | ||||
|    tess_vertex *v1, *v2; | ||||
|    GLuint i, vertex_cnt; | ||||
|    GLdouble xp1, yp1, xp2, yp2; | ||||
|    GLboolean tst; | ||||
|  | ||||
|    tst = GL_FALSE; | ||||
|    v1 = contour->vertices; | ||||
|    v2 = contour->vertices->previous; | ||||
|    for (i = 0, vertex_cnt = contour->vertex_cnt; i < vertex_cnt; i++) { | ||||
|       xp1 = v1->x; | ||||
|       yp1 = v1->y; | ||||
|       xp2 = v2->x; | ||||
|       yp2 = v2->y; | ||||
|       if ((((yp1 <= y) && (y < yp2)) || ((yp2 <= y) && (y < yp1))) && | ||||
| 	  (x < (xp2 - xp1) * (y - yp1) / (yp2 - yp1) + xp1)) | ||||
| 	 tst = (tst == GL_FALSE ? GL_TRUE : GL_FALSE); | ||||
|       v2 = v1; | ||||
|       v1 = v1->next; | ||||
|    } | ||||
|    return tst; | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| contours_overlap(tess_contour * contour, tess_polygon * polygon) | ||||
| { | ||||
|    tess_vertex *vertex1, *vertex2; | ||||
|    GLuint vertex1_cnt, vertex2_cnt, i, j; | ||||
|    GLenum test; | ||||
|  | ||||
|    vertex1 = contour->vertices; | ||||
|    vertex2 = polygon->vertices; | ||||
|    vertex1_cnt = contour->vertex_cnt; | ||||
|    vertex2_cnt = polygon->vertex_cnt; | ||||
|    for (i = 0; i < vertex1_cnt; vertex1 = vertex1->next, i++) { | ||||
|       for (j = 0; j < vertex2_cnt; vertex2 = vertex2->next, j++) | ||||
| 	 if ((test = edge_edge_intersect(vertex1, vertex1->next, vertex2, | ||||
| 					 vertex2->next)) != GLU_NO_ERROR) | ||||
| 	    return test; | ||||
|    } | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_new_exterior(GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    contour->type = GLU_EXTERIOR; | ||||
|    contour->next = NULL; | ||||
|    contour->previous = tobj->last_contour; | ||||
|    tobj->last_contour->next = contour; | ||||
|    tobj->last_contour = contour; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_new_interior(GLUtriangulatorObj * tobj, | ||||
| 		 tess_contour * outer, tess_contour * contour) | ||||
| { | ||||
|    contour->type = GLU_INTERIOR; | ||||
|    contour->next = outer->next; | ||||
|    contour->previous = outer; | ||||
|    if (outer->next != NULL) | ||||
|       outer->next->previous = contour; | ||||
|    outer->next = contour; | ||||
|    if (tobj->last_contour == outer) | ||||
|       tobj->last_contour = contour; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_interior_with_hierarchy_check(GLUtriangulatorObj * tobj, | ||||
| 				  tess_contour * outer, | ||||
| 				  tess_contour * contour) | ||||
| { | ||||
|    tess_contour *ptr; | ||||
|  | ||||
|    /* for all interiors of outer check if they are interior of contour */ | ||||
|    /* if so, change that interior to exterior and move it of of the */ | ||||
|    /* interior sequence */ | ||||
|    if (outer->next != NULL && outer->next->type == GLU_INTERIOR) { | ||||
|       GLenum test; | ||||
|  | ||||
|       for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR; | ||||
| 	   ptr = ptr->next) { | ||||
| 	 test = is_contour_contained_in(ptr, contour); | ||||
| 	 switch (test) { | ||||
| 	 case GLU_INTERIOR: | ||||
| 	    /* contour is contained in one of the interiors */ | ||||
| 	    /* check if possibly contained in other exteriors */ | ||||
| 	    /* move ptr to first EXTERIOR */ | ||||
| 	    for (; ptr != NULL && ptr->type == GLU_INTERIOR; ptr = ptr->next); | ||||
| 	    if (ptr == NULL) | ||||
| 	       /* another exterior */ | ||||
| 	       add_new_exterior(tobj, contour); | ||||
| 	    else | ||||
| 	       add_exterior_with_check(tobj, ptr, contour); | ||||
| 	    return; | ||||
| 	 case GLU_EXTERIOR: | ||||
| 	    /* one of the interiors is contained in the contour */ | ||||
| 	    /* change it to EXTERIOR, and shift it away from the */ | ||||
| 	    /* interior sequence */ | ||||
| 	    shift_interior_to_exterior(tobj, ptr); | ||||
| 	    break; | ||||
| 	 case GLU_NO_ERROR: | ||||
| 	    /* disjoint */ | ||||
| 	    break; | ||||
| 	 default: | ||||
| 	    abort(); | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|    /* add contour to the interior sequence */ | ||||
|    add_new_interior(tobj, outer, contour); | ||||
| } | ||||
|  | ||||
| static void | ||||
| reverse_hierarchy_and_add_exterior(GLUtriangulatorObj * tobj, | ||||
| 				   tess_contour * outer, | ||||
| 				   tess_contour * contour) | ||||
| { | ||||
|    tess_contour *ptr; | ||||
|  | ||||
|    /* reverse INTERIORS to EXTERIORS */ | ||||
|    /* any INTERIORS? */ | ||||
|    if (outer->next != NULL && outer->next->type == GLU_INTERIOR) | ||||
|       for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR; | ||||
| 	   ptr = ptr->next) ptr->type = GLU_EXTERIOR; | ||||
|    /* the outer now becomes inner */ | ||||
|    outer->type = GLU_INTERIOR; | ||||
|    /* contour is the EXTERIOR */ | ||||
|    contour->next = outer; | ||||
|    if (tobj->contours == outer) { | ||||
|       /* first contour beeing reversed */ | ||||
|       contour->previous = NULL; | ||||
|       tobj->contours = contour; | ||||
|    } | ||||
|    else { | ||||
|       outer->previous->next = contour; | ||||
|       contour->previous = outer->previous; | ||||
|    } | ||||
|    outer->previous = contour; | ||||
| } | ||||
|  | ||||
| static void | ||||
| shift_interior_to_exterior(GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    contour->previous->next = contour->next; | ||||
|    if (contour->next != NULL) | ||||
|       contour->next->previous = contour->previous; | ||||
|    else | ||||
|       tobj->last_contour = contour->previous; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_exterior_with_check(GLUtriangulatorObj * tobj, | ||||
| 			tess_contour * outer, tess_contour * contour) | ||||
| { | ||||
|    GLenum test; | ||||
|  | ||||
|    /* this contour might be interior to further exteriors - check */ | ||||
|    /* if not, just add as a new exterior */ | ||||
|    for (; outer != NULL && outer->type == GLU_EXTERIOR; outer = outer->next) { | ||||
|       test = is_contour_contained_in(outer, contour); | ||||
|       switch (test) { | ||||
|       case GLU_INTERIOR: | ||||
| 	 /* now we have to check if contour is inside interiors */ | ||||
| 	 /* or not */ | ||||
| 	 /* any interiors? */ | ||||
| 	 if (outer->next != NULL && outer->next->type == GLU_INTERIOR) { | ||||
| 	    /* for all interior, check if inside any of them */ | ||||
| 	    /* if not inside any of interiors, its another */ | ||||
| 	    /* interior */ | ||||
| 	    /* or it may contain some interiors, then change */ | ||||
| 	    /* the contained interiors to exterior ones */ | ||||
| 	    add_interior_with_hierarchy_check(tobj, outer, contour); | ||||
| 	 } | ||||
| 	 else { | ||||
| 	    /* not in interior, add as new interior contour */ | ||||
| 	    add_new_interior(tobj, outer, contour); | ||||
| 	 } | ||||
| 	 return; | ||||
|       case GLU_NO_ERROR: | ||||
| 	 /* disjoint */ | ||||
| 	 break; | ||||
|       default: | ||||
| 	 abort(); | ||||
|       } | ||||
|    } | ||||
|    /* add contour to the exterior sequence */ | ||||
|    add_new_exterior(tobj, contour); | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_handle_holes(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_contour *contour, *hole; | ||||
|    GLenum exterior_orientation; | ||||
|  | ||||
|    /* verify hole orientation */ | ||||
|    for (contour = tobj->contours; contour != NULL;) { | ||||
|       exterior_orientation = contour->orientation; | ||||
|       for (contour = contour->next; | ||||
| 	   contour != NULL && contour->type == GLU_INTERIOR; | ||||
| 	   contour = contour->next) { | ||||
| 	 if (contour->orientation == exterior_orientation) { | ||||
| 	    tess_call_user_error(tobj, GLU_TESS_ERROR5); | ||||
| 	    return; | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|    /* now cut-out holes */ | ||||
|    for (contour = tobj->contours; contour != NULL;) { | ||||
|       hole = contour->next; | ||||
|       while (hole != NULL && hole->type == GLU_INTERIOR) { | ||||
| 	 if (cut_out_hole(tobj, contour, hole) == GLU_ERROR) | ||||
| 	    return; | ||||
| 	 hole = contour->next; | ||||
|       } | ||||
|       contour = contour->next; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| cut_out_hole(GLUtriangulatorObj * tobj, | ||||
| 	     tess_contour * contour, tess_contour * hole) | ||||
| { | ||||
|    tess_contour *tmp_hole; | ||||
|    tess_vertex *v1, *v2, *tmp_vertex; | ||||
|    GLuint vertex1_cnt, vertex2_cnt, tmp_vertex_cnt; | ||||
|    GLuint i, j, k; | ||||
|    GLenum test = 0; | ||||
|  | ||||
|    /* find an edge connecting contour and hole not intersecting any other */ | ||||
|    /* edge belonging to either the contour or any of the other holes */ | ||||
|    for (v1 = contour->vertices, vertex1_cnt = contour->vertex_cnt, i = 0; | ||||
| 	i < vertex1_cnt; i++, v1 = v1->next) { | ||||
|       for (v2 = hole->vertices, vertex2_cnt = hole->vertex_cnt, j = 0; | ||||
| 	   j < vertex2_cnt; j++, v2 = v2->next) { | ||||
| 	 /* does edge (v1,v2) intersect any edge of contour */ | ||||
| 	 for (tmp_vertex = contour->vertices, tmp_vertex_cnt = | ||||
| 	      contour->vertex_cnt, k = 0; k < tmp_vertex_cnt; | ||||
| 	      tmp_vertex = tmp_vertex->next, k++) { | ||||
| 	    /* skip edge tests for edges directly connected */ | ||||
| 	    if (v1 == tmp_vertex || v1 == tmp_vertex->next) | ||||
| 	       continue; | ||||
| 	    test = edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next); | ||||
| 	    if (test != GLU_NO_ERROR) | ||||
| 	       break; | ||||
| 	 } | ||||
| 	 if (test == GLU_NO_ERROR) { | ||||
| 	    /* does edge (v1,v2) intersect any edge of hole */ | ||||
| 	    for (tmp_vertex = hole->vertices, | ||||
| 		 tmp_vertex_cnt = hole->vertex_cnt, k = 0; | ||||
| 		 k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) { | ||||
| 	       /* skip edge tests for edges directly connected */ | ||||
| 	       if (v2 == tmp_vertex || v2 == tmp_vertex->next) | ||||
| 		  continue; | ||||
| 	       test = | ||||
| 		  edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next); | ||||
| 	       if (test != GLU_NO_ERROR) | ||||
| 		  break; | ||||
| 	    } | ||||
| 	    if (test == GLU_NO_ERROR) { | ||||
| 	       /* does edge (v1,v2) intersect any other hole? */ | ||||
| 	       for (tmp_hole = hole->next; | ||||
| 		    tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR; | ||||
| 		    tmp_hole = tmp_hole->next) { | ||||
| 		  /* does edge (v1,v2) intersect any edge of hole */ | ||||
| 		  for (tmp_vertex = tmp_hole->vertices, | ||||
| 		       tmp_vertex_cnt = tmp_hole->vertex_cnt, k = 0; | ||||
| 		       k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) { | ||||
| 		     test = edge_edge_intersect(v1, v2, tmp_vertex, | ||||
| 						tmp_vertex->next); | ||||
| 		     if (test != GLU_NO_ERROR) | ||||
| 			break; | ||||
| 		  } | ||||
| 		  if (test != GLU_NO_ERROR) | ||||
| 		     break; | ||||
| 	       } | ||||
| 	    } | ||||
| 	 } | ||||
| 	 if (test == GLU_NO_ERROR) { | ||||
| 	    /* edge (v1,v2) is good for eliminating the hole */ | ||||
| 	    if (merge_hole_with_contour(tobj, contour, hole, v1, v2) | ||||
| 		== GLU_NO_ERROR) | ||||
| 	       return GLU_NO_ERROR; | ||||
| 	    else | ||||
| 	       return GLU_ERROR; | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
|    /* other holes are blocking all possible connections of hole */ | ||||
|    /* with contour, we shift this hole as the last hole and retry */ | ||||
|    for (tmp_hole = hole; | ||||
| 	tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR; | ||||
| 	tmp_hole = tmp_hole->next); | ||||
|    contour->next = hole->next; | ||||
|    hole->next->previous = contour; | ||||
|    if (tmp_hole == NULL) { | ||||
|       /* last EXTERIOR contour, shift hole as last contour */ | ||||
|       hole->next = NULL; | ||||
|       hole->previous = tobj->last_contour; | ||||
|       tobj->last_contour->next = hole; | ||||
|       tobj->last_contour = hole; | ||||
|    } | ||||
|    else { | ||||
|       tmp_hole->previous->next = hole; | ||||
|       hole->previous = tmp_hole->previous; | ||||
|       tmp_hole->previous = hole; | ||||
|       hole->next = tmp_hole; | ||||
|    } | ||||
|    hole = contour->next; | ||||
|    /* try once again - recurse */ | ||||
|    return cut_out_hole(tobj, contour, hole); | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| merge_hole_with_contour(GLUtriangulatorObj * tobj, | ||||
| 			tess_contour * contour, | ||||
| 			tess_contour * hole, | ||||
| 			tess_vertex * v1, tess_vertex * v2) | ||||
| { | ||||
|    tess_vertex *v1_new, *v2_new; | ||||
|  | ||||
|    /* make copies of v1 and v2, place them respectively after their originals */ | ||||
|    if ((v1_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
|       return GLU_ERROR; | ||||
|    } | ||||
|    if ((v2_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
|       return GLU_ERROR; | ||||
|    } | ||||
|    v1_new->edge_flag = GL_TRUE; | ||||
|    v1_new->data = v1->data; | ||||
|    v1_new->location[0] = v1->location[0]; | ||||
|    v1_new->location[1] = v1->location[1]; | ||||
|    v1_new->location[2] = v1->location[2]; | ||||
|    v1_new->x = v1->x; | ||||
|    v1_new->y = v1->y; | ||||
|    v1_new->shadow_vertex = v1; | ||||
|    v1->shadow_vertex = v1_new; | ||||
|    v1_new->next = v1->next; | ||||
|    v1_new->previous = v1; | ||||
|    v1->next->previous = v1_new; | ||||
|    v1->next = v1_new; | ||||
|    v2_new->edge_flag = GL_TRUE; | ||||
|    v2_new->data = v2->data; | ||||
|    v2_new->location[0] = v2->location[0]; | ||||
|    v2_new->location[1] = v2->location[1]; | ||||
|    v2_new->location[2] = v2->location[2]; | ||||
|    v2_new->x = v2->x; | ||||
|    v2_new->y = v2->y; | ||||
|    v2_new->shadow_vertex = v2; | ||||
|    v2->shadow_vertex = v2_new; | ||||
|    v2_new->next = v2->next; | ||||
|    v2_new->previous = v2; | ||||
|    v2->next->previous = v2_new; | ||||
|    v2->next = v2_new; | ||||
|    /* link together the two lists */ | ||||
|    v1->next = v2_new; | ||||
|    v2_new->previous = v1; | ||||
|    v2->next = v1_new; | ||||
|    v1_new->previous = v2; | ||||
|    /* update the vertex count of the contour */ | ||||
|    contour->vertex_cnt += hole->vertex_cnt + 2; | ||||
|    /* remove the INTERIOR contour */ | ||||
|    contour->next = hole->next; | ||||
|    if (hole->next != NULL) | ||||
|       hole->next->previous = contour; | ||||
|    free(hole); | ||||
|    /* update tobj structure */ | ||||
|    --(tobj->contour_cnt); | ||||
|    if (contour->last_vertex == v1) | ||||
|       contour->last_vertex = v1_new; | ||||
|    /* mark two vertices with edge_flag */ | ||||
|    v2->edge_flag = GL_FALSE; | ||||
|    v1->edge_flag = GL_FALSE; | ||||
|    return GLU_NO_ERROR; | ||||
| } | ||||
							
								
								
									
										402
									
								
								src/glu/mini/project.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								src/glu/mini/project.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,402 @@ | ||||
| /* $Id: project.c,v 1.1.2.1 2003/03/21 13:02:18 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
| #include "gluP.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr). | ||||
|  * Thanks Marc!!! | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| /* implementation de gluProject et gluUnproject */ | ||||
| /* M. Buffat 17/2/95 */ | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Transform a point (column vector) by a 4x4 matrix.  I.e.  out = m * in | ||||
|  * Input:  m - the 4x4 matrix | ||||
|  *         in - the 4x1 vector | ||||
|  * Output:  out - the resulting 4x1 vector. | ||||
|  */ | ||||
| static void | ||||
| transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]) | ||||
| { | ||||
| #define M(row,col)  m[col*4+row] | ||||
|    out[0] = | ||||
|       M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; | ||||
|    out[1] = | ||||
|       M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; | ||||
|    out[2] = | ||||
|       M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; | ||||
|    out[3] = | ||||
|       M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; | ||||
| #undef M | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Perform a 4x4 matrix multiplication  (product = a x b). | ||||
|  * Input:  a, b - matrices to multiply | ||||
|  * Output:  product - product of a and b | ||||
|  */ | ||||
| static void | ||||
| matmul(GLdouble * product, const GLdouble * a, const GLdouble * b) | ||||
| { | ||||
|    /* This matmul was contributed by Thomas Malik */ | ||||
|    GLdouble temp[16]; | ||||
|    GLint i; | ||||
|  | ||||
| #define A(row,col)  a[(col<<2)+row] | ||||
| #define B(row,col)  b[(col<<2)+row] | ||||
| #define T(row,col)  temp[(col<<2)+row] | ||||
|  | ||||
|    /* i-te Zeile */ | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       T(i, 0) = | ||||
| 	 A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i, | ||||
| 								       3) * | ||||
| 	 B(3, 0); | ||||
|       T(i, 1) = | ||||
| 	 A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i, | ||||
| 								       3) * | ||||
| 	 B(3, 1); | ||||
|       T(i, 2) = | ||||
| 	 A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i, | ||||
| 								       3) * | ||||
| 	 B(3, 2); | ||||
|       T(i, 3) = | ||||
| 	 A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i, | ||||
| 								       3) * | ||||
| 	 B(3, 3); | ||||
|    } | ||||
|  | ||||
| #undef A | ||||
| #undef B | ||||
| #undef T | ||||
|    MEMCPY(product, temp, 16 * sizeof(GLdouble)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Compute inverse of 4x4 transformation matrix. | ||||
|  * Code contributed by Jacques Leroy jle@star.be | ||||
|  * Return GL_TRUE for success, GL_FALSE for failure (singular matrix) | ||||
|  */ | ||||
| static GLboolean | ||||
| invert_matrix(const GLdouble * m, GLdouble * out) | ||||
| { | ||||
| /* NB. OpenGL Matrices are COLUMN major. */ | ||||
| #define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; } | ||||
| #define MAT(m,r,c) (m)[(c)*4+(r)] | ||||
|  | ||||
|    GLdouble wtmp[4][8]; | ||||
|    GLdouble m0, m1, m2, m3, s; | ||||
|    GLdouble *r0, *r1, *r2, *r3; | ||||
|  | ||||
|    r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; | ||||
|  | ||||
|    r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1), | ||||
|       r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3), | ||||
|       r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, | ||||
|       r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1), | ||||
|       r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3), | ||||
|       r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, | ||||
|       r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1), | ||||
|       r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3), | ||||
|       r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, | ||||
|       r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1), | ||||
|       r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3), | ||||
|       r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; | ||||
|  | ||||
|    /* choose pivot - or die */ | ||||
|    if (fabs(r3[0]) > fabs(r2[0])) | ||||
|       SWAP_ROWS(r3, r2); | ||||
|    if (fabs(r2[0]) > fabs(r1[0])) | ||||
|       SWAP_ROWS(r2, r1); | ||||
|    if (fabs(r1[0]) > fabs(r0[0])) | ||||
|       SWAP_ROWS(r1, r0); | ||||
|    if (0.0 == r0[0]) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* eliminate first variable     */ | ||||
|    m1 = r1[0] / r0[0]; | ||||
|    m2 = r2[0] / r0[0]; | ||||
|    m3 = r3[0] / r0[0]; | ||||
|    s = r0[1]; | ||||
|    r1[1] -= m1 * s; | ||||
|    r2[1] -= m2 * s; | ||||
|    r3[1] -= m3 * s; | ||||
|    s = r0[2]; | ||||
|    r1[2] -= m1 * s; | ||||
|    r2[2] -= m2 * s; | ||||
|    r3[2] -= m3 * s; | ||||
|    s = r0[3]; | ||||
|    r1[3] -= m1 * s; | ||||
|    r2[3] -= m2 * s; | ||||
|    r3[3] -= m3 * s; | ||||
|    s = r0[4]; | ||||
|    if (s != 0.0) { | ||||
|       r1[4] -= m1 * s; | ||||
|       r2[4] -= m2 * s; | ||||
|       r3[4] -= m3 * s; | ||||
|    } | ||||
|    s = r0[5]; | ||||
|    if (s != 0.0) { | ||||
|       r1[5] -= m1 * s; | ||||
|       r2[5] -= m2 * s; | ||||
|       r3[5] -= m3 * s; | ||||
|    } | ||||
|    s = r0[6]; | ||||
|    if (s != 0.0) { | ||||
|       r1[6] -= m1 * s; | ||||
|       r2[6] -= m2 * s; | ||||
|       r3[6] -= m3 * s; | ||||
|    } | ||||
|    s = r0[7]; | ||||
|    if (s != 0.0) { | ||||
|       r1[7] -= m1 * s; | ||||
|       r2[7] -= m2 * s; | ||||
|       r3[7] -= m3 * s; | ||||
|    } | ||||
|  | ||||
|    /* choose pivot - or die */ | ||||
|    if (fabs(r3[1]) > fabs(r2[1])) | ||||
|       SWAP_ROWS(r3, r2); | ||||
|    if (fabs(r2[1]) > fabs(r1[1])) | ||||
|       SWAP_ROWS(r2, r1); | ||||
|    if (0.0 == r1[1]) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* eliminate second variable */ | ||||
|    m2 = r2[1] / r1[1]; | ||||
|    m3 = r3[1] / r1[1]; | ||||
|    r2[2] -= m2 * r1[2]; | ||||
|    r3[2] -= m3 * r1[2]; | ||||
|    r2[3] -= m2 * r1[3]; | ||||
|    r3[3] -= m3 * r1[3]; | ||||
|    s = r1[4]; | ||||
|    if (0.0 != s) { | ||||
|       r2[4] -= m2 * s; | ||||
|       r3[4] -= m3 * s; | ||||
|    } | ||||
|    s = r1[5]; | ||||
|    if (0.0 != s) { | ||||
|       r2[5] -= m2 * s; | ||||
|       r3[5] -= m3 * s; | ||||
|    } | ||||
|    s = r1[6]; | ||||
|    if (0.0 != s) { | ||||
|       r2[6] -= m2 * s; | ||||
|       r3[6] -= m3 * s; | ||||
|    } | ||||
|    s = r1[7]; | ||||
|    if (0.0 != s) { | ||||
|       r2[7] -= m2 * s; | ||||
|       r3[7] -= m3 * s; | ||||
|    } | ||||
|  | ||||
|    /* choose pivot - or die */ | ||||
|    if (fabs(r3[2]) > fabs(r2[2])) | ||||
|       SWAP_ROWS(r3, r2); | ||||
|    if (0.0 == r2[2]) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* eliminate third variable */ | ||||
|    m3 = r3[2] / r2[2]; | ||||
|    r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], | ||||
|       r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7]; | ||||
|  | ||||
|    /* last check */ | ||||
|    if (0.0 == r3[3]) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    s = 1.0 / r3[3];		/* now back substitute row 3 */ | ||||
|    r3[4] *= s; | ||||
|    r3[5] *= s; | ||||
|    r3[6] *= s; | ||||
|    r3[7] *= s; | ||||
|  | ||||
|    m2 = r2[3];			/* now back substitute row 2 */ | ||||
|    s = 1.0 / r2[2]; | ||||
|    r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), | ||||
|       r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); | ||||
|    m1 = r1[3]; | ||||
|    r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, | ||||
|       r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; | ||||
|    m0 = r0[3]; | ||||
|    r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, | ||||
|       r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; | ||||
|  | ||||
|    m1 = r1[2];			/* now back substitute row 1 */ | ||||
|    s = 1.0 / r1[1]; | ||||
|    r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), | ||||
|       r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); | ||||
|    m0 = r0[2]; | ||||
|    r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, | ||||
|       r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; | ||||
|  | ||||
|    m0 = r0[1];			/* now back substitute row 0 */ | ||||
|    s = 1.0 / r0[0]; | ||||
|    r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), | ||||
|       r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); | ||||
|  | ||||
|    MAT(out, 0, 0) = r0[4]; | ||||
|    MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6]; | ||||
|    MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4]; | ||||
|    MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6]; | ||||
|    MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4]; | ||||
|    MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6]; | ||||
|    MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4]; | ||||
|    MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6]; | ||||
|    MAT(out, 3, 3) = r3[7]; | ||||
|  | ||||
|    return GL_TRUE; | ||||
|  | ||||
| #undef MAT | ||||
| #undef SWAP_ROWS | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */ | ||||
| GLint GLAPIENTRY | ||||
| gluProject(GLdouble objx, GLdouble objy, GLdouble objz, | ||||
| 	   const GLdouble model[16], const GLdouble proj[16], | ||||
| 	   const GLint viewport[4], | ||||
| 	   GLdouble * winx, GLdouble * winy, GLdouble * winz) | ||||
| { | ||||
|    /* matrice de transformation */ | ||||
|    GLdouble in[4], out[4]; | ||||
|  | ||||
|    /* initilise la matrice et le vecteur a transformer */ | ||||
|    in[0] = objx; | ||||
|    in[1] = objy; | ||||
|    in[2] = objz; | ||||
|    in[3] = 1.0; | ||||
|    transform_point(out, model, in); | ||||
|    transform_point(in, proj, out); | ||||
|  | ||||
|    /* d'ou le resultat normalise entre -1 et 1 */ | ||||
|    if (in[3] == 0.0) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    in[0] /= in[3]; | ||||
|    in[1] /= in[3]; | ||||
|    in[2] /= in[3]; | ||||
|  | ||||
|    /* en coordonnees ecran */ | ||||
|    *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2; | ||||
|    *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2; | ||||
|    /* entre 0 et 1 suivant z */ | ||||
|    *winz = (1 + in[2]) / 2; | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* transformation du point ecran (winx,winy,winz) en point objet */ | ||||
| GLint GLAPIENTRY | ||||
| gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, | ||||
| 	     const GLdouble model[16], const GLdouble proj[16], | ||||
| 	     const GLint viewport[4], | ||||
| 	     GLdouble * objx, GLdouble * objy, GLdouble * objz) | ||||
| { | ||||
|    /* matrice de transformation */ | ||||
|    GLdouble m[16], A[16]; | ||||
|    GLdouble in[4], out[4]; | ||||
|  | ||||
|    /* transformation coordonnees normalisees entre -1 et 1 */ | ||||
|    in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0; | ||||
|    in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0; | ||||
|    in[2] = 2 * winz - 1.0; | ||||
|    in[3] = 1.0; | ||||
|  | ||||
|    /* calcul transformation inverse */ | ||||
|    matmul(A, proj, model); | ||||
|    invert_matrix(A, m); | ||||
|  | ||||
|    /* d'ou les coordonnees objets */ | ||||
|    transform_point(out, m, in); | ||||
|    if (out[3] == 0.0) | ||||
|       return GL_FALSE; | ||||
|    *objx = out[0] / out[3]; | ||||
|    *objy = out[1] / out[3]; | ||||
|    *objz = out[2] / out[3]; | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * New in GLU 1.3 | ||||
|  * This is like gluUnProject but also takes near and far DepthRange values. | ||||
|  */ | ||||
| #ifdef GLU_VERSION_1_3 | ||||
| GLint GLAPIENTRY | ||||
| gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw, | ||||
| 	      const GLdouble modelMatrix[16], | ||||
| 	      const GLdouble projMatrix[16], | ||||
| 	      const GLint viewport[4], | ||||
| 	      GLclampd nearZ, GLclampd farZ, | ||||
| 	      GLdouble * objx, GLdouble * objy, GLdouble * objz, | ||||
| 	      GLdouble * objw) | ||||
| { | ||||
|    /* matrice de transformation */ | ||||
|    GLdouble m[16], A[16]; | ||||
|    GLdouble in[4], out[4]; | ||||
|    GLdouble z = nearZ + winz * (farZ - nearZ); | ||||
|  | ||||
|    /* transformation coordonnees normalisees entre -1 et 1 */ | ||||
|    in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0; | ||||
|    in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0; | ||||
|    in[2] = 2.0 * z - 1.0; | ||||
|    in[3] = clipw; | ||||
|  | ||||
|    /* calcul transformation inverse */ | ||||
|    matmul(A, projMatrix, modelMatrix); | ||||
|    invert_matrix(A, m); | ||||
|  | ||||
|    /* d'ou les coordonnees objets */ | ||||
|    transform_point(out, m, in); | ||||
|    if (out[3] == 0.0) | ||||
|       return GL_FALSE; | ||||
|    *objx = out[0] / out[3]; | ||||
|    *objy = out[1] / out[3]; | ||||
|    *objz = out[2] / out[3]; | ||||
|    *objw = out[3]; | ||||
|    return GL_TRUE; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										774
									
								
								src/glu/mini/quadric.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										774
									
								
								src/glu/mini/quadric.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,774 @@ | ||||
| /* $Id: quadric.c,v 1.1.2.1 2003/03/21 13:02:22 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1999-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* TODO: | ||||
|  *   texture coordinate support | ||||
|  *   flip normals according to orientation | ||||
|  *   there's still some inside/outside orientation bugs in possibly all | ||||
|  *     but the sphere function | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include "gluP.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifndef M_PI | ||||
| #  define M_PI (3.1415926) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Convert degrees to radians: | ||||
|  */ | ||||
| #define DEG_TO_RAD(A)   ((A)*(M_PI/180.0)) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Sin and Cos for degree angles: | ||||
|  */ | ||||
| #define SIND( A )   sin( (A)*(M_PI/180.0) ) | ||||
| #define COSD( A)    cos( (A)*(M_PI/180.0) ) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Texture coordinates if texture flag is set | ||||
|  */ | ||||
| #define TXTR_COORD(x,y)    if (qobj->TextureFlag) glTexCoord2f(x,y); | ||||
|  | ||||
|  | ||||
|  | ||||
| struct GLUquadric | ||||
| { | ||||
|    GLenum DrawStyle;		/* GLU_FILL, LINE, SILHOUETTE, or POINT */ | ||||
|    GLenum Orientation;		/* GLU_INSIDE or GLU_OUTSIDE */ | ||||
|    GLboolean TextureFlag;	/* Generate texture coords? */ | ||||
|    GLenum Normals;		/* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */ | ||||
|    void (GLCALLBACK * ErrorFunc) (GLenum err);	/* Error handler callback function */ | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Process a GLU error. | ||||
|  */ | ||||
| static void | ||||
| quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg) | ||||
| { | ||||
|    /* Call the error call back function if any */ | ||||
|    if (qobj->ErrorFunc) { | ||||
|       (*qobj->ErrorFunc) (error); | ||||
|    } | ||||
|    /* Print a message to stdout if MESA_DEBUG variable is defined */ | ||||
|    if (getenv("MESA_DEBUG")) { | ||||
|       fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error), | ||||
| 	      msg); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| GLUquadricObj *GLAPIENTRY | ||||
| gluNewQuadric(void) | ||||
| { | ||||
|    GLUquadricObj *q; | ||||
|  | ||||
|    q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric)); | ||||
|    if (q) { | ||||
|       q->DrawStyle = GLU_FILL; | ||||
|       q->Orientation = GLU_OUTSIDE; | ||||
|       q->TextureFlag = GL_FALSE; | ||||
|       q->Normals = GLU_SMOOTH; | ||||
|       q->ErrorFunc = NULL; | ||||
|    } | ||||
|    return q; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluDeleteQuadric(GLUquadricObj * state) | ||||
| { | ||||
|    if (state) { | ||||
|       free((void *) state); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE, | ||||
|  * or GLU_POINT. | ||||
|  */ | ||||
| void GLAPIENTRY | ||||
| gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle) | ||||
| { | ||||
|    if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE | ||||
| 		      || drawStyle == GLU_SILHOUETTE | ||||
| 		      || drawStyle == GLU_POINT)) { | ||||
|       quadObject->DrawStyle = drawStyle; | ||||
|    } | ||||
|    else { | ||||
|       quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle"); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set the orientation to GLU_INSIDE or GLU_OUTSIDE. | ||||
|  */ | ||||
| void GLAPIENTRY | ||||
| gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation) | ||||
| { | ||||
|    if (quadObject | ||||
|        && (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) { | ||||
|       quadObject->Orientation = orientation; | ||||
|    } | ||||
|    else { | ||||
|       quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation"); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Set the error handler callback function. | ||||
|  */ | ||||
| void GLAPIENTRY | ||||
| gluQuadricCallback(GLUquadricObj * qobj, | ||||
| 		   GLenum which, void (GLCALLBACK * fn) ()) | ||||
| { | ||||
|    /* | ||||
|     * UGH, this is a mess!  I thought ANSI was a standard. | ||||
|     */ | ||||
|    if (qobj && which == GLU_ERROR) { | ||||
| #ifdef __CYGWIN32__ | ||||
|       qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn; | ||||
| #elif defined(OPENSTEP) | ||||
|       qobj->ErrorFunc = (void (*)(GLenum)) fn; | ||||
| #elif defined(_WIN32) | ||||
|       qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn; | ||||
| #elif defined(__STORM__) | ||||
|       qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn; | ||||
| #elif defined(__BEOS__) | ||||
|       qobj->ErrorFunc = (void (*)(GLenum)) fn; | ||||
| #else | ||||
|       qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn; | ||||
| #endif | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals) | ||||
| { | ||||
|    if (quadObject | ||||
|        && (normals == GLU_NONE || normals == GLU_FLAT | ||||
| 	   || normals == GLU_SMOOTH)) { | ||||
|       quadObject->Normals = normals; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords) | ||||
| { | ||||
|    if (quadObject) { | ||||
|       quadObject->TextureFlag = textureCoords; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Call glNormal3f after scaling normal to unit length. | ||||
|  */ | ||||
| static void | ||||
| normal3f(GLfloat x, GLfloat y, GLfloat z) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluCylinder(GLUquadricObj * qobj, | ||||
| 	    GLdouble baseRadius, GLdouble topRadius, | ||||
| 	    GLdouble height, GLint slices, GLint stacks) | ||||
| { | ||||
|    GLdouble da, r, dr, dz; | ||||
|    GLfloat x, y, z, nz, nsign; | ||||
|    GLint i, j; | ||||
|  | ||||
|    if (qobj->Orientation == GLU_INSIDE) { | ||||
|       nsign = -1.0; | ||||
|    } | ||||
|    else { | ||||
|       nsign = 1.0; | ||||
|    } | ||||
|  | ||||
|    da = 2.0 * M_PI / slices; | ||||
|    dr = (topRadius - baseRadius) / stacks; | ||||
|    dz = height / stacks; | ||||
|    nz = (baseRadius - topRadius) / height;	/* Z component of normal vectors */ | ||||
|  | ||||
|    if (qobj->DrawStyle == GLU_POINT) { | ||||
|       glBegin(GL_POINTS); | ||||
|       for (i = 0; i < slices; i++) { | ||||
| 	 x = cos(i * da); | ||||
| 	 y = sin(i * da); | ||||
| 	 normal3f(x * nsign, y * nsign, nz * nsign); | ||||
|  | ||||
| 	 z = 0.0; | ||||
| 	 r = baseRadius; | ||||
| 	 for (j = 0; j <= stacks; j++) { | ||||
| 	    glVertex3f(x * r, y * r, z); | ||||
| 	    z += dz; | ||||
| 	    r += dr; | ||||
| 	 } | ||||
|       } | ||||
|       glEnd(); | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) { | ||||
|       /* Draw rings */ | ||||
|       if (qobj->DrawStyle == GLU_LINE) { | ||||
| 	 z = 0.0; | ||||
| 	 r = baseRadius; | ||||
| 	 for (j = 0; j <= stacks; j++) { | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (i = 0; i < slices; i++) { | ||||
| 	       x = cos(i * da); | ||||
| 	       y = sin(i * da); | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       glVertex3f(x * r, y * r, z); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	    z += dz; | ||||
| 	    r += dr; | ||||
| 	 } | ||||
|       } | ||||
|       else { | ||||
| 	 /* draw one ring at each end */ | ||||
| 	 if (baseRadius != 0.0) { | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (i = 0; i < slices; i++) { | ||||
| 	       x = cos(i * da); | ||||
| 	       y = sin(i * da); | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       glVertex3f(x * baseRadius, y * baseRadius, 0.0); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (i = 0; i < slices; i++) { | ||||
| 	       x = cos(i * da); | ||||
| 	       y = sin(i * da); | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       glVertex3f(x * topRadius, y * topRadius, height); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	 } | ||||
|       } | ||||
|       /* draw length lines */ | ||||
|       glBegin(GL_LINES); | ||||
|       for (i = 0; i < slices; i++) { | ||||
| 	 x = cos(i * da); | ||||
| 	 y = sin(i * da); | ||||
| 	 normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	 glVertex3f(x * baseRadius, y * baseRadius, 0.0); | ||||
| 	 glVertex3f(x * topRadius, y * topRadius, height); | ||||
|       } | ||||
|       glEnd(); | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_FILL) { | ||||
|       GLfloat ds = 1.0 / slices; | ||||
|       GLfloat dt = 1.0 / stacks; | ||||
|       GLfloat t = 0.0; | ||||
|       z = 0.0; | ||||
|       r = baseRadius; | ||||
|       for (j = 0; j < stacks; j++) { | ||||
| 	 GLfloat s = 0.0; | ||||
| 	 glBegin(GL_QUAD_STRIP); | ||||
| 	 for (i = 0; i <= slices; i++) { | ||||
| 	    GLfloat x, y; | ||||
| 	    if (i == slices) { | ||||
| 	       x = sin(0.0); | ||||
| 	       y = cos(0.0); | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       x = sin(i * da); | ||||
| 	       y = cos(i * da); | ||||
| 	    } | ||||
| 	    if (nsign == 1.0) { | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       TXTR_COORD(s, t); | ||||
| 	       glVertex3f(x * r, y * r, z); | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       TXTR_COORD(s, t + dt); | ||||
| 	       glVertex3f(x * (r + dr), y * (r + dr), z + dz); | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       TXTR_COORD(s, t); | ||||
| 	       glVertex3f(x * r, y * r, z); | ||||
| 	       normal3f(x * nsign, y * nsign, nz * nsign); | ||||
| 	       TXTR_COORD(s, t + dt); | ||||
| 	       glVertex3f(x * (r + dr), y * (r + dr), z + dz); | ||||
| 	    } | ||||
| 	    s += ds; | ||||
| 	 }			/* for slices */ | ||||
| 	 glEnd(); | ||||
| 	 r += dr; | ||||
| 	 t += dt; | ||||
| 	 z += dz; | ||||
|       }				/* for stacks */ | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks) | ||||
| { | ||||
|    GLfloat rho, drho, theta, dtheta; | ||||
|    GLfloat x, y, z; | ||||
|    GLfloat s, t, ds, dt; | ||||
|    GLint i, j, imin, imax; | ||||
|    GLboolean normals; | ||||
|    GLfloat nsign; | ||||
|  | ||||
|    if (qobj->Normals == GLU_NONE) { | ||||
|       normals = GL_FALSE; | ||||
|    } | ||||
|    else { | ||||
|       normals = GL_TRUE; | ||||
|    } | ||||
|    if (qobj->Orientation == GLU_INSIDE) { | ||||
|       nsign = -1.0; | ||||
|    } | ||||
|    else { | ||||
|       nsign = 1.0; | ||||
|    } | ||||
|  | ||||
|    drho = M_PI / (GLfloat) stacks; | ||||
|    dtheta = 2.0 * M_PI / (GLfloat) slices; | ||||
|  | ||||
|    /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */ | ||||
|    /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */ | ||||
|    /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */ | ||||
|  | ||||
|    if (qobj->DrawStyle == GLU_FILL) { | ||||
|       if (!qobj->TextureFlag) { | ||||
| 	 /* draw +Z end as a triangle fan */ | ||||
| 	 glBegin(GL_TRIANGLE_FAN); | ||||
| /* 	 glNormal3f(0.0, 0.0, 1.0); */ | ||||
| 	 glVertex3f(0.0, 0.0, nsign * radius); | ||||
| 	 for (j = 0; j <= slices; j++) { | ||||
| 	    theta = (j == slices) ? 0.0 : j * dtheta; | ||||
| 	    x = -sin(theta) * sin(drho); | ||||
| 	    y = cos(theta) * sin(drho); | ||||
| 	    z = nsign * cos(drho); | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
|       } | ||||
|  | ||||
|       ds = 1.0 / slices; | ||||
|       dt = 1.0 / stacks; | ||||
|       t = 1.0;			/* because loop now runs from 0 */ | ||||
|       if (qobj->TextureFlag) { | ||||
| 	 imin = 0; | ||||
| 	 imax = stacks; | ||||
|       } | ||||
|       else { | ||||
| 	 imin = 1; | ||||
| 	 imax = stacks - 1; | ||||
|       } | ||||
|  | ||||
|       /* draw intermediate stacks as quad strips */ | ||||
|       for (i = imin; i < imax; i++) { | ||||
| 	 rho = i * drho; | ||||
| 	 glBegin(GL_QUAD_STRIP); | ||||
| 	 s = 0.0; | ||||
| 	 for (j = 0; j <= slices; j++) { | ||||
| 	    theta = (j == slices) ? 0.0 : j * dtheta; | ||||
| 	    x = -sin(theta) * sin(rho); | ||||
| 	    y = cos(theta) * sin(rho); | ||||
| 	    z = nsign * cos(rho); | ||||
| 	    TXTR_COORD(s, t); | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	    x = -sin(theta) * sin(rho + drho); | ||||
| 	    y = cos(theta) * sin(rho + drho); | ||||
| 	    z = nsign * cos(rho + drho); | ||||
| 	    TXTR_COORD(s, t - dt); | ||||
| 	    s += ds; | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
| 	 t -= dt; | ||||
|       } | ||||
|  | ||||
|       if (!qobj->TextureFlag) { | ||||
| 	 /* draw -Z end as a triangle fan */ | ||||
| 	 glBegin(GL_TRIANGLE_FAN); | ||||
| 	 glVertex3f(0.0, 0.0, -radius * nsign); | ||||
| 	 rho = M_PI - drho; | ||||
| 	 s = 1.0; | ||||
| 	 t = dt; | ||||
| 	 for (j = slices; j >= 0; j--) { | ||||
| 	    theta = (j == slices) ? 0.0 : j * dtheta; | ||||
| 	    x = -sin(theta) * sin(rho); | ||||
| 	    y = cos(theta) * sin(rho); | ||||
| 	    z = nsign * cos(rho); | ||||
| 	    s -= ds; | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
|       } | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) { | ||||
|       /* draw stack lines */ | ||||
|       for (i = 1; i < stacks; i++) {	/* stack line at i==stacks-1 was missing here */ | ||||
| 	 rho = i * drho; | ||||
| 	 glBegin(GL_LINE_LOOP); | ||||
| 	 for (j = 0; j < slices; j++) { | ||||
| 	    theta = j * dtheta; | ||||
| 	    x = cos(theta) * sin(rho); | ||||
| 	    y = sin(theta) * sin(rho); | ||||
| 	    z = cos(rho); | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
|       } | ||||
|       /* draw slice lines */ | ||||
|       for (j = 0; j < slices; j++) { | ||||
| 	 theta = j * dtheta; | ||||
| 	 glBegin(GL_LINE_STRIP); | ||||
| 	 for (i = 0; i <= stacks; i++) { | ||||
| 	    rho = i * drho; | ||||
| 	    x = cos(theta) * sin(rho); | ||||
| 	    y = sin(theta) * sin(rho); | ||||
| 	    z = cos(rho); | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
|       } | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_POINT) { | ||||
|       /* top and bottom-most points */ | ||||
|       glBegin(GL_POINTS); | ||||
|       glVertex3f(0.0, 0.0, radius); | ||||
|       glVertex3f(0.0, 0.0, -radius); | ||||
|  | ||||
|       /* loop over stacks */ | ||||
|       for (i = 1; i < stacks - 1; i++) { | ||||
| 	 rho = i * drho; | ||||
| 	 for (j = 0; j < slices; j++) { | ||||
| 	    theta = j * dtheta; | ||||
| 	    x = cos(theta) * sin(rho); | ||||
| 	    y = sin(theta) * sin(rho); | ||||
| 	    z = cos(rho); | ||||
| 	    glVertex3f(x * radius, y * radius, z * radius); | ||||
| 	 } | ||||
|       } | ||||
|       glEnd(); | ||||
|    } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluDisk(GLUquadricObj * qobj, | ||||
| 	GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops) | ||||
| { | ||||
|    GLfloat da, dr; | ||||
| #if 0 | ||||
|    GLdouble a, da; | ||||
|    GLfloat r, dr; | ||||
|    GLfloat x, y; | ||||
|    GLfloat r1, r2, dtc; | ||||
|    GLint s, l; | ||||
| #endif | ||||
|  | ||||
|  | ||||
|    da = 2.0 * M_PI / slices; | ||||
|    dr = (outerRadius - innerRadius) / (GLfloat) loops; | ||||
|  | ||||
|    switch (qobj->DrawStyle) { | ||||
|    case GLU_FILL: | ||||
|       { | ||||
| 	 /* texture of a gluDisk is a cut out of the texture unit square | ||||
| 	  * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] | ||||
| 	  * (linear mapping) | ||||
| 	  */ | ||||
| 	 GLfloat dtc = 2.0f * outerRadius; | ||||
| 	 GLfloat sa, ca; | ||||
| 	 GLfloat r1 = innerRadius; | ||||
| 	 GLint l; | ||||
| 	 for (l = 0; l < loops; l++) { | ||||
| 	    GLfloat r2 = r1 + dr; | ||||
| 	    if (qobj->Orientation == GLU_OUTSIDE) { | ||||
| 	       GLint s; | ||||
| 	       glBegin(GL_QUAD_STRIP); | ||||
| 	       for (s = 0; s <= slices; s++) { | ||||
| 		  GLfloat a; | ||||
| 		  if (s == slices) | ||||
| 		     a = 0.0; | ||||
| 		  else | ||||
| 		     a = s * da; | ||||
| 		  sa = sin(a); | ||||
| 		  ca = cos(a); | ||||
| 		  TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc); | ||||
| 		  glVertex2f(r2 * sa, r2 * ca); | ||||
| 		  TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc); | ||||
| 		  glVertex2f(r1 * sa, r1 * ca); | ||||
| 	       } | ||||
| 	       glEnd(); | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       GLint s; | ||||
| 	       glBegin(GL_QUAD_STRIP); | ||||
| 	       for (s = slices; s >= 0; s--) { | ||||
| 		  GLfloat a; | ||||
| 		  if (s == slices) | ||||
| 		     a = 0.0; | ||||
| 		  else | ||||
| 		     a = s * da; | ||||
| 		  sa = sin(a); | ||||
| 		  ca = cos(a); | ||||
| 		  TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc); | ||||
| 		  glVertex2f(r2 * sa, r2 * ca); | ||||
| 		  TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc); | ||||
| 		  glVertex2f(r1 * sa, r1 * ca); | ||||
| 	       } | ||||
| 	       glEnd(); | ||||
| 	    } | ||||
| 	    r1 = r2; | ||||
| 	 } | ||||
| 	 break; | ||||
|       } | ||||
|    case GLU_LINE: | ||||
|       { | ||||
| 	 GLint l, s; | ||||
| 	 /* draw loops */ | ||||
| 	 for (l = 0; l <= loops; l++) { | ||||
| 	    GLfloat r = innerRadius + l * dr; | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (s = 0; s < slices; s++) { | ||||
| 	       GLfloat a = s * da; | ||||
| 	       glVertex2f(r * sin(a), r * cos(a)); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	 } | ||||
| 	 /* draw spokes */ | ||||
| 	 for (s = 0; s < slices; s++) { | ||||
| 	    GLfloat a = s * da; | ||||
| 	    GLfloat x = sin(a); | ||||
| 	    GLfloat y = cos(a); | ||||
| 	    glBegin(GL_LINE_STRIP); | ||||
| 	    for (l = 0; l <= loops; l++) { | ||||
| 	       GLfloat r = innerRadius + l * dr; | ||||
| 	       glVertex2f(r * x, r * y); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	 } | ||||
| 	 break; | ||||
|       } | ||||
|    case GLU_POINT: | ||||
|       { | ||||
| 	 GLint s; | ||||
| 	 glBegin(GL_POINTS); | ||||
| 	 for (s = 0; s < slices; s++) { | ||||
| 	    GLfloat a = s * da; | ||||
| 	    GLfloat x = sin(a); | ||||
| 	    GLfloat y = cos(a); | ||||
| 	    GLint l; | ||||
| 	    for (l = 0; l <= loops; l++) { | ||||
| 	       GLfloat r = innerRadius * l * dr; | ||||
| 	       glVertex2f(r * x, r * y); | ||||
| 	    } | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
| 	 break; | ||||
|       } | ||||
|    case GLU_SILHOUETTE: | ||||
|       { | ||||
| 	 if (innerRadius != 0.0) { | ||||
| 	    GLfloat a; | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (a = 0.0; a < 2.0 * M_PI; a += da) { | ||||
| 	       GLfloat x = innerRadius * sin(a); | ||||
| 	       GLfloat y = innerRadius * cos(a); | ||||
| 	       glVertex2f(x, y); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	 } | ||||
| 	 { | ||||
| 	    GLfloat a; | ||||
| 	    glBegin(GL_LINE_LOOP); | ||||
| 	    for (a = 0; a < 2.0 * M_PI; a += da) { | ||||
| 	       GLfloat x = outerRadius * sin(a); | ||||
| 	       GLfloat y = outerRadius * cos(a); | ||||
| 	       glVertex2f(x, y); | ||||
| 	    } | ||||
| 	    glEnd(); | ||||
| 	 } | ||||
| 	 break; | ||||
|       } | ||||
|    default: | ||||
|       abort(); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius, | ||||
| 	       GLdouble outerRadius, GLint slices, GLint loops, | ||||
| 	       GLdouble startAngle, GLdouble sweepAngle) | ||||
| { | ||||
|    if (qobj->DrawStyle == GLU_POINT) { | ||||
|       GLint loop, slice; | ||||
|       GLdouble radius, delta_radius; | ||||
|       GLdouble angle, delta_angle; | ||||
|       delta_radius = (outerRadius - innerRadius) / (loops - 1); | ||||
|       delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1)); | ||||
|       glBegin(GL_POINTS); | ||||
|       radius = innerRadius; | ||||
|       for (loop = 0; loop < loops; loop++) { | ||||
| 	 angle = DEG_TO_RAD(startAngle); | ||||
| 	 for (slice = 0; slice < slices; slice++) { | ||||
| 	    glVertex2f(radius * sin(angle), radius * cos(angle)); | ||||
| 	    angle += delta_angle; | ||||
| 	 } | ||||
| 	 radius += delta_radius; | ||||
|       } | ||||
|       glEnd(); | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_LINE) { | ||||
|       GLint loop, slice; | ||||
|       GLdouble radius, delta_radius; | ||||
|       GLdouble angle, delta_angle; | ||||
|       delta_radius = (outerRadius - innerRadius) / loops; | ||||
|       delta_angle = DEG_TO_RAD(sweepAngle / slices); | ||||
|       /* draw rings */ | ||||
|       radius = innerRadius; | ||||
|       for (loop = 0; loop < loops; loop++) { | ||||
| 	 angle = DEG_TO_RAD(startAngle); | ||||
| 	 glBegin(GL_LINE_STRIP); | ||||
| 	 for (slice = 0; slice <= slices; slice++) { | ||||
| 	    glVertex2f(radius * sin(angle), radius * cos(angle)); | ||||
| 	    angle += delta_angle; | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
| 	 radius += delta_radius; | ||||
|       } | ||||
|       /* draw spokes */ | ||||
|       angle = DEG_TO_RAD(startAngle); | ||||
|       for (slice = 0; slice <= slices; slice++) { | ||||
| 	 radius = innerRadius; | ||||
| 	 glBegin(GL_LINE_STRIP); | ||||
| 	 for (loop = 0; loop < loops; loop++) { | ||||
| 	    glVertex2f(radius * sin(angle), radius * cos(angle)); | ||||
| 	    radius += delta_radius; | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
| 	 angle += delta_angle; | ||||
|       } | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_SILHOUETTE) { | ||||
|       GLint slice; | ||||
|       GLdouble angle, delta_angle; | ||||
|       delta_angle = DEG_TO_RAD(sweepAngle / slices); | ||||
|       /* draw outer ring */ | ||||
|       glBegin(GL_LINE_STRIP); | ||||
|       angle = DEG_TO_RAD(startAngle); | ||||
|       for (slice = 0; slice <= slices; slice++) { | ||||
| 	 glVertex2f(outerRadius * sin(angle), outerRadius * cos(angle)); | ||||
| 	 angle += delta_angle; | ||||
|       } | ||||
|       glEnd(); | ||||
|       /* draw inner ring */ | ||||
|       if (innerRadius > 0.0) { | ||||
| 	 glBegin(GL_LINE_STRIP); | ||||
| 	 angle = DEG_TO_RAD(startAngle); | ||||
| 	 for (slice = 0; slice < slices; slice++) { | ||||
| 	    glVertex2f(innerRadius * sin(angle), innerRadius * cos(angle)); | ||||
| 	    angle += delta_angle; | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
|       } | ||||
|       /* draw spokes */ | ||||
|       if (sweepAngle < 360.0) { | ||||
| 	 GLdouble stopAngle = startAngle + sweepAngle; | ||||
| 	 glBegin(GL_LINES); | ||||
| 	 glVertex2f(innerRadius * SIND(startAngle), | ||||
| 		    innerRadius * COSD(startAngle)); | ||||
| 	 glVertex2f(outerRadius * SIND(startAngle), | ||||
| 		    outerRadius * COSD(startAngle)); | ||||
| 	 glVertex2f(innerRadius * SIND(stopAngle), | ||||
| 		    innerRadius * COSD(stopAngle)); | ||||
| 	 glVertex2f(outerRadius * SIND(stopAngle), | ||||
| 		    outerRadius * COSD(stopAngle)); | ||||
| 	 glEnd(); | ||||
|       } | ||||
|    } | ||||
|    else if (qobj->DrawStyle == GLU_FILL) { | ||||
|       GLint loop, slice; | ||||
|       GLdouble radius, delta_radius; | ||||
|       GLdouble angle, delta_angle; | ||||
|       delta_radius = (outerRadius - innerRadius) / loops; | ||||
|       delta_angle = DEG_TO_RAD(sweepAngle / slices); | ||||
|       radius = innerRadius; | ||||
|       for (loop = 0; loop < loops; loop++) { | ||||
| 	 glBegin(GL_QUAD_STRIP); | ||||
| 	 angle = DEG_TO_RAD(startAngle); | ||||
| 	 for (slice = 0; slice <= slices; slice++) { | ||||
| 	    if (qobj->Orientation == GLU_OUTSIDE) { | ||||
| 	       glVertex2f((radius + delta_radius) * sin(angle), | ||||
| 			  (radius + delta_radius) * cos(angle)); | ||||
| 	       glVertex2f(radius * sin(angle), radius * cos(angle)); | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       glVertex2f(radius * sin(angle), radius * cos(angle)); | ||||
| 	       glVertex2f((radius + delta_radius) * sin(angle), | ||||
| 			  (radius + delta_radius) * cos(angle)); | ||||
| 	    } | ||||
| 	    angle += delta_angle; | ||||
| 	 } | ||||
| 	 glEnd(); | ||||
| 	 radius += delta_radius; | ||||
|       } | ||||
|    } | ||||
| } | ||||
							
								
								
									
										328
									
								
								src/glu/mini/tess.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								src/glu/mini/tess.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,328 @@ | ||||
| /* $Id: tess.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file is part of the polygon tesselation code contributed by | ||||
|  * Bogdan Sikorski | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| #include "tess.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This is ugly, but seems the easiest way to do things to make the | ||||
|  * code work under YellowBox for Windows | ||||
|  */ | ||||
| #if defined(OPENSTEP) && defined(CALLBACK) | ||||
| #undef CALLBACK | ||||
| #define CALLBACK | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static void delete_contours(GLUtriangulatorObj *); | ||||
|  | ||||
| #ifdef __CYGWIN32__ | ||||
| #define _CALLBACK | ||||
| #else | ||||
| #define _CALLBACK GLCALLBACK | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static void | ||||
| init_callbacks(tess_callbacks * callbacks) | ||||
| { | ||||
|    callbacks->begin = (void (_CALLBACK *) (GLenum)) 0; | ||||
|    callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0; | ||||
|    callbacks->vertex = (void (_CALLBACK *) (void *)) 0; | ||||
|    callbacks->end = (void (_CALLBACK *) (void)) 0; | ||||
|    callbacks->error = (void (_CALLBACK *) (GLenum)) 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr) | ||||
| { | ||||
|    if (tobj->error == GLU_NO_ERROR) | ||||
|       tobj->error = gluerr; | ||||
|    if (tobj->callbacks.error != NULL) | ||||
|       (tobj->callbacks.error) (gluerr); | ||||
| } | ||||
|  | ||||
| GLUtriangulatorObj *GLAPIENTRY | ||||
| gluNewTess(void) | ||||
| { | ||||
|    GLUtriangulatorObj *tobj; | ||||
|  | ||||
|    if ((tobj = (GLUtriangulatorObj *) | ||||
| 	malloc(sizeof(struct GLUtesselator))) == NULL) | ||||
|       return NULL; | ||||
|    tobj->contours = tobj->last_contour = NULL; | ||||
|    init_callbacks(&tobj->callbacks); | ||||
|    tobj->error = GLU_NO_ERROR; | ||||
|    tobj->current_polygon = NULL; | ||||
|    tobj->contour_cnt = 0; | ||||
|    return tobj; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluTessCallback(GLUtriangulatorObj * tobj, GLenum which, | ||||
| 		void (GLCALLBACK * fn) ()) | ||||
| { | ||||
|    switch (which) { | ||||
|    case GLU_BEGIN: | ||||
|       tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn; | ||||
|       break; | ||||
|    case GLU_EDGE_FLAG: | ||||
|       tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn; | ||||
|       break; | ||||
|    case GLU_VERTEX: | ||||
|       tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn; | ||||
|       break; | ||||
|    case GLU_END: | ||||
|       tobj->callbacks.end = (void (_CALLBACK *) (void)) fn; | ||||
|       break; | ||||
|    case GLU_ERROR: | ||||
|       tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn; | ||||
|       break; | ||||
|    default: | ||||
|       tobj->error = GLU_INVALID_ENUM; | ||||
|       break; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluDeleteTess(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt) | ||||
|       /* was gluEndPolygon called? */ | ||||
|       tess_call_user_error(tobj, GLU_TESS_ERROR1); | ||||
|    /* delete all internal structures */ | ||||
|    delete_contours(tobj); | ||||
|    free(tobj); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluBeginPolygon(GLUtriangulatorObj * tobj) | ||||
| { | ||||
| /* | ||||
| 	if(tobj->error!=GLU_NO_ERROR) | ||||
| 		return; | ||||
| */ | ||||
|    tobj->error = GLU_NO_ERROR; | ||||
|    if (tobj->current_polygon != NULL) { | ||||
|       /* gluEndPolygon was not called */ | ||||
|       tess_call_user_error(tobj, GLU_TESS_ERROR1); | ||||
|       /* delete all internal structures */ | ||||
|       delete_contours(tobj); | ||||
|    } | ||||
|    else { | ||||
|       if ((tobj->current_polygon = | ||||
| 	   (tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) { | ||||
| 	 tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
| 	 return; | ||||
|       } | ||||
|       tobj->current_polygon->vertex_cnt = 0; | ||||
|       tobj->current_polygon->vertices = | ||||
| 	 tobj->current_polygon->last_vertex = NULL; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluEndPolygon(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    /*tess_contour *contour_ptr; */ | ||||
|  | ||||
|    /* there was an error */ | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       goto end; | ||||
|  | ||||
|    /* check if gluBeginPolygon was called */ | ||||
|    if (tobj->current_polygon == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_TESS_ERROR2); | ||||
|       return; | ||||
|    } | ||||
|    tess_test_polygon(tobj); | ||||
|    /* there was an error */ | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       goto end; | ||||
|  | ||||
|    /* any real contours? */ | ||||
|    if (tobj->contour_cnt == 0) { | ||||
|       /* delete all internal structures */ | ||||
|       delete_contours(tobj); | ||||
|       return; | ||||
|    } | ||||
|    tess_find_contour_hierarchies(tobj); | ||||
|    /* there was an error */ | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       goto end; | ||||
|  | ||||
|    tess_handle_holes(tobj); | ||||
|    /* there was an error */ | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       goto end; | ||||
|  | ||||
|    /* if no callbacks, nothing to do */ | ||||
|    if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL && | ||||
|        tobj->callbacks.end != NULL) { | ||||
|       if (tobj->callbacks.edgeFlag == NULL) | ||||
| 	 tess_tesselate(tobj); | ||||
|       else | ||||
| 	 tess_tesselate_with_edge_flag(tobj); | ||||
|    } | ||||
|  | ||||
|  end: | ||||
|    /* delete all internal structures */ | ||||
|    delete_contours(tobj); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluNextContour(GLUtriangulatorObj * tobj, GLenum type) | ||||
| { | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       return; | ||||
|    if (tobj->current_polygon == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_TESS_ERROR2); | ||||
|       return; | ||||
|    } | ||||
|    /* first contour? */ | ||||
|    if (tobj->current_polygon->vertex_cnt) | ||||
|       tess_test_polygon(tobj); | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_vertex *last_vertex_ptr; | ||||
|  | ||||
|    if (tobj->error != GLU_NO_ERROR) | ||||
|       return; | ||||
|    if (polygon == NULL) { | ||||
|       tess_call_user_error(tobj, GLU_TESS_ERROR2); | ||||
|       return; | ||||
|    } | ||||
|    last_vertex_ptr = polygon->last_vertex; | ||||
|    if (last_vertex_ptr == NULL) { | ||||
|       if ((last_vertex_ptr = (tess_vertex *) | ||||
| 	   malloc(sizeof(tess_vertex))) == NULL) { | ||||
| 	 tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
| 	 return; | ||||
|       } | ||||
|       polygon->vertices = last_vertex_ptr; | ||||
|       polygon->last_vertex = last_vertex_ptr; | ||||
|       last_vertex_ptr->data = data; | ||||
|       last_vertex_ptr->location[0] = v[0]; | ||||
|       last_vertex_ptr->location[1] = v[1]; | ||||
|       last_vertex_ptr->location[2] = v[2]; | ||||
|       last_vertex_ptr->next = NULL; | ||||
|       last_vertex_ptr->previous = NULL; | ||||
|       ++(polygon->vertex_cnt); | ||||
|    } | ||||
|    else { | ||||
|       tess_vertex *vertex_ptr; | ||||
|  | ||||
|       /* same point twice? */ | ||||
|       if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON && | ||||
| 	  fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON && | ||||
| 	  fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) { | ||||
| 	 tess_call_user_error(tobj, GLU_TESS_ERROR6); | ||||
| 	 return; | ||||
|       } | ||||
|       if ((vertex_ptr = (tess_vertex *) | ||||
| 	   malloc(sizeof(tess_vertex))) == NULL) { | ||||
| 	 tess_call_user_error(tobj, GLU_OUT_OF_MEMORY); | ||||
| 	 return; | ||||
|       } | ||||
|       vertex_ptr->data = data; | ||||
|       vertex_ptr->location[0] = v[0]; | ||||
|       vertex_ptr->location[1] = v[1]; | ||||
|       vertex_ptr->location[2] = v[2]; | ||||
|       vertex_ptr->next = NULL; | ||||
|       vertex_ptr->previous = last_vertex_ptr; | ||||
|       ++(polygon->vertex_cnt); | ||||
|       last_vertex_ptr->next = vertex_ptr; | ||||
|       polygon->last_vertex = vertex_ptr; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| delete_contours(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_polygon *polygon = tobj->current_polygon; | ||||
|    tess_contour *contour, *contour_tmp; | ||||
|    tess_vertex *vertex, *vertex_tmp; | ||||
|  | ||||
|    /* remove current_polygon list - if exists due to detected error */ | ||||
|    if (polygon != NULL) { | ||||
|       if (polygon->vertices) { | ||||
| 	 for (vertex = polygon->vertices; vertex != polygon->last_vertex;) { | ||||
| 	    vertex_tmp = vertex->next; | ||||
| 	    free(vertex); | ||||
| 	    vertex = vertex_tmp; | ||||
| 	 } | ||||
| 	 free(vertex); | ||||
|       } | ||||
|       free(polygon); | ||||
|       tobj->current_polygon = NULL; | ||||
|    } | ||||
|    /* remove all contour data */ | ||||
|    for (contour = tobj->contours; contour != NULL;) { | ||||
|       for (vertex = contour->vertices; vertex != contour->last_vertex;) { | ||||
| 	 vertex_tmp = vertex->next; | ||||
| 	 free(vertex); | ||||
| 	 vertex = vertex_tmp; | ||||
|       } | ||||
|       free(vertex); | ||||
|       contour_tmp = contour->next; | ||||
|       free(contour); | ||||
|       contour = contour_tmp; | ||||
|    } | ||||
|    tobj->contours = tobj->last_contour = NULL; | ||||
|    tobj->contour_cnt = 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GLAPIENTRY | ||||
| gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ) | ||||
| { | ||||
|    /* dummy function */ | ||||
|    (void) tess; | ||||
|    (void) valueX; | ||||
|    (void) valueY; | ||||
|    (void) valueZ; | ||||
| } | ||||
							
								
								
									
										108
									
								
								src/glu/mini/tess.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/glu/mini/tess.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* $Id: tess.h,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file is part of the polygon tesselation code contributed by | ||||
|  * Bogdan Sikorski | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef TESS_H | ||||
| #define TESS_H | ||||
|  | ||||
|  | ||||
| #include "gluP.h" | ||||
|  | ||||
| #define EPSILON 1e-06		/* epsilon for double precision compares */ | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|    OXY, | ||||
|    OYZ, | ||||
|    OXZ | ||||
| } | ||||
| projection_type; | ||||
|  | ||||
| typedef struct callbacks_str | ||||
| { | ||||
|    void (GLCALLBACK * begin) (GLenum mode); | ||||
|    void (GLCALLBACK * edgeFlag) (GLboolean flag); | ||||
|    void (GLCALLBACK * vertex) (GLvoid * v); | ||||
|    void (GLCALLBACK * end) (void); | ||||
|    void (GLCALLBACK * error) (GLenum err); | ||||
| } | ||||
| tess_callbacks; | ||||
|  | ||||
| typedef struct vertex_str | ||||
| { | ||||
|    void *data; | ||||
|    GLdouble location[3]; | ||||
|    GLdouble x, y; | ||||
|    GLboolean edge_flag; | ||||
|    struct vertex_str *shadow_vertex; | ||||
|    struct vertex_str *next, *previous; | ||||
| } | ||||
| tess_vertex; | ||||
|  | ||||
| typedef struct contour_str | ||||
| { | ||||
|    GLenum type; | ||||
|    GLuint vertex_cnt; | ||||
|    GLdouble area; | ||||
|    GLenum orientation; | ||||
|    struct vertex_str *vertices, *last_vertex; | ||||
|    struct contour_str *next, *previous; | ||||
| } | ||||
| tess_contour; | ||||
|  | ||||
| typedef struct polygon_str | ||||
| { | ||||
|    GLuint vertex_cnt; | ||||
|    GLdouble A, B, C, D; | ||||
|    GLdouble area; | ||||
|    GLenum orientation; | ||||
|    struct vertex_str *vertices, *last_vertex; | ||||
| } | ||||
| tess_polygon; | ||||
|  | ||||
| struct GLUtesselator | ||||
| { | ||||
|    tess_contour *contours, *last_contour; | ||||
|    GLuint contour_cnt; | ||||
|    tess_callbacks callbacks; | ||||
|    tess_polygon *current_polygon; | ||||
|    GLenum error; | ||||
|    GLdouble A, B, C, D; | ||||
|    projection_type projection; | ||||
| }; | ||||
|  | ||||
|  | ||||
| extern void tess_call_user_error(GLUtriangulatorObj *, GLenum); | ||||
| extern void tess_test_polygon(GLUtriangulatorObj *); | ||||
| extern void tess_find_contour_hierarchies(GLUtriangulatorObj *); | ||||
| extern void tess_handle_holes(GLUtriangulatorObj *); | ||||
| extern void tess_tesselate(GLUtriangulatorObj *); | ||||
| extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *); | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										407
									
								
								src/glu/mini/tesselat.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										407
									
								
								src/glu/mini/tesselat.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,407 @@ | ||||
| /* $Id: tesselat.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Mesa 3-D graphics library | ||||
|  * Version:  3.3 | ||||
|  * Copyright (C) 1995-2000  Brian Paul | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with this library; if not, write to the Free | ||||
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This file is part of the polygon tesselation code contributed by | ||||
|  * Bogdan Sikorski | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifdef PC_HEADER | ||||
| #include "all.h" | ||||
| #else | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| #include "tess.h" | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLboolean edge_flag; | ||||
|  | ||||
| static void emit_triangle(GLUtriangulatorObj *, tess_vertex *, | ||||
| 			  tess_vertex *, tess_vertex *); | ||||
|  | ||||
| static void emit_triangle_with_edge_flag(GLUtriangulatorObj *, | ||||
| 					 tess_vertex *, GLboolean, | ||||
| 					 tess_vertex *, GLboolean, | ||||
| 					 tess_vertex *, GLboolean); | ||||
|  | ||||
| static GLdouble | ||||
| twice_the_triangle_area(tess_vertex * va, tess_vertex * vb, tess_vertex * vc) | ||||
| { | ||||
|    return (vb->x - va->x) * (vc->y - va->y) - (vb->y - va->y) * (vc->x - | ||||
| 								 va->x); | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| left(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y) | ||||
| { | ||||
|    if (A * x + B * y + C > -EPSILON) | ||||
|       return GL_TRUE; | ||||
|    else | ||||
|       return GL_FALSE; | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| right(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y) | ||||
| { | ||||
|    if (A * x + B * y + C < EPSILON) | ||||
|       return GL_TRUE; | ||||
|    else | ||||
|       return GL_FALSE; | ||||
| } | ||||
|  | ||||
| static GLint | ||||
| convex_ccw(tess_vertex * va, | ||||
| 	   tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    GLdouble d; | ||||
|  | ||||
|    d = twice_the_triangle_area(va, vb, vc); | ||||
|  | ||||
|    if (d > EPSILON) { | ||||
|       return 1; | ||||
|    } | ||||
|    else if (d < -EPSILON) { | ||||
|       return 0; | ||||
|    } | ||||
|    else { | ||||
|       return -1; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static GLint | ||||
| convex_cw(tess_vertex * va, | ||||
| 	  tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    GLdouble d; | ||||
|  | ||||
|    d = twice_the_triangle_area(va, vb, vc); | ||||
|  | ||||
|    if (d < -EPSILON) { | ||||
|       return 1; | ||||
|    } | ||||
|    else if (d > EPSILON) { | ||||
|       return 0; | ||||
|    } | ||||
|    else { | ||||
|       return -1; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| diagonal_ccw(tess_vertex * va, | ||||
| 	     tess_vertex * vb, | ||||
| 	     GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vc = va->next, *vertex, *shadow_vertex; | ||||
|    struct | ||||
|    { | ||||
|       GLdouble A, B, C; | ||||
|    } | ||||
|    ac, cb, ba; | ||||
|    GLdouble x, y; | ||||
|  | ||||
|    GLint res = convex_ccw(va, vc, vb, tobj); | ||||
|    if (res == 0) | ||||
|       return GL_FALSE; | ||||
|    if (res == -1) | ||||
|       return GL_TRUE; | ||||
|  | ||||
|    ba.A = vb->y - va->y; | ||||
|    ba.B = va->x - vb->x; | ||||
|    ba.C = -ba.A * va->x - ba.B * va->y; | ||||
|    ac.A = va->y - vc->y; | ||||
|    ac.B = vc->x - va->x; | ||||
|    ac.C = -ac.A * vc->x - ac.B * vc->y; | ||||
|    cb.A = vc->y - vb->y; | ||||
|    cb.B = vb->x - vc->x; | ||||
|    cb.C = -cb.A * vb->x - cb.B * vb->y; | ||||
|    for (vertex = vb->next; vertex != va; vertex = vertex->next) { | ||||
|       shadow_vertex = vertex->shadow_vertex; | ||||
|       if (shadow_vertex != NULL && | ||||
| 	  (shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc)) | ||||
| 	 continue; | ||||
|       x = vertex->x; | ||||
|       y = vertex->y; | ||||
|       if (left(ba.A, ba.B, ba.C, x, y) && | ||||
| 	  left(ac.A, ac.B, ac.C, x, y) && left(cb.A, cb.B, cb.C, x, y)) | ||||
| 	 return GL_FALSE; | ||||
|    } | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| diagonal_cw(tess_vertex * va, | ||||
| 	    tess_vertex * vb, | ||||
| 	    GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vc = va->next, *vertex, *shadow_vertex; | ||||
|    struct | ||||
|    { | ||||
|       GLdouble A, B, C; | ||||
|    } | ||||
|    ac, cb, ba; | ||||
|    GLdouble x, y; | ||||
|  | ||||
|    GLint res = convex_cw(va, vc, vb, tobj); | ||||
|    if (res == 0) | ||||
|       return GL_FALSE; | ||||
|    if (res == -1) | ||||
|       return GL_TRUE; | ||||
|  | ||||
|    ba.A = vb->y - va->y; | ||||
|    ba.B = va->x - vb->x; | ||||
|    ba.C = -ba.A * va->x - ba.B * va->y; | ||||
|    ac.A = va->y - vc->y; | ||||
|    ac.B = vc->x - va->x; | ||||
|    ac.C = -ac.A * vc->x - ac.B * vc->y; | ||||
|    cb.A = vc->y - vb->y; | ||||
|    cb.B = vb->x - vc->x; | ||||
|    cb.C = -cb.A * vb->x - cb.B * vb->y; | ||||
|    for (vertex = vb->next; vertex != va; vertex = vertex->next) { | ||||
|       shadow_vertex = vertex->shadow_vertex; | ||||
|       if (shadow_vertex != NULL && | ||||
| 	  (shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc)) | ||||
| 	 continue; | ||||
|       x = vertex->x; | ||||
|       y = vertex->y; | ||||
|       if (right(ba.A, ba.B, ba.C, x, y) && | ||||
| 	  right(ac.A, ac.B, ac.C, x, y) && right(cb.A, cb.B, cb.C, x, y)) | ||||
| 	 return GL_FALSE; | ||||
|    } | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clip_ear(GLUtriangulatorObj * tobj, tess_vertex * v, tess_contour * contour) | ||||
| { | ||||
|    emit_triangle(tobj, v->previous, v, v->next); | ||||
|    /* the first in the list */ | ||||
|    if (contour->vertices == v) { | ||||
|       contour->vertices = v->next; | ||||
|       contour->last_vertex->next = v->next; | ||||
|       v->next->previous = contour->last_vertex; | ||||
|    } | ||||
|    else | ||||
|       /* the last ? */ | ||||
|    if (contour->last_vertex == v) { | ||||
|       contour->vertices->previous = v->previous; | ||||
|       v->previous->next = v->next; | ||||
|       contour->last_vertex = v->previous; | ||||
|    } | ||||
|    else { | ||||
|       v->next->previous = v->previous; | ||||
|       v->previous->next = v->next; | ||||
|    } | ||||
|    free(v); | ||||
|    --(contour->vertex_cnt); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clip_ear_with_edge_flag(GLUtriangulatorObj * tobj, | ||||
| 			tess_vertex * v, tess_contour * contour) | ||||
| { | ||||
|    emit_triangle_with_edge_flag(tobj, v->previous, v->previous->edge_flag, | ||||
| 				v, v->edge_flag, v->next, GL_FALSE); | ||||
|    v->previous->edge_flag = GL_FALSE; | ||||
|    /* the first in the list */ | ||||
|    if (contour->vertices == v) { | ||||
|       contour->vertices = v->next; | ||||
|       contour->last_vertex->next = v->next; | ||||
|       v->next->previous = contour->last_vertex; | ||||
|    } | ||||
|    else | ||||
|       /* the last ? */ | ||||
|    if (contour->last_vertex == v) { | ||||
|       contour->vertices->previous = v->previous; | ||||
|       v->previous->next = v->next; | ||||
|       contour->last_vertex = v->previous; | ||||
|    } | ||||
|    else { | ||||
|       v->next->previous = v->previous; | ||||
|       v->previous->next = v->next; | ||||
|    } | ||||
|    free(v); | ||||
|    --(contour->vertex_cnt); | ||||
| } | ||||
|  | ||||
| static void | ||||
| triangulate_ccw(GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vertex; | ||||
|    GLuint vertex_cnt = contour->vertex_cnt; | ||||
|  | ||||
|    while (vertex_cnt > 3) { | ||||
|       vertex = contour->vertices; | ||||
|       while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) == | ||||
| 	     GL_FALSE && tobj->error == GLU_NO_ERROR) | ||||
| 	 vertex = vertex->next; | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|       clip_ear(tobj, vertex->next, contour); | ||||
|       --vertex_cnt; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void | ||||
| triangulate_cw(GLUtriangulatorObj * tobj, tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vertex; | ||||
|    GLuint vertex_cnt = contour->vertex_cnt; | ||||
|  | ||||
|    while (vertex_cnt > 3) { | ||||
|       vertex = contour->vertices; | ||||
|       while (diagonal_cw(vertex, vertex->next->next, tobj, contour) == | ||||
| 	     GL_FALSE && tobj->error == GLU_NO_ERROR) | ||||
| 	 vertex = vertex->next; | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|       clip_ear(tobj, vertex->next, contour); | ||||
|       --vertex_cnt; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void | ||||
| triangulate_ccw_with_edge_flag(GLUtriangulatorObj * tobj, | ||||
| 			       tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vertex; | ||||
|    GLuint vertex_cnt = contour->vertex_cnt; | ||||
|  | ||||
|    while (vertex_cnt > 3) { | ||||
|       vertex = contour->vertices; | ||||
|       while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) == | ||||
| 	     GL_FALSE && tobj->error == GLU_NO_ERROR) | ||||
| 	 vertex = vertex->next; | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|       clip_ear_with_edge_flag(tobj, vertex->next, contour); | ||||
|       --vertex_cnt; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void | ||||
| triangulate_cw_with_edge_flag(GLUtriangulatorObj * tobj, | ||||
| 			      tess_contour * contour) | ||||
| { | ||||
|    tess_vertex *vertex; | ||||
|    GLuint vertex_cnt = contour->vertex_cnt; | ||||
|  | ||||
|    while (vertex_cnt > 3) { | ||||
|       vertex = contour->vertices; | ||||
|       while (diagonal_cw(vertex, vertex->next->next, tobj, contour) == | ||||
| 	     GL_FALSE && tobj->error == GLU_NO_ERROR) | ||||
| 	 vertex = vertex->next; | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|       clip_ear_with_edge_flag(tobj, vertex->next, contour); | ||||
|       --vertex_cnt; | ||||
|    } | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_tesselate(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_contour *contour; | ||||
|  | ||||
|    for (contour = tobj->contours; contour != NULL; contour = contour->next) { | ||||
|       if (contour->orientation == GLU_CCW) { | ||||
| 	 triangulate_ccw(tobj, contour); | ||||
|       } | ||||
|       else { | ||||
| 	 triangulate_cw(tobj, contour); | ||||
|       } | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|  | ||||
|       /* emit the last triangle */ | ||||
|       emit_triangle(tobj, contour->vertices, contour->vertices->next, | ||||
| 		    contour->vertices->next->next); | ||||
|    } | ||||
| } | ||||
|  | ||||
| void | ||||
| tess_tesselate_with_edge_flag(GLUtriangulatorObj * tobj) | ||||
| { | ||||
|    tess_contour *contour; | ||||
|  | ||||
|    edge_flag = GL_TRUE; | ||||
|    /* first callback with edgeFlag set to GL_TRUE */ | ||||
|    (tobj->callbacks.edgeFlag) (GL_TRUE); | ||||
|  | ||||
|    for (contour = tobj->contours; contour != NULL; contour = contour->next) { | ||||
|       if (contour->orientation == GLU_CCW) | ||||
| 	 triangulate_ccw_with_edge_flag(tobj, contour); | ||||
|       else | ||||
| 	 triangulate_cw_with_edge_flag(tobj, contour); | ||||
|       if (tobj->error != GLU_NO_ERROR) | ||||
| 	 return; | ||||
|       /* emit the last triangle */ | ||||
|       emit_triangle_with_edge_flag(tobj, contour->vertices, | ||||
| 				   contour->vertices->edge_flag, | ||||
| 				   contour->vertices->next, | ||||
| 				   contour->vertices->next->edge_flag, | ||||
| 				   contour->vertices->next->next, | ||||
| 				   contour->vertices->next->next->edge_flag); | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void | ||||
| emit_triangle(GLUtriangulatorObj * tobj, | ||||
| 	      tess_vertex * v1, tess_vertex * v2, tess_vertex * v3) | ||||
| { | ||||
|    (tobj->callbacks.begin) (GL_TRIANGLES); | ||||
|    (tobj->callbacks.vertex) (v1->data); | ||||
|    (tobj->callbacks.vertex) (v2->data); | ||||
|    (tobj->callbacks.vertex) (v3->data); | ||||
|    (tobj->callbacks.end) (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| emit_triangle_with_edge_flag(GLUtriangulatorObj * tobj, | ||||
| 			     tess_vertex * v1, | ||||
| 			     GLboolean edge_flag1, | ||||
| 			     tess_vertex * v2, | ||||
| 			     GLboolean edge_flag2, | ||||
| 			     tess_vertex * v3, GLboolean edge_flag3) | ||||
| { | ||||
|    (tobj->callbacks.begin) (GL_TRIANGLES); | ||||
|    if (edge_flag1 != edge_flag) { | ||||
|       edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE); | ||||
|       (tobj->callbacks.edgeFlag) (edge_flag); | ||||
|    } | ||||
|    (tobj->callbacks.vertex) (v1->data); | ||||
|    if (edge_flag2 != edge_flag) { | ||||
|       edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE); | ||||
|       (tobj->callbacks.edgeFlag) (edge_flag); | ||||
|    } | ||||
|    (tobj->callbacks.vertex) (v2->data); | ||||
|    if (edge_flag3 != edge_flag) { | ||||
|       edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE); | ||||
|       (tobj->callbacks.edgeFlag) (edge_flag); | ||||
|    } | ||||
|    (tobj->callbacks.vertex) (v3->data); | ||||
|    (tobj->callbacks.end) (); | ||||
| } | ||||
| @@ -1,43 +1,11 @@ | ||||
| # Mesa 3-D graphics library | ||||
| # Version:  4.0 | ||||
| #  | ||||
| # Copyright (C) 1999  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"), | ||||
| # 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. | ||||
|  | ||||
| # DOS/DJGPP glut makefile v1.1 for Mesa 4.0 | ||||
| # | ||||
| #  Copyright (C) 2002 - Borca Daniel | ||||
| #  Email : dborca@yahoo.com | ||||
| #  Web   : http://www.geocities.com/dborca | ||||
| MESA = ../.. | ||||
|  | ||||
| MARK = $(MESA)/src-glut | ||||
| default: libglut.so.3.7 install  | ||||
| include $(MESA)/Makefile.include | ||||
|  | ||||
|  | ||||
| .PHONY: all clean | ||||
|  | ||||
| TOP = ../.. | ||||
| MARK = $(TOP)/src-glut | ||||
| LIBDIR = $(TOP)/lib | ||||
| GLUT_LIB = libglut.so | ||||
|  | ||||
| CC = gcc | ||||
| INCLUDES = -I$(TOP)/include -I$(MARK) | ||||
| CFLAGS = -c -g $(INCLUDES) -MD  | ||||
| INCLUDES = -I$(MESA)/include -I$(MARK) | ||||
|  | ||||
| CORE_SOURCES = \ | ||||
| 	bitmap.c \ | ||||
| @@ -64,35 +32,19 @@ MARK_SOURCES = \ | ||||
|  | ||||
| SOURCES = $(CORE_SOURCES)  $(MARK_SOURCES) | ||||
|  | ||||
| OBJS = $(addsuffix .o,$(basename $(SOURCES))) | ||||
|  | ||||
| LIBS=-L$(TOP)/lib -lGL -lGLU -lm | ||||
|  | ||||
| .c.o: | ||||
| 	$(CC) -o $@ -c $(CFLAGS) $< | ||||
| .S.o: | ||||
| 	$(CC) -o $@ -c $(CFLAGS) $< | ||||
|  | ||||
| default: libglut.so.3.7 install  | ||||
| OBJS =  $(SOURCES:.c=.o) | ||||
|  | ||||
| LIBS = -L$(MESA)/lib -lGL -lGLU -lm | ||||
|  | ||||
| libglut.so.3.7: $(OBJS) Makefile | ||||
| 	gcc -shared -Wl,-soname,libglut.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@  | ||||
|  | ||||
| install: | ||||
| 	rm -f $(TOP)/lib/libglut.so* | ||||
| 	install -D libglut.so.3.7 $(TOP)/lib/libglut.so.3.7 | ||||
| 	ln -s libglut.so.3.7 $(TOP)/lib/libglut.so.3 | ||||
| 	ln -s libglut.so.3 $(TOP)/lib/libglut.so | ||||
|  | ||||
|  | ||||
| clean: | ||||
| 	rm -f *~ .*~ *.o libglut.so*  *.d | ||||
| 	rm -f $(MESA)/lib/libglut.so* | ||||
| 	install -D libglut.so.3.7 $(MESA)/lib/libglut.so.3.7 | ||||
| 	ln -s libglut.so.3.7 $(MESA)/lib/libglut.so.3 | ||||
| 	ln -s libglut.so.3 $(MESA)/lib/libglut.so | ||||
|  | ||||
|  | ||||
| -include $(SOURCES:.c=.d) | ||||
|  | ||||
| .SUFFIXES: .c .d | ||||
|  | ||||
| .c.d: | ||||
| 	$(CC) -M $(INCLUDES) $< > $@ | ||||
|   | ||||
| @@ -12,8 +12,8 @@ glutBitmapCharacter(GLUTbitmapFont font, int c) | ||||
| { | ||||
|   const BitmapCharRec *ch; | ||||
|   BitmapFontPtr fontinfo; | ||||
|   GLint swapbytes, lsbfirst, rowlength; | ||||
|   GLint skiprows, skippixels, alignment; | ||||
|   GLfloat swapbytes, lsbfirst, rowlength; | ||||
|   GLfloat skiprows, skippixels, alignment; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   fontinfo = (BitmapFontPtr) __glutFont(font); | ||||
| @@ -27,30 +27,30 @@ glutBitmapCharacter(GLUTbitmapFont font, int c) | ||||
|   ch = fontinfo->ch[c - fontinfo->first]; | ||||
|   if (ch) { | ||||
|     /* Save current modes. */ | ||||
|     glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); | ||||
|     glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); | ||||
|     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); | ||||
|     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); | ||||
|     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); | ||||
|     glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); | ||||
| /*     glGetFloatv(GL_UNPACK_SWAP_BYTES, &swapbytes); */ | ||||
| /*     glGetFloatv(GL_UNPACK_LSB_FIRST, &lsbfirst); */ | ||||
| /*     glGetFloatv(GL_UNPACK_ROW_LENGTH, &rowlength); */ | ||||
| /*     glGetFloatv(GL_UNPACK_SKIP_ROWS, &skiprows); */ | ||||
| /*     glGetFloatv(GL_UNPACK_SKIP_PIXELS, &skippixels); */ | ||||
|        glGetFloatv(GL_UNPACK_ALIGNMENT, &alignment);  | ||||
|     /* Little endian machines (DEC Alpha for example) could | ||||
|        benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE | ||||
|        instead of GL_FALSE, but this would require changing the | ||||
|        generated bitmaps too. */ | ||||
|     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); | ||||
|     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); | ||||
|     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||||
|     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | ||||
|     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | ||||
|     glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
| /*     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); */ | ||||
| /*     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); */ | ||||
| /*     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); */ | ||||
| /*     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); */ | ||||
| /*     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); */ | ||||
|      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  | ||||
|     glBitmap(ch->width, ch->height, ch->xorig, ch->yorig, | ||||
|       ch->advance, 0, ch->bitmap); | ||||
|     /* Restore saved modes. */ | ||||
|     glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); | ||||
|     glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); | ||||
|     glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); | ||||
|     glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); | ||||
|     glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); | ||||
|     glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); | ||||
| /*     glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); */ | ||||
| /*     glPixelStorei(GL_UNPACK_LSB_FIRST, (int)lsbfirst); */ | ||||
| /*     glPixelStorei(GL_UNPACK_ROW_LENGTH, (int)rowlength); */ | ||||
| /*     glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); */ | ||||
| /*     glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); */ | ||||
|      glPixelStorei(GL_UNPACK_ALIGNMENT, (int)alignment);  | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -40,9 +40,6 @@ void APIENTRY glutInit (int *argcp, char **argv) | ||||
| void APIENTRY glutInitDisplayMode (unsigned int mode) | ||||
| { | ||||
|  g_display_mode = mode; | ||||
|  | ||||
| /*  pc_install_keyb(); */ | ||||
| /*  g_mouse = pc_install_mouse(); */ | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -60,103 +57,3 @@ void APIENTRY glutInitWindowSize (int width, int height) | ||||
| } | ||||
|  | ||||
|  | ||||
| void APIENTRY glutMainLoop (void) | ||||
| { | ||||
|  GLboolean idle; | ||||
|  static int old_mouse_x = 0; | ||||
|  static int old_mouse_y = 0; | ||||
|  static int old_mouse_b = 0; | ||||
|  | ||||
|  glutPostRedisplay(); | ||||
|  if (reshape_func) reshape_func(g_width, g_height); | ||||
|  if (visibility_func) visibility_func(GLUT_VISIBLE); | ||||
| /*  if (g_mouse) pc_show_mouse(); */ | ||||
|  | ||||
|  while (GL_TRUE) { | ||||
|        idle = GL_TRUE; | ||||
|  | ||||
|        if (g_redisplay && display_func) { | ||||
|           idle        = GL_FALSE; | ||||
|           g_redisplay = GL_FALSE; | ||||
|  | ||||
| /*           if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_scare_mouse(); */ | ||||
|           display_func(); | ||||
| /*           if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_unscare_mouse(); */ | ||||
|        } | ||||
|  | ||||
| #if 0 | ||||
|        if (pc_keypressed()) { | ||||
|           int key; | ||||
|  | ||||
|           idle = GL_FALSE; | ||||
|           key  = pc_readkey(); | ||||
|  | ||||
|           switch (key>>16) { | ||||
|                  case KEY_F1:     if (special_func) special_func(GLUT_KEY_F1,        0, 0); break; | ||||
|                  case KEY_F2:     if (special_func) special_func(GLUT_KEY_F2,        0, 0); break; | ||||
|                  case KEY_F3:     if (special_func) special_func(GLUT_KEY_F3,        0, 0); break; | ||||
|                  case KEY_F4:     if (special_func) special_func(GLUT_KEY_F4,        0, 0); break; | ||||
|                  case KEY_F5:     if (special_func) special_func(GLUT_KEY_F5,        0, 0); break; | ||||
|                  case KEY_F6:     if (special_func) special_func(GLUT_KEY_F6,        0, 0); break; | ||||
|                  case KEY_F7:     if (special_func) special_func(GLUT_KEY_F7,        0, 0); break; | ||||
|                  case KEY_F8:     if (special_func) special_func(GLUT_KEY_F8,        0, 0); break; | ||||
|                  case KEY_F9:     if (special_func) special_func(GLUT_KEY_F9,        0, 0); break; | ||||
|                  case KEY_F10:    if (special_func) special_func(GLUT_KEY_F10,       0, 0); break; | ||||
|                  case KEY_F11:    if (special_func) special_func(GLUT_KEY_F11,       0, 0); break; | ||||
|                  case KEY_F12:    if (special_func) special_func(GLUT_KEY_F12,       0, 0); break; | ||||
|                  case KEY_LEFT:   if (special_func) special_func(GLUT_KEY_LEFT,      0, 0); break; | ||||
|                  case KEY_UP:     if (special_func) special_func(GLUT_KEY_UP,        0, 0); break; | ||||
|                  case KEY_RIGHT:  if (special_func) special_func(GLUT_KEY_RIGHT,     0, 0); break; | ||||
|                  case KEY_DOWN:   if (special_func) special_func(GLUT_KEY_DOWN,      0, 0); break; | ||||
|                  case KEY_PGUP:   if (special_func) special_func(GLUT_KEY_PAGE_UP,   0, 0); break; | ||||
|                  case KEY_PGDN:   if (special_func) special_func(GLUT_KEY_PAGE_DOWN, 0, 0); break; | ||||
|                  case KEY_HOME:   if (special_func) special_func(GLUT_KEY_HOME,      0, 0); break; | ||||
|                  case KEY_END:    if (special_func) special_func(GLUT_KEY_END,       0, 0); break; | ||||
|                  case KEY_INSERT: if (special_func) special_func(GLUT_KEY_INSERT,    0, 0); break; | ||||
|                  default:         if (keyboard_func) keyboard_func(key & 0xFF, 0, 0); | ||||
|           } | ||||
|        } | ||||
|  | ||||
|        if (g_mouse) { | ||||
|           int mouse_x; | ||||
|           int mouse_y; | ||||
|           int mouse_b; | ||||
|         | ||||
|           mouse_b = pc_query_mouse(&mouse_x, &mouse_y); | ||||
|            | ||||
|           if (motion_func && ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y))) { | ||||
|              idle        = GL_FALSE; | ||||
|              old_mouse_x = mouse_x; | ||||
|              old_mouse_y = mouse_y; | ||||
|     | ||||
|              motion_func(old_mouse_x, old_mouse_y); | ||||
|           } | ||||
|     | ||||
|           if (mouse_func && (mouse_b != old_mouse_b)) { | ||||
|              int new_mouse_b = mouse_b; | ||||
|     | ||||
|              if ((old_mouse_b & 1) && !(new_mouse_b & 1)) | ||||
|                 mouse_func(GLUT_LEFT_BUTTON, GLUT_UP,   mouse_x, mouse_y); | ||||
|              else if (!(old_mouse_b & 1) && (new_mouse_b & 1)) | ||||
|                 mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, mouse_x, mouse_y); | ||||
|     | ||||
|              if ((old_mouse_b & 2) && !(new_mouse_b & 2)) | ||||
|                 mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP,   mouse_x, mouse_y); | ||||
|              else if (!(old_mouse_b & 2) && (new_mouse_b & 2)) | ||||
|                 mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, mouse_x, mouse_y); | ||||
|     | ||||
|              if ((old_mouse_b & 4) && !(new_mouse_b & 4)) | ||||
|                 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP,   mouse_x, mouse_y); | ||||
|              else if (!(old_mouse_b & 3) && (new_mouse_b & 4)) | ||||
|                 mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, mouse_x, mouse_y); | ||||
|     | ||||
|              idle        = GL_FALSE; | ||||
|              old_mouse_b = new_mouse_b; | ||||
|           } | ||||
|        } | ||||
| #endif | ||||
|  | ||||
|        if (idle && idle_func) | ||||
|           idle_func(); | ||||
|  } | ||||
| } | ||||
|   | ||||
| @@ -152,7 +152,7 @@ drawBox(GLfloat size, GLenum type) | ||||
|  | ||||
|   for (i = 5; i >= 0; i--) { | ||||
|     glBegin(type); | ||||
|     glNormal3fv(&n[i][0]); | ||||
| /*     glNormal3fv(&n[i][0]); */ | ||||
|     glVertex3fv(&v[faces[i][0]][0]); | ||||
|     glVertex3fv(&v[faces[i][1]][0]); | ||||
|     glVertex3fv(&v[faces[i][2]][0]); | ||||
| @@ -205,9 +205,9 @@ doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings) | ||||
|       sinPhi = sin(phi); | ||||
|       dist = R + r * cosPhi; | ||||
|  | ||||
|       glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); | ||||
| /*       glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); */ | ||||
|       glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); | ||||
|       glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); | ||||
| /*       glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); */ | ||||
|       glVertex3f(cosTheta * dist, -sinTheta * dist,  r * sinPhi); | ||||
|     } | ||||
|     glEnd(); | ||||
| @@ -222,10 +222,10 @@ void APIENTRY | ||||
| glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, | ||||
|   GLint nsides, GLint rings) | ||||
| { | ||||
|   glPushAttrib(GL_POLYGON_BIT); | ||||
| /*   glPushAttrib(GL_POLYGON_BIT); */ | ||||
|   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
|   doughnut(innerRadius, outerRadius, nsides, rings); | ||||
|   glPopAttrib(); | ||||
| /*   glPopAttrib(); */ | ||||
| } | ||||
|  | ||||
| void APIENTRY | ||||
| @@ -318,7 +318,7 @@ pentagon(int a, int b, int c, int d, int e, GLenum shadeType) | ||||
|   normalize(n0); | ||||
|  | ||||
|   glBegin(shadeType); | ||||
|   glNormal3fv(n0); | ||||
| /*   glNormal3fv(n0); */ | ||||
|   glVertex3fv(&dodec[a][0]); | ||||
|   glVertex3fv(&dodec[b][0]); | ||||
|   glVertex3fv(&dodec[c][0]); | ||||
| @@ -377,7 +377,7 @@ recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3, | ||||
|   normalize(q1); | ||||
|  | ||||
|   glBegin(shadeType); | ||||
|   glNormal3fv(q1); | ||||
| /*   glNormal3fv(q1); */ | ||||
|   glVertex3fv(n1); | ||||
|   glVertex3fv(n2); | ||||
|   glVertex3fv(n3); | ||||
|   | ||||
| @@ -143,6 +143,7 @@ teapot(GLint grid, GLdouble scale, GLenum type) | ||||
|   float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3]; | ||||
|   long i, j, k, l; | ||||
|  | ||||
| #if 0 | ||||
|   glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT); | ||||
|   glEnable(GL_AUTO_NORMAL); | ||||
|   glEnable(GL_NORMALIZE); | ||||
| @@ -194,6 +195,7 @@ teapot(GLint grid, GLdouble scale, GLenum type) | ||||
|   } | ||||
|   glPopMatrix(); | ||||
|   glPopAttrib(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /* CENTRY */ | ||||
|   | ||||
| @@ -218,3 +218,50 @@ void APIENTRY glutShowWindow (void) | ||||
| void APIENTRY glutHideWindow (void) | ||||
| { | ||||
| } | ||||
|  | ||||
| void APIENTRY glutMainLoop (void) | ||||
| { | ||||
|    GLboolean idle; | ||||
|    GLboolean have_event; | ||||
|    XEvent evt; | ||||
|  | ||||
|    glutPostRedisplay(); | ||||
|    if (reshape_func) reshape_func(g_width, g_height); | ||||
|  | ||||
|    while (GL_TRUE) { | ||||
|       idle = GL_TRUE; | ||||
|  | ||||
|  | ||||
|       if (idle_func)  | ||||
| 	 have_event = XCheckWindowEvent( dpy, win, ~0, &evt ); | ||||
|       else  | ||||
| 	 have_event = XNextEvent( dpy, &evt ); | ||||
|  | ||||
|       if (have_event) { | ||||
| 	 fprintf(stderr, "got event type %d\n", evt.type); | ||||
| 	 idle = GL_FALSE; | ||||
| 	 switch(evt.type) { | ||||
| 	 case MapNotify: | ||||
| 	    if (visibility_func) visibility_func(GLUT_VISIBLE); | ||||
| 	    break; | ||||
| 	 case UnmapNotify: | ||||
| 	    if (visibility_func) visibility_func(GLUT_NOT_VISIBLE); | ||||
| 	    break; | ||||
| 	 case Expose: | ||||
| 	    g_redisplay = 1; | ||||
| 	    break; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       if (g_redisplay && display_func) { | ||||
| 	 idle        = GL_FALSE; | ||||
| 	 g_redisplay = GL_FALSE; | ||||
|  | ||||
| 	 display_func(); | ||||
|       } | ||||
|  | ||||
|       if (idle && idle_func) { | ||||
| 	 idle_func(); | ||||
|       } | ||||
|    } | ||||
| } | ||||
|   | ||||
							
								
								
									
										134
									
								
								src/mesa/drivers/dri/r200/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/mesa/drivers/dri/r200/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| # $Id: Makefile,v 1.1.2.1 2003/03/10 11:23:04 keithw Exp $ | ||||
|  | ||||
| # Mesa 3-D graphics library | ||||
| # Version:  5.0 | ||||
| # Copyright (C) 1995-2002  Brian Paul | ||||
|  | ||||
|  | ||||
|  | ||||
| MESA = ../../.. | ||||
| default: r200_dri.so  | ||||
| include $(MESA)/Makefile.include | ||||
|  | ||||
|  | ||||
| SHARED_INCLUDES= -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -Iserver | ||||
| MINIGLX_INCLUDES = -I$(MESABUILDDIR)/miniglx  | ||||
| DRI_INCLUDES = -I$(MESABUILDDIR)/dri | ||||
|  | ||||
| ifeq ($(FULL_DRIVER),true) | ||||
| DEFINES = \ | ||||
| 	-DGLX_DIRECT_RENDERING \ | ||||
| -Dlinux -D__i386__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE  -D_GNU_SOURCE   -DFUNCPROTO=15 -DNARROWPROTO -DXTHREADS  -D_REENTRANT -DXUSE_MTSAFE_API    -DMALLOC_0_RETURNS_NULL -DGLXEXT -DXF86DRI -DGLX_DIRECT_RENDERING -DGLX_USE_DLOPEN -DGLX_USE_MESA  -DX_BYTE_ORDER=X_LITTLE_ENDIAN \ | ||||
| 	-D_HAVE_SWRAST=1 \ | ||||
| 	-D_HAVE_SWTNL=1 \ | ||||
| 	-D_HAVE_SANITY=1 \ | ||||
| 	-D_HAVE_CODEGEN=1 \ | ||||
| 	-D_HAVE_LIGHTING=1 \ | ||||
| 	-D_HAVE_TEXGEN=1 \ | ||||
| 	-D_HAVE_USERCLIP=1 \ | ||||
| 	-D_HAVE_FULL_GL=1 | ||||
| else | ||||
| DEFINES = \ | ||||
| 	-D_HAVE_SWRAST=0 \ | ||||
| 	-D_HAVE_SWTNL=0 \ | ||||
| 	-D_HAVE_SANITY=0 \ | ||||
| 	-D_HAVE_CODEGEN=0 \ | ||||
| 	-D_HAVE_LIGHTING=0 \ | ||||
| 	-D_HAVE_TEXGEN=0 \ | ||||
| 	-D_HAVE_USERCLIP=0 \ | ||||
| 	-D_HAVE_FULL_GL=0 | ||||
| endif | ||||
|  | ||||
| # The .a files for each mesa module required by this driver: | ||||
| # | ||||
| FULL_MESA = 	$(MESABUILDDIR)/swrast_setup/swrast_setup.a \ | ||||
| 		$(MESABUILDDIR)/tnl/tnl.a \ | ||||
| 		$(MESABUILDDIR)/math/math.a \ | ||||
| 		$(MESABUILDDIR)/array_cache/array_cache.a \ | ||||
| 		$(MESABUILDDIR)/swrast/swrast.a \ | ||||
| 		$(MESABUILDDIR)/mesa.a \ | ||||
| 		$(MESABUILDDIR)/math/math.a #kludge | ||||
|  | ||||
| SUBSET_MESA = 	$(MESABUILDDIR)/mesa.a \ | ||||
| 		$(MESABUILDDIR)/math/m_matrix.o | ||||
|  | ||||
|  | ||||
|  | ||||
| MINIGLX_SOURCES = server/radeon_dri.c  | ||||
|  | ||||
| DRIVER_SOURCES = r200_context.c \ | ||||
| 		 r200_ioctl.c \ | ||||
| 		 r200_lock.c \ | ||||
| 		 r200_screen.c \ | ||||
| 		 r200_state.c \ | ||||
| 		 r200_state_init.c \ | ||||
| 		 ../common/mm.c  | ||||
|  | ||||
| SUBSET_DRIVER_SOURCES = \ | ||||
| 		r200_subset_bitmap.c \ | ||||
| 		r200_subset_readpix.c \ | ||||
| 		r200_subset_select.c \ | ||||
| 		r200_subset_tex.c \ | ||||
| 		r200_subset_vtx.c  | ||||
|  | ||||
| FULL_DRIVER_SOURCES = 	\ | ||||
| 		 r200_cmdbuf.c \ | ||||
| 		 r200_pixel.c \ | ||||
| 		 r200_tex.c \ | ||||
| 		 r200_texmem.c \ | ||||
| 		 r200_texstate.c \ | ||||
| 		 r200_tcl.c \ | ||||
| 		 r200_swtcl.c \ | ||||
| 		 r200_span.c \ | ||||
| 		 r200_maos.c \ | ||||
| 		 r200_sanity.c \ | ||||
| 		 r200_vtxfmt.c \ | ||||
| 		 r200_vtxfmt_c.c \ | ||||
| 		 r200_vtxfmt_sse.c \ | ||||
| 		 r200_vtxfmt_x86.c  | ||||
|  | ||||
|  | ||||
| INCLUDES = $(MINIGLX_INCLUDES) \ | ||||
| 	   $(SHARED_INCLUDES) | ||||
|  | ||||
|  | ||||
| ifeq ($(FULL_DRIVER),true) | ||||
| C_SOURCES = $(DRIVER_SOURCES) \ | ||||
| 	    $(FULL_DRIVER_SOURCES) \ | ||||
| 	    $(MINIGLX_SOURCES)  | ||||
| MESA_MODULES = $(FULL_MESA) | ||||
| else | ||||
| C_SOURCES = $(DRIVER_SOURCES) \ | ||||
| 	    $(SUBSET_DRIVER_SOURCES) \ | ||||
| 	    $(MINIGLX_SOURCES)  | ||||
| MESA_MODULES = $(SUBSET_MESA) | ||||
| endif | ||||
|  | ||||
|  | ||||
| ifeq ($(WINDOW_SYSTEM),dri) | ||||
| WINOBJ=$(MESABUILDDIR)/dri/dri.a | ||||
| WINLIB= | ||||
| else | ||||
| WINOBJ= | ||||
| WINLIB=-L$(MESA)/src/miniglx | ||||
| endif | ||||
|  | ||||
| ASM_SOURCES =  | ||||
| OBJECTS = $(C_SOURCES:.c=.o) \ | ||||
| 	  $(ASM_SOURCES:.S=.o)  | ||||
|  | ||||
|  | ||||
|  | ||||
| ##### TARGETS ##### | ||||
|  | ||||
|  | ||||
| # Build the subset or full driver? | ||||
| # | ||||
| r200_dri.so:  $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile | ||||
| 	rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lGL -lc -lm -Wl,-rpath,../../../lib | ||||
| 	rm -f $(MESA)/lib/r200_dri.so && \ | ||||
| 	install r200_dri.so $(MESA)/lib/r200_dri.so | ||||
|  | ||||
| ##### DEPENDENCIES ##### | ||||
|  | ||||
| -include $(C_SOURCES:.c=.d) | ||||
							
								
								
									
										344
									
								
								src/mesa/drivers/dri/r200/r200_cmdbuf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								src/mesa/drivers/dri/r200/r200_cmdbuf.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,344 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "macros.h" | ||||
| #include "context.h" | ||||
| #include "swrast/swrast.h" | ||||
| #include "simple_list.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_sanity.h" | ||||
| #include "radeon_reg.h" | ||||
|  | ||||
| static void print_state_atom( struct r200_state_atom *state ) | ||||
| { | ||||
|    int i; | ||||
|  | ||||
|    fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); | ||||
|  | ||||
|    if (0 & R200_DEBUG & DEBUG_VERBOSE)  | ||||
|       for (i = 0 ; i < state->cmd_size ; i++)  | ||||
| 	 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); | ||||
|  | ||||
| } | ||||
|  | ||||
| static void r200_emit_state_list( r200ContextPtr rmesa,  | ||||
| 				    struct r200_state_atom *list ) | ||||
| { | ||||
|    struct r200_state_atom *state, *tmp; | ||||
|    char *dest; | ||||
|  | ||||
|    foreach_s( state, tmp, list ) { | ||||
|       if (state->check( rmesa->glCtx, state->idx )) { | ||||
| 	 dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__); | ||||
| 	 memcpy( dest, state->cmd, state->cmd_size * 4); | ||||
| 	 move_to_head( &(rmesa->hw.clean), state ); | ||||
| 	 if (R200_DEBUG & DEBUG_STATE)  | ||||
| 	    print_state_atom( state ); | ||||
|       } | ||||
|       else if (R200_DEBUG & DEBUG_STATE) | ||||
| 	 fprintf(stderr, "skip state %s\n", state->name); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200EmitState( r200ContextPtr rmesa ) | ||||
| { | ||||
|    struct r200_state_atom *state, *tmp; | ||||
|  | ||||
|    if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    /* Somewhat overkill: | ||||
|     */ | ||||
|    if ( rmesa->lost_context) { | ||||
|       if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL)) | ||||
| 	 fprintf(stderr, "%s - lost context\n", __FUNCTION__);  | ||||
|  | ||||
|       foreach_s( state, tmp, &(rmesa->hw.clean) )  | ||||
| 	 move_to_tail(&(rmesa->hw.dirty), state ); | ||||
|  | ||||
|       rmesa->lost_context = 0; | ||||
|    } | ||||
|    else { | ||||
|       move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] );  | ||||
|       /* odd bug? -- isosurf, cycle between reflect & lit */ | ||||
|    } | ||||
|  | ||||
|    r200_emit_state_list( rmesa, &rmesa->hw.dirty ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Fire a section of the retained (indexed_verts) buffer as a regular | ||||
|  * primtive.   | ||||
|  */ | ||||
| extern void r200EmitVbufPrim( r200ContextPtr rmesa, | ||||
| 				GLuint primitive, | ||||
| 				GLuint vertex_nr ) | ||||
| { | ||||
|    drmRadeonCmdHeader *cmd; | ||||
|  | ||||
|    assert(!(primitive & R200_VF_PRIM_WALK_IND)); | ||||
|     | ||||
|    r200EmitState( rmesa ); | ||||
|     | ||||
|    if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) | ||||
|       fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__, | ||||
| 	      rmesa->store.cmd_used/4, primitive, vertex_nr); | ||||
|     | ||||
|    cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 3 * sizeof(*cmd), | ||||
| 						  __FUNCTION__ ); | ||||
|    cmd[0].i = 0; | ||||
|    cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; | ||||
|    cmd[1].i = R200_CP_CMD_3D_DRAW_VBUF_2; | ||||
|    cmd[2].i = (primitive |  | ||||
| 	       R200_VF_PRIM_WALK_LIST | | ||||
| 	       R200_VF_COLOR_ORDER_RGBA | | ||||
| 	       (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT)); | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SYNC) { | ||||
|       fprintf(stderr, "\nSyncing\n\n"); | ||||
|       R200_FIREVERTICES( rmesa ); | ||||
|       r200Finish( rmesa->glCtx ); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200FlushElts( r200ContextPtr rmesa ) | ||||
| { | ||||
|    int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); | ||||
|    int dwords; | ||||
|    int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 12)) / 2; | ||||
|  | ||||
|    if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    assert( rmesa->dma.flush == r200FlushElts ); | ||||
|    rmesa->dma.flush = 0; | ||||
|  | ||||
|    /* Cope with odd number of elts: | ||||
|     */ | ||||
|    rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; | ||||
|    dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; | ||||
|  | ||||
|    cmd[1] |= (dwords - 3) << 16; | ||||
|    cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SYNC) { | ||||
|       fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); | ||||
|       R200_FIREVERTICES( rmesa ); | ||||
|       r200Finish( rmesa->glCtx ); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, | ||||
| 				    GLuint primitive, | ||||
| 				    GLuint min_nr ) | ||||
| { | ||||
|    drmRadeonCmdHeader *cmd; | ||||
|    GLushort *retval; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); | ||||
|  | ||||
|    assert((primitive & R200_VF_PRIM_WALK_IND)); | ||||
|     | ||||
|    r200EmitState( rmesa ); | ||||
|     | ||||
|    cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa,  | ||||
| 						12 + min_nr*2, | ||||
| 						__FUNCTION__ ); | ||||
|    cmd[0].i = 0; | ||||
|    cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; | ||||
|    cmd[1].i = R200_CP_CMD_3D_DRAW_INDX_2; | ||||
|    cmd[2].i = (primitive |  | ||||
| 	       R200_VF_PRIM_WALK_IND | | ||||
| 	       R200_VF_COLOR_ORDER_RGBA); | ||||
|  | ||||
|     | ||||
|    retval = (GLushort *)(cmd+3); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PRIMS) | ||||
|       fprintf(stderr, "%s: header 0x%x prim %x \n", | ||||
| 	      __FUNCTION__, | ||||
| 	      cmd[1].i, primitive); | ||||
|  | ||||
|    assert(!rmesa->dma.flush); | ||||
|    rmesa->dma.flush = r200FlushElts; | ||||
|  | ||||
|    rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; | ||||
|  | ||||
|    return retval; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200EmitVertexAOS( r200ContextPtr rmesa, | ||||
| 			  GLuint vertex_size, | ||||
| 			  GLuint offset ) | ||||
| { | ||||
|    drmRadeonCmdHeader *cmd; | ||||
|  | ||||
|    if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) | ||||
|       fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n", | ||||
| 	      __FUNCTION__, vertex_size, offset); | ||||
|  | ||||
|    cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 5 * sizeof(int), | ||||
| 						  __FUNCTION__ ); | ||||
|  | ||||
|    cmd[0].header.cmd_type = RADEON_CMD_PACKET3; | ||||
|    cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (2 << 16); | ||||
|    cmd[2].i = 1; | ||||
|    cmd[3].i = vertex_size | (vertex_size << 8); | ||||
|    cmd[4].i = offset; | ||||
| } | ||||
| 		        | ||||
|  | ||||
| void r200EmitAOS( r200ContextPtr rmesa, | ||||
| 		    struct r200_dma_region **component, | ||||
| 		    GLuint nr, | ||||
| 		    GLuint offset ) | ||||
| { | ||||
|    drmRadeonCmdHeader *cmd; | ||||
|    int sz = 3 + ((nr/2)*3) + ((nr&1)*2); | ||||
|    int i; | ||||
|    int *tmp; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr); | ||||
|  | ||||
|    cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sz * sizeof(int), | ||||
| 						  __FUNCTION__ ); | ||||
|    cmd[0].i = 0; | ||||
|    cmd[0].header.cmd_type = RADEON_CMD_PACKET3; | ||||
|    cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | ((sz-3) << 16); | ||||
|    cmd[2].i = nr; | ||||
|    tmp = &cmd[0].i; | ||||
|    cmd += 3; | ||||
|  | ||||
|    for (i = 0 ; i < nr ; i++) { | ||||
|       if (i & 1) { | ||||
| 	 cmd[0].i |= ((component[i]->aos_stride << 24) |  | ||||
| 		      (component[i]->aos_size << 16)); | ||||
| 	 cmd[2].i = (component[i]->aos_start +  | ||||
| 		     offset * component[i]->aos_stride * 4); | ||||
| 	 cmd += 3; | ||||
|       } | ||||
|       else { | ||||
| 	 cmd[0].i = ((component[i]->aos_stride << 8) |  | ||||
| 		     (component[i]->aos_size << 0)); | ||||
| 	 cmd[1].i = (component[i]->aos_start +  | ||||
| 		     offset * component[i]->aos_stride * 4); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) { | ||||
|       fprintf(stderr, "%s:\n", __FUNCTION__); | ||||
|       for (i = 0 ; i < sz ; i++) | ||||
| 	 fprintf(stderr, "   %d: %x\n", i, tmp[i]); | ||||
|    } | ||||
| } | ||||
|  | ||||
| void r200EmitBlit( r200ContextPtr rmesa, | ||||
| 		   GLuint color_fmt, | ||||
| 		   GLuint src_pitch, | ||||
| 		   GLuint src_offset, | ||||
| 		   GLuint dst_pitch, | ||||
| 		   GLuint dst_offset, | ||||
| 		   GLint srcx, GLint srcy, | ||||
| 		   GLint dstx, GLint dsty, | ||||
| 		   GLuint w, GLuint h ) | ||||
| { | ||||
|    drmRadeonCmdHeader *cmd; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", | ||||
| 	      __FUNCTION__,  | ||||
| 	      src_pitch, src_offset, srcx, srcy, | ||||
| 	      dst_pitch, dst_offset, dstx, dsty, | ||||
| 	      w, h); | ||||
|  | ||||
|    assert( (src_pitch & 63) == 0 ); | ||||
|    assert( (dst_pitch & 63) == 0 ); | ||||
|    assert( (src_offset & 1023) == 0 ); | ||||
|    assert( (dst_offset & 1023) == 0 ); | ||||
|    assert( w < (1<<16) ); | ||||
|    assert( h < (1<<16) ); | ||||
|  | ||||
|    cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 8 * sizeof(int), | ||||
| 						  __FUNCTION__ ); | ||||
|  | ||||
|  | ||||
|    cmd[0].header.cmd_type = RADEON_CMD_PACKET3; | ||||
|    cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16); | ||||
|    cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | | ||||
| 	       RADEON_GMC_DST_PITCH_OFFSET_CNTL | | ||||
| 	       RADEON_GMC_BRUSH_NONE | | ||||
| 	       (color_fmt << 8) | | ||||
| 	       RADEON_GMC_SRC_DATATYPE_COLOR | | ||||
| 	       RADEON_ROP3_S | | ||||
| 	       RADEON_DP_SRC_SOURCE_MEMORY | | ||||
| 	       RADEON_GMC_CLR_CMP_CNTL_DIS | | ||||
| 	       RADEON_GMC_WR_MSK_DIS ); | ||||
|  | ||||
|    cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); | ||||
|    cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); | ||||
|    cmd[5].i = (srcx << 16) | srcy; | ||||
|    cmd[6].i = (dstx << 16) | dsty; /* dst */ | ||||
|    cmd[7].i = (w << 16) | h; | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200EmitWait( r200ContextPtr rmesa, GLuint flags ) | ||||
| { | ||||
|    if (rmesa->dri.drmMinor >= 6) { | ||||
|       drmRadeonCmdHeader *cmd; | ||||
|  | ||||
|       assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); | ||||
|        | ||||
|       cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 1 * sizeof(int), | ||||
| 						   __FUNCTION__ ); | ||||
|       cmd[0].i = 0; | ||||
|       cmd[0].wait.cmd_type = RADEON_CMD_WAIT; | ||||
|       cmd[0].wait.flags = flags; | ||||
|    } | ||||
| } | ||||
							
								
								
									
										673
									
								
								src/mesa/drivers/dri/r200/r200_context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										673
									
								
								src/mesa/drivers/dri/r200/r200_context.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,673 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "api_arrayelt.h" | ||||
| #include "context.h" | ||||
| #include "simple_list.h" | ||||
| #include "imports.h" | ||||
| #include "matrix.h" | ||||
| #include "state.h" | ||||
| #include "extensions.h" | ||||
| #include "state.h" | ||||
|  | ||||
| #include "swrast/swrast.h" | ||||
| #include "swrast_setup/swrast_setup.h" | ||||
| #include "array_cache/acache.h" | ||||
|  | ||||
| #include "tnl/tnl.h" | ||||
| #include "tnl/t_pipeline.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_span.h" | ||||
| #include "r200_pixel.h" | ||||
| #include "r200_tex.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_vtxfmt.h" | ||||
| #include "r200_maos.h" | ||||
|  | ||||
| #if defined(USE_X86_ASM) | ||||
| #include "X86/common_x86_asm.h" | ||||
| #endif | ||||
|  | ||||
| #define R200_DATE	"20021125" | ||||
|  | ||||
| #ifndef R200_DEBUG | ||||
| int R200_DEBUG = (0); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Return the width and height of the given buffer. | ||||
|  */ | ||||
| static void r200GetBufferSize( GLframebuffer *buffer, | ||||
| 			       GLuint *width, GLuint *height ) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|    *width  = rmesa->dri.drawable->w; | ||||
|    *height = rmesa->dri.drawable->h; | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
| } | ||||
|  | ||||
| /* Return various strings for glGetString(). | ||||
|  */ | ||||
| static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    static char buffer[128]; | ||||
|  | ||||
|    switch ( name ) { | ||||
|    case GL_VENDOR: | ||||
|       return (GLubyte *)"Tungsten Graphics, Inc."; | ||||
|  | ||||
|    case GL_RENDERER: | ||||
|       sprintf( buffer, "Mesa DRI R200 " R200_DATE); | ||||
|  | ||||
|       /* Append any chipset-specific information.  None yet. | ||||
|        */ | ||||
|  | ||||
|       /* Append any AGP-specific information. | ||||
|        */ | ||||
|       switch ( rmesa->r200Screen->AGPMode ) { | ||||
|       case 1: | ||||
| 	 strncat( buffer, " AGP 1x", 7 ); | ||||
| 	 break; | ||||
|       case 2: | ||||
| 	 strncat( buffer, " AGP 2x", 7 ); | ||||
| 	 break; | ||||
|       case 4: | ||||
| 	 strncat( buffer, " AGP 4x", 7 ); | ||||
| 	 break; | ||||
|       } | ||||
|  | ||||
|       /* Append any CPU-specific information. | ||||
|        */ | ||||
| #ifdef USE_X86_ASM | ||||
|       if ( _mesa_x86_cpu_features ) { | ||||
| 	 strncat( buffer, " x86", 4 ); | ||||
|       } | ||||
| #ifdef USE_MMX_ASM | ||||
|       if ( cpu_has_mmx ) { | ||||
| 	 strncat( buffer, "/MMX", 4 ); | ||||
|       } | ||||
| #endif | ||||
| #ifdef USE_3DNOW_ASM | ||||
|       if ( cpu_has_3dnow ) { | ||||
| 	 strncat( buffer, "/3DNow!", 7 ); | ||||
|       } | ||||
| #endif | ||||
| #ifdef USE_SSE_ASM | ||||
|       if ( cpu_has_xmm ) { | ||||
| 	 strncat( buffer, "/SSE", 4 ); | ||||
|       } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|       if ( !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) ) { | ||||
| 	 strncat( buffer, " TCL", 4 ); | ||||
|       } | ||||
|       else { | ||||
| 	 strncat( buffer, " NO-TCL", 7 ); | ||||
|       } | ||||
|  | ||||
|       return (GLubyte *)buffer; | ||||
|  | ||||
|    default: | ||||
|       return NULL; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Initialize the extensions supported by this driver. | ||||
|  */ | ||||
| static void r200InitExtensions( GLcontext *ctx, r200ScreenPtr r200Screen ) | ||||
| { | ||||
|    _mesa_enable_imaging_extensions( ctx ); | ||||
|  | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); | ||||
|    if (r200Screen->drmSupportsCubeMaps) | ||||
|       _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_texture_env_dot3" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_texture_mirrored_repeat" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ARB_texture_border_clamp" ); | ||||
|  | ||||
|    _mesa_enable_extension( ctx, "GL_ATI_texture_env_combine3" ); | ||||
|    _mesa_enable_extension( ctx, "GL_ATI_texture_mirror_once" ); | ||||
|  | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_blend_logic_op" ); | ||||
|    /*_mesa_enable_extension( ctx, "GL_EXT_fog_coord" );*/ | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_edge_clamp" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_env_dot3" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_filter_anisotropic" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_secondary_color" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); | ||||
|    _mesa_enable_extension( ctx, "GL_EXT_blend_minmax" ); | ||||
|  | ||||
| /*     _mesa_enable_extension( ctx, "GL_EXT_fog_coord" ); */ | ||||
|  | ||||
|    _mesa_enable_extension( ctx, "GL_MESA_pack_invert" ); | ||||
|    _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); | ||||
|    _mesa_enable_extension( ctx, "GL_NV_texture_rectangle" ); | ||||
| } | ||||
|  | ||||
| extern const struct gl_pipeline_stage _r200_render_stage; | ||||
| extern const struct gl_pipeline_stage _r200_tcl_stage; | ||||
|  | ||||
| static const struct gl_pipeline_stage *r200_pipeline[] = { | ||||
|  | ||||
|    /* Try and go straight to t&l | ||||
|     */ | ||||
|    &_r200_tcl_stage,   | ||||
|  | ||||
|    /* Catch any t&l fallbacks | ||||
|     */ | ||||
|    &_tnl_vertex_transform_stage, | ||||
|    &_tnl_normal_transform_stage, | ||||
|    &_tnl_lighting_stage, | ||||
|    &_tnl_fog_coordinate_stage, | ||||
|    &_tnl_texgen_stage, | ||||
|    &_tnl_texture_transform_stage, | ||||
|  | ||||
|    /* Try again to go to tcl?  | ||||
|     *     - no good for asymmetric-twoside (do with multipass) | ||||
|     *     - no good for asymmetric-unfilled (do with multipass) | ||||
|     *     - good for material | ||||
|     *     - good for texgen | ||||
|     *     - need to manipulate a bit of state | ||||
|     * | ||||
|     * - worth it/not worth it? | ||||
|     */ | ||||
| 			 | ||||
|    /* Else do them here. | ||||
|     */ | ||||
|    &_r200_render_stage,  | ||||
|    &_tnl_render_stage,		/* FALLBACK:  */ | ||||
|    0, | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Initialize the driver's misc functions. | ||||
|  */ | ||||
| static void r200InitDriverFuncs( GLcontext *ctx ) | ||||
| { | ||||
|     ctx->Driver.GetBufferSize		= r200GetBufferSize; | ||||
|     ctx->Driver.ResizeBuffers           = _swrast_alloc_buffers; | ||||
|     ctx->Driver.GetString		= r200GetString; | ||||
|  | ||||
|     ctx->Driver.Error			= NULL; | ||||
|     ctx->Driver.DrawPixels		= NULL; | ||||
|     ctx->Driver.Bitmap			= NULL; | ||||
| } | ||||
|  | ||||
| static void add_debug_flags( const char *debug ) | ||||
| { | ||||
|    if (strstr(debug, "fall"))  | ||||
|       R200_DEBUG |= DEBUG_FALLBACKS; | ||||
|  | ||||
|    if (strstr(debug, "tex"))  | ||||
|       R200_DEBUG |= DEBUG_TEXTURE; | ||||
|  | ||||
|    if (strstr(debug, "ioctl"))  | ||||
|       R200_DEBUG |= DEBUG_IOCTL; | ||||
|  | ||||
|    if (strstr(debug, "prim"))  | ||||
|       R200_DEBUG |= DEBUG_PRIMS; | ||||
|  | ||||
|    if (strstr(debug, "vert"))  | ||||
|       R200_DEBUG |= DEBUG_VERTS; | ||||
|  | ||||
|    if (strstr(debug, "state"))  | ||||
|       R200_DEBUG |= DEBUG_STATE; | ||||
|  | ||||
|    if (strstr(debug, "code"))  | ||||
|       R200_DEBUG |= DEBUG_CODEGEN; | ||||
|  | ||||
|    if (strstr(debug, "vfmt") || strstr(debug, "vtxf"))  | ||||
|       R200_DEBUG |= DEBUG_VFMT; | ||||
|  | ||||
|    if (strstr(debug, "verb"))  | ||||
|       R200_DEBUG |= DEBUG_VERBOSE; | ||||
|  | ||||
|    if (strstr(debug, "dri"))  | ||||
|       R200_DEBUG |= DEBUG_DRI; | ||||
|  | ||||
|    if (strstr(debug, "dma"))  | ||||
|       R200_DEBUG |= DEBUG_DMA; | ||||
|  | ||||
|    if (strstr(debug, "san"))  | ||||
|       R200_DEBUG |= DEBUG_SANITY; | ||||
|  | ||||
|    if (strstr(debug, "sync"))  | ||||
|       R200_DEBUG |= DEBUG_SYNC; | ||||
|  | ||||
|    if (strstr(debug, "pix"))  | ||||
|       R200_DEBUG |= DEBUG_PIXEL; | ||||
|  | ||||
|    if (strstr(debug, "mem"))  | ||||
|       R200_DEBUG |= DEBUG_MEMORY; | ||||
| } | ||||
|  | ||||
| /* Create the device specific context. | ||||
|  */ | ||||
| GLboolean r200CreateContext( const __GLcontextModes *glVisual, | ||||
| 			     __DRIcontextPrivate *driContextPriv, | ||||
| 			     void *sharedContextPrivate) | ||||
| { | ||||
|    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; | ||||
|    r200ScreenPtr r200Screen = (r200ScreenPtr)(sPriv->private); | ||||
|    r200ContextPtr rmesa; | ||||
|    GLcontext *ctx, *shareCtx; | ||||
|    int i, memPerUnit; | ||||
|  | ||||
|    assert(glVisual); | ||||
|    assert(driContextPriv); | ||||
|    assert(r200Screen); | ||||
|  | ||||
|    /* Allocate the R200 context */ | ||||
|    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); | ||||
|    if ( !rmesa ) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* Allocate the Mesa context */ | ||||
|    if (sharedContextPrivate) | ||||
|       shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx; | ||||
|    else | ||||
|       shareCtx = NULL; | ||||
|    rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) rmesa, GL_TRUE); | ||||
|    if (!rmesa->glCtx) { | ||||
|       FREE(rmesa); | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|    driContextPriv->driverPrivate = rmesa; | ||||
|  | ||||
|    /* Init r200 context data */ | ||||
|    rmesa->dri.context = driContextPriv; | ||||
|    rmesa->dri.screen = sPriv; | ||||
|    rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */ | ||||
|    rmesa->dri.hwContext = driContextPriv->hHWContext; | ||||
|    rmesa->dri.hwLock = &sPriv->pSAREA->lock; | ||||
|    rmesa->dri.fd = sPriv->fd; | ||||
|    rmesa->dri.drmMinor = sPriv->drmMinor; | ||||
|  | ||||
|    rmesa->r200Screen = r200Screen; | ||||
|    rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA + | ||||
| 				       r200Screen->sarea_priv_offset); | ||||
|  | ||||
|  | ||||
|    rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address; | ||||
|  | ||||
|    for ( i = 0 ; i < r200Screen->numTexHeaps ; i++ ) { | ||||
|       make_empty_list( &rmesa->texture.objects[i] ); | ||||
|       rmesa->texture.heap[i] = mmInit( 0, r200Screen->texSize[i] ); | ||||
|       rmesa->texture.age[i] = -1; | ||||
|    } | ||||
|    rmesa->texture.numHeaps = r200Screen->numTexHeaps; | ||||
|    make_empty_list( &rmesa->texture.swapped ); | ||||
|  | ||||
|    rmesa->swtcl.RenderIndex = ~0; | ||||
|    rmesa->lost_context = 1; | ||||
|  | ||||
|    /* KW: Set the maximum texture size small enough that we can | ||||
|     * guarentee that both texture units can bind a maximal texture | ||||
|     * and have them both in on-card memory at once. | ||||
|     * Test for 2 textures * 4 bytes/texel * size * size. | ||||
|     */ | ||||
|    ctx = rmesa->glCtx; | ||||
|    memPerUnit = r200Screen->texSize[RADEON_CARD_HEAP] / 2; | ||||
|  | ||||
|    /* XXX the following code could go into a utility file */ | ||||
|    if (memPerUnit >= 4 * 2048 * 2048) { | ||||
|       ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 1024 * 1024) { | ||||
|       ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 512 * 512) { | ||||
|       ctx->Const.MaxTextureLevels = 10; /* 512x512 */ | ||||
|    } | ||||
|    else { | ||||
|       ctx->Const.MaxTextureLevels = 9; /* 256x256 */ | ||||
|    } | ||||
|  | ||||
| #if ENABLE_HW_3D_TEXTURE | ||||
|    if (memPerUnit >= 4 * 256 * 256 * 256) { | ||||
|       ctx->Const.Max3DTextureLevels = 9; /* 256x256x256 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 64 * 64 * 64) { | ||||
|       ctx->Const.Max3DTextureLevels = 8; /* 128x128x128 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 32 * 32 * 32) { | ||||
|       ctx->Const.Max3DTextureLevels = 7; /* 64x64x64 */ | ||||
|    } | ||||
|    else { /* 256KBytes */ | ||||
|       ctx->Const.Max3DTextureLevels = 6; /* 32x32x32 */ | ||||
|    } | ||||
| #endif | ||||
|  | ||||
|    if (memPerUnit >= 4 * 6 * 2048 * 2048) { | ||||
|       ctx->Const.MaxCubeTextureLevels = 12; /* 2048x2048 */ | ||||
|    } | ||||
|    if (memPerUnit >= 4 * 6 * 1024 * 1024) { | ||||
|       ctx->Const.MaxCubeTextureLevels = 11; /* 1024x1024 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 6 * 512 * 512) { | ||||
|       ctx->Const.MaxCubeTextureLevels = 10; /* 512x512 */ | ||||
|    } | ||||
|    else if (memPerUnit >= 4 * 6 * 256 * 256) { | ||||
|       ctx->Const.MaxCubeTextureLevels = 9; /* 256x256 */ | ||||
|    } | ||||
|    else { /* 393216 bytes */ | ||||
|       ctx->Const.MaxCubeTextureLevels = 8; /* 128x128 */ | ||||
|    } | ||||
|  | ||||
|    ctx->Const.MaxTextureUnits = 2; | ||||
|    ctx->Const.MaxTextureMaxAnisotropy = 16.0; | ||||
|  | ||||
|    /* No wide points. | ||||
|     */ | ||||
|    ctx->Const.MinPointSize = 1.0; | ||||
|    ctx->Const.MinPointSizeAA = 1.0; | ||||
|    ctx->Const.MaxPointSize = 1.0; | ||||
|    ctx->Const.MaxPointSizeAA = 1.0; | ||||
|  | ||||
|    ctx->Const.MinLineWidth = 1.0; | ||||
|    ctx->Const.MinLineWidthAA = 1.0; | ||||
|    ctx->Const.MaxLineWidth = 10.0; | ||||
|    ctx->Const.MaxLineWidthAA = 10.0; | ||||
|    ctx->Const.LineWidthGranularity = 0.0625; | ||||
|  | ||||
|    /* Initialize the software rasterizer and helper modules. | ||||
|     */ | ||||
|    _swrast_CreateContext( ctx ); | ||||
|    _ac_CreateContext( ctx ); | ||||
|    _tnl_CreateContext( ctx ); | ||||
|    _swsetup_CreateContext( ctx ); | ||||
|    _ae_create_context( ctx ); | ||||
|  | ||||
|    /* Install the customized pipeline: | ||||
|     */ | ||||
|    _tnl_destroy_pipeline( ctx ); | ||||
|    _tnl_install_pipeline( ctx, r200_pipeline ); | ||||
|    ctx->Driver.FlushVertices = r200FlushVertices; | ||||
|  | ||||
|    /* Try and keep materials and vertices separate: | ||||
|     */ | ||||
|    _tnl_isolate_materials( ctx, GL_TRUE ); | ||||
|  | ||||
|  | ||||
|    /* Configure swrast to match hardware characteristics: | ||||
|     */ | ||||
|    _swrast_allow_pixel_fog( ctx, GL_FALSE ); | ||||
|    _swrast_allow_vertex_fog( ctx, GL_TRUE ); | ||||
|  | ||||
|  | ||||
|    _math_matrix_ctr( &rmesa->TexGenMatrix[0] ); | ||||
|    _math_matrix_ctr( &rmesa->TexGenMatrix[1] ); | ||||
|    _math_matrix_ctr( &rmesa->tmpmat ); | ||||
|    _math_matrix_set_identity( &rmesa->TexGenMatrix[0] ); | ||||
|    _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); | ||||
|    _math_matrix_set_identity( &rmesa->tmpmat ); | ||||
|  | ||||
|    r200InitExtensions( ctx, r200Screen ); | ||||
|    r200InitDriverFuncs( ctx ); | ||||
|    r200InitIoctlFuncs( ctx ); | ||||
|    r200InitStateFuncs( ctx ); | ||||
|    r200InitSpanFuncs( ctx ); | ||||
|    r200InitPixelFuncs( ctx ); | ||||
|    r200InitTextureFuncs( ctx ); | ||||
|    r200InitState( rmesa ); | ||||
|    r200InitSwtcl( ctx ); | ||||
|  | ||||
|    rmesa->iw.irq_seq = -1; | ||||
|    rmesa->irqsEmitted = 0; | ||||
|    rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 &&  | ||||
| 		     !getenv("R200_NO_IRQS") && | ||||
| 		     rmesa->r200Screen->irq); | ||||
|  | ||||
|    if (!rmesa->do_irqs) | ||||
|       fprintf(stderr,  | ||||
| 	      "IRQ's not enabled, falling back to busy waits: %d %d %d\n", | ||||
| 	      rmesa->dri.drmMinor, | ||||
| 	      !!getenv("R200_NO_IRQS"), | ||||
| 	      rmesa->r200Screen->irq); | ||||
|  | ||||
|  | ||||
|    rmesa->do_usleeps = !getenv("R200_NO_USLEEPS"); | ||||
|    rmesa->prefer_agp_client_texturing =  | ||||
|       (getenv("R200_AGP_CLIENT_TEXTURES") != 0); | ||||
|     | ||||
|     | ||||
| #if DO_DEBUG | ||||
|    if (getenv("R200_DEBUG")) | ||||
|       add_debug_flags( getenv("R200_DEBUG") ); | ||||
|    if (getenv("RADEON_DEBUG")) | ||||
|       add_debug_flags( getenv("RADEON_DEBUG") ); | ||||
| #endif | ||||
|  | ||||
|    if (getenv("R200_NO_RAST")) { | ||||
|       fprintf(stderr, "disabling 3D acceleration\n"); | ||||
|       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);  | ||||
|    } | ||||
|    else if (getenv("R200_NO_TCL")) { | ||||
|       fprintf(stderr, "disabling TCL support\n"); | ||||
|       TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);  | ||||
|    } | ||||
|    else { | ||||
|       if (!getenv("R200_NO_VTXFMT")) { | ||||
| 	 r200VtxfmtInit( ctx ); | ||||
|       } | ||||
|       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); | ||||
|    } | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Destroy the device specific context. | ||||
|  */ | ||||
| /* Destroy the Mesa and driver specific context data. | ||||
|  */ | ||||
| void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; | ||||
|    r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL; | ||||
|  | ||||
|    /* check if we're deleting the currently bound context */ | ||||
|    if (rmesa == current) { | ||||
|       R200_FIREVERTICES( rmesa ); | ||||
|       _mesa_make_current2(NULL, NULL, NULL); | ||||
|    } | ||||
|  | ||||
|    /* Free r200 context resources */ | ||||
|    assert(rmesa); /* should never be null */ | ||||
|    if ( rmesa ) { | ||||
|       if (rmesa->glCtx->Shared->RefCount == 1) { | ||||
|          /* This share group is about to go away, free our private | ||||
|           * texture object data. | ||||
|           */ | ||||
|          r200TexObjPtr t, next_t; | ||||
|          int i; | ||||
|  | ||||
|          for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { | ||||
|             foreach_s ( t, next_t, &rmesa->texture.objects[i] ) { | ||||
|                r200DestroyTexObj( rmesa, t ); | ||||
|             } | ||||
|             mmDestroy( rmesa->texture.heap[i] ); | ||||
| 	    rmesa->texture.heap[i] = NULL; | ||||
|          } | ||||
|  | ||||
|          foreach_s ( t, next_t, &rmesa->texture.swapped ) { | ||||
|             r200DestroyTexObj( rmesa, t ); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       _swsetup_DestroyContext( rmesa->glCtx ); | ||||
|       _tnl_DestroyContext( rmesa->glCtx ); | ||||
|       _ac_DestroyContext( rmesa->glCtx ); | ||||
|       _swrast_DestroyContext( rmesa->glCtx ); | ||||
|  | ||||
|       r200DestroySwtcl( rmesa->glCtx ); | ||||
|  | ||||
|       r200ReleaseArrays( rmesa->glCtx, ~0 ); | ||||
|  | ||||
|       if (rmesa->dma.current.buf) { | ||||
| 	 r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); | ||||
| 	 r200FlushCmdBuf( rmesa, __FUNCTION__ ); | ||||
|       } | ||||
|  | ||||
|       if (!rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) | ||||
| 	 if (!getenv("R200_NO_VTXFMT")) | ||||
| 	    r200VtxfmtDestroy( rmesa->glCtx ); | ||||
|  | ||||
|       /* free the Mesa context */ | ||||
|       rmesa->glCtx->DriverCtx = NULL; | ||||
|       _mesa_destroy_context( rmesa->glCtx ); | ||||
|  | ||||
|       if (rmesa->state.scissor.pClipRects) { | ||||
| 	 FREE(rmesa->state.scissor.pClipRects); | ||||
| 	 rmesa->state.scissor.pClipRects = 0; | ||||
|       } | ||||
|  | ||||
|       FREE( rmesa ); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void | ||||
| r200SwapBuffers( __DRIdrawablePrivate *dPriv ) | ||||
| { | ||||
|    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { | ||||
|       r200ContextPtr rmesa; | ||||
|       GLcontext *ctx; | ||||
|       rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; | ||||
|       ctx = rmesa->glCtx; | ||||
|       if (ctx->Visual.doubleBufferMode) { | ||||
|          _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */ | ||||
|          if ( rmesa->doPageFlip ) { | ||||
|             r200PageFlip( dPriv ); | ||||
|          } | ||||
|          else { | ||||
|             r200CopyBuffer( dPriv ); | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       /* XXX this shouldn't be an error but we can't handle it for now */ | ||||
|       _mesa_problem(NULL, "r200SwapBuffers: drawable has no context!\n"); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Force the context `c' to be the current context and associate with it | ||||
|  * buffer `b'. | ||||
|  */ | ||||
| GLboolean | ||||
| r200MakeCurrent( __DRIcontextPrivate *driContextPriv, | ||||
|                    __DRIdrawablePrivate *driDrawPriv, | ||||
|                    __DRIdrawablePrivate *driReadPriv ) | ||||
| { | ||||
|    if ( driContextPriv ) { | ||||
|       r200ContextPtr newR200Ctx =  | ||||
| 	 (r200ContextPtr) driContextPriv->driverPrivate; | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_DRI) | ||||
| 	 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newR200Ctx->glCtx); | ||||
|  | ||||
|       if ( newR200Ctx->dri.drawable != driDrawPriv ) { | ||||
| 	 newR200Ctx->dri.drawable = driDrawPriv; | ||||
| 	 r200UpdateWindow( newR200Ctx->glCtx ); | ||||
| 	 r200UpdateViewportOffset( newR200Ctx->glCtx ); | ||||
|       } | ||||
|  | ||||
|       _mesa_make_current2( newR200Ctx->glCtx, | ||||
| 			   (GLframebuffer *) driDrawPriv->driverPrivate, | ||||
| 			   (GLframebuffer *) driReadPriv->driverPrivate ); | ||||
|  | ||||
|       if ( !newR200Ctx->glCtx->Viewport.Width ) { | ||||
| 	 _mesa_set_viewport( newR200Ctx->glCtx, 0, 0, | ||||
| 			     driDrawPriv->w, driDrawPriv->h ); | ||||
|       } | ||||
|  | ||||
|       if (newR200Ctx->vb.enabled) | ||||
| 	 r200VtxfmtMakeCurrent( newR200Ctx->glCtx ); | ||||
|  | ||||
|       _mesa_update_state( newR200Ctx->glCtx ); | ||||
|       r200ValidateState( newR200Ctx->glCtx ); | ||||
|  | ||||
|    } else { | ||||
|       if (R200_DEBUG & DEBUG_DRI) | ||||
| 	 fprintf(stderr, "%s ctx is null\n", __FUNCTION__); | ||||
|       _mesa_make_current( 0, 0 ); | ||||
|    } | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_DRI) | ||||
|       fprintf(stderr, "End %s\n", __FUNCTION__); | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| /* Force the context `c' to be unbound from its buffer. | ||||
|  */ | ||||
| GLboolean | ||||
| r200UnbindContext( __DRIcontextPrivate *driContextPriv ) | ||||
| { | ||||
|    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_DRI) | ||||
|       fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx); | ||||
|  | ||||
|    r200VtxfmtUnbindContext( rmesa->glCtx ); | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										944
									
								
								src/mesa/drivers/dri/r200/r200_context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										944
									
								
								src/mesa/drivers/dri/r200/r200_context.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,944 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_CONTEXT_H__ | ||||
| #define __R200_CONTEXT_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "dri_util.h" | ||||
| #include "radeon_common.h" | ||||
|  | ||||
| #include "macros.h" | ||||
| #include "mtypes.h" | ||||
| #include "r200_reg.h" | ||||
|  | ||||
| #define ENABLE_HW_3D_TEXTURE 0  /* XXX this is temporary! */ | ||||
|  | ||||
| struct r200_context; | ||||
| typedef struct r200_context r200ContextRec; | ||||
| typedef struct r200_context *r200ContextPtr; | ||||
|  | ||||
| #include "r200_lock.h" | ||||
| #include "r200_screen.h" | ||||
| #include "mm.h" | ||||
|  | ||||
| /* Flags for software fallback cases */ | ||||
| /* See correponding strings in r200_swtcl.c */ | ||||
| #define R200_FALLBACK_TEXTURE           0x1 | ||||
| #define R200_FALLBACK_DRAW_BUFFER       0x2 | ||||
| #define R200_FALLBACK_STENCIL           0x4 | ||||
| #define R200_FALLBACK_RENDER_MODE       0x8 | ||||
| #define R200_FALLBACK_BLEND_EQ          0x10 | ||||
| #define R200_FALLBACK_BLEND_FUNC        0x20 | ||||
| #define R200_FALLBACK_DISABLE           0x40 | ||||
|  | ||||
| /* The blit width for texture uploads | ||||
|  */ | ||||
| #define BLIT_WIDTH_BYTES 1024 | ||||
|  | ||||
| /* Use the templated vertex format: | ||||
|  */ | ||||
| #define COLOR_IS_RGBA | ||||
| #define TAG(x) r200##x | ||||
| #include "tnl_dd/t_dd_vertex.h" | ||||
| #undef TAG | ||||
|  | ||||
| typedef void (*r200_tri_func)( r200ContextPtr, | ||||
| 				 r200Vertex *, | ||||
| 				 r200Vertex *, | ||||
| 				 r200Vertex * ); | ||||
|  | ||||
| typedef void (*r200_line_func)( r200ContextPtr, | ||||
| 				  r200Vertex *, | ||||
| 				  r200Vertex * ); | ||||
|  | ||||
| typedef void (*r200_point_func)( r200ContextPtr, | ||||
| 				   r200Vertex * ); | ||||
|  | ||||
|  | ||||
| struct r200_colorbuffer_state { | ||||
|    GLuint clear; | ||||
|    GLint drawOffset, drawPitch; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_depthbuffer_state { | ||||
|    GLfloat scale; | ||||
| }; | ||||
|  | ||||
| struct r200_pixel_state { | ||||
|    GLint readOffset, readPitch; | ||||
| }; | ||||
|  | ||||
| struct r200_scissor_state { | ||||
|    XF86DRIClipRectRec rect; | ||||
|    GLboolean enabled; | ||||
|  | ||||
|    GLuint numClipRects;			/* Cliprects active */ | ||||
|    GLuint numAllocedClipRects;		/* Cliprects available */ | ||||
|    XF86DRIClipRectPtr pClipRects; | ||||
| }; | ||||
|  | ||||
| struct r200_stencilbuffer_state { | ||||
|    GLboolean hwBuffer; | ||||
|    GLuint clear;			/* rb3d_stencilrefmask value */ | ||||
| }; | ||||
|  | ||||
| struct r200_stipple_state { | ||||
|    GLuint mask[32]; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| #define TEX_0   0x1 | ||||
| #define TEX_1   0x2 | ||||
| #define TEX_ALL 0x3 | ||||
|  | ||||
| typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; | ||||
|  | ||||
| /* Texture object in locally shared texture space. | ||||
|  */ | ||||
| struct r200_tex_obj { | ||||
|    r200TexObjPtr next, prev; | ||||
|  | ||||
|    struct gl_texture_object *tObj;	/* Mesa texture object */ | ||||
|  | ||||
|    PMemBlock memBlock;			/* Memory block containing texture */ | ||||
|    GLuint bufAddr;			/* Offset to start of locally | ||||
| 					   shared texture block */ | ||||
|  | ||||
|    GLuint dirty_images[6];		/* Flags for whether or not | ||||
| 					   images need to be uploaded to | ||||
| 					   local or AGP texture space. | ||||
| 					   Six cube faces. */ | ||||
|  | ||||
|    GLuint dirty_state;		        /* Flags (1 per texunit) for | ||||
| 					   whether or not this texobj | ||||
| 					   has dirty hardware state | ||||
| 					   (pp_*) that needs to be | ||||
| 					   brought into the | ||||
| 					   texunit. */ | ||||
|  | ||||
|    GLint heap;				/* Texture heap currently stored in */ | ||||
|  | ||||
|    drmRadeonTexImage image[6][RADEON_MAX_TEXTURE_LEVELS]; | ||||
| 					/* Six, for the cube faces */ | ||||
|  | ||||
|    GLint totalSize;			/* Total size of the texture | ||||
| 					   including all mipmap levels, | ||||
| 					   and all six cube faces */ | ||||
|  | ||||
|    GLuint pp_txfilter;		        /* hardware register values */ | ||||
|    GLuint pp_txformat; | ||||
|    GLuint pp_txformat_x; | ||||
|    GLuint pp_txoffset;		        /* Image location in texmem. | ||||
| 					   All cube faces follow. */ | ||||
|    GLuint pp_txsize;		        /* npot only */ | ||||
|    GLuint pp_txpitch;		        /* npot only */ | ||||
|    GLuint pp_border_color; | ||||
|    GLuint pp_cubic_faces;	        /* cube face 1,2,3,4 log2 sizes */ | ||||
|  | ||||
|    /* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the | ||||
|     * images to upload. | ||||
|     */ | ||||
|    GLint firstLevel;      | ||||
|    GLint lastLevel;       | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_texture_env_state { | ||||
|    r200TexObjPtr texobj; | ||||
|    GLenum format; | ||||
|    GLenum envMode; | ||||
| }; | ||||
|  | ||||
| #define R200_MAX_TEXTURE_UNITS 3 | ||||
|  | ||||
| struct r200_texture_state { | ||||
|    struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_state_atom { | ||||
|    struct r200_state_atom *next, *prev; | ||||
|    const char *name;		         /* for debug */ | ||||
|    int cmd_size;		         /* size in bytes */ | ||||
|    GLuint idx; | ||||
|    int *cmd;			         /* one or more cmd's */ | ||||
|    int *lastcmd;			 /* one or more cmd's */ | ||||
|    GLboolean (*check)( GLcontext *, int );    /* is this state active? */ | ||||
| }; | ||||
|     | ||||
|  | ||||
|  | ||||
| /* Trying to keep these relatively short as the variables are becoming | ||||
|  * extravagently long.  Drop the R200_ off the front of everything - | ||||
|  * I think we know we're in the r200 driver by now, and keep the | ||||
|  * prefix to 3 letters unless absolutely impossible.   | ||||
|  */ | ||||
|  | ||||
| #define CTX_CMD_0             0 | ||||
| #define CTX_PP_MISC           1 | ||||
| #define CTX_PP_FOG_COLOR      2 | ||||
| #define CTX_RE_SOLID_COLOR    3 | ||||
| #define CTX_RB3D_BLENDCNTL    4 | ||||
| #define CTX_RB3D_DEPTHOFFSET  5 | ||||
| #define CTX_RB3D_DEPTHPITCH   6 | ||||
| #define CTX_RB3D_ZSTENCILCNTL 7 | ||||
| #define CTX_CMD_1             8 | ||||
| #define CTX_PP_CNTL           9 | ||||
| #define CTX_RB3D_CNTL         10 | ||||
| #define CTX_RB3D_COLOROFFSET  11 | ||||
| #define CTX_CMD_2             12 /* why */ | ||||
| #define CTX_RB3D_COLORPITCH   13 /* why */ | ||||
| #define CTX_STATE_SIZE        14 | ||||
|  | ||||
| #define SET_CMD_0               0 | ||||
| #define SET_SE_CNTL             1 | ||||
| #define SET_RE_CNTL             2 /* replace se_coord_fmt */ | ||||
| #define SET_STATE_SIZE          3 | ||||
|  | ||||
| #define VTE_CMD_0               0 | ||||
| #define VTE_SE_VTE_CNTL         1 | ||||
| #define VTE_STATE_SIZE          2 | ||||
|  | ||||
| #define LIN_CMD_0               0 | ||||
| #define LIN_RE_LINE_PATTERN     1 | ||||
| #define LIN_RE_LINE_STATE       2 | ||||
| #define LIN_CMD_1               3 | ||||
| #define LIN_SE_LINE_WIDTH       4 | ||||
| #define LIN_STATE_SIZE          5 | ||||
|  | ||||
| #define MSK_CMD_0               0 | ||||
| #define MSK_RB3D_STENCILREFMASK 1 | ||||
| #define MSK_RB3D_ROPCNTL        2 | ||||
| #define MSK_RB3D_PLANEMASK      3 | ||||
| #define MSK_STATE_SIZE          4 | ||||
|  | ||||
| #define VPT_CMD_0           0 | ||||
| #define VPT_SE_VPORT_XSCALE          1 | ||||
| #define VPT_SE_VPORT_XOFFSET         2 | ||||
| #define VPT_SE_VPORT_YSCALE          3 | ||||
| #define VPT_SE_VPORT_YOFFSET         4 | ||||
| #define VPT_SE_VPORT_ZSCALE          5 | ||||
| #define VPT_SE_VPORT_ZOFFSET         6 | ||||
| #define VPT_STATE_SIZE      7 | ||||
|  | ||||
| #define ZBS_CMD_0               0 | ||||
| #define ZBS_SE_ZBIAS_FACTOR     1 | ||||
| #define ZBS_SE_ZBIAS_CONSTANT   2 | ||||
| #define ZBS_STATE_SIZE          3 | ||||
|  | ||||
| #define MSC_CMD_0               0 | ||||
| #define MSC_RE_MISC             1 | ||||
| #define MSC_STATE_SIZE          2 | ||||
|  | ||||
| #define TAM_CMD_0               0 | ||||
| #define TAM_DEBUG3              1 | ||||
| #define TAM_STATE_SIZE          2 | ||||
|  | ||||
| #define TEX_CMD_0                   0 | ||||
| #define TEX_PP_TXFILTER             1  /*2c00*/ | ||||
| #define TEX_PP_TXFORMAT             2  /*2c04*/ | ||||
| #define TEX_PP_TXFORMAT_X           3  /*2c08*/ | ||||
| #define TEX_PP_TXSIZE               4  /*2c0c*/ | ||||
| #define TEX_PP_TXPITCH              5  /*2c10*/ | ||||
| #define TEX_PP_BORDER_COLOR         6  /*2c14*/ | ||||
| #define TEX_CMD_1                   7 | ||||
| #define TEX_PP_TXOFFSET             8  /*2d00 */ | ||||
| #define TEX_STATE_SIZE              9 | ||||
|  | ||||
| #define CUBE_CMD_0                  0  /* 1 register follows */ | ||||
| #define CUBE_PP_CUBIC_FACES         1  /* 0x2c18 */ | ||||
| #define CUBE_CMD_1                  2  /* 5 registers follow */ | ||||
| #define CUBE_PP_CUBIC_OFFSET_F1     3  /* 0x2d04 */ | ||||
| #define CUBE_PP_CUBIC_OFFSET_F2     4  /* 0x2d08 */ | ||||
| #define CUBE_PP_CUBIC_OFFSET_F3     5  /* 0x2d0c */ | ||||
| #define CUBE_PP_CUBIC_OFFSET_F4     6  /* 0x2d10 */ | ||||
| #define CUBE_PP_CUBIC_OFFSET_F5     7  /* 0x2d14 */ | ||||
| #define CUBE_STATE_SIZE             8 | ||||
|  | ||||
| #define PIX_CMD_0                   0 | ||||
| #define PIX_PP_TXCBLEND             1 | ||||
| #define PIX_PP_TXCBLEND2            2 | ||||
| #define PIX_PP_TXABLEND             3 | ||||
| #define PIX_PP_TXABLEND2            4 | ||||
| #define PIX_STATE_SIZE              5 | ||||
|  | ||||
| #define TF_CMD_0                    0 | ||||
| #define TF_TFACTOR_0                1 | ||||
| #define TF_TFACTOR_1                2 | ||||
| #define TF_TFACTOR_2                3 | ||||
| #define TF_TFACTOR_3                4 | ||||
| #define TF_TFACTOR_4                5 | ||||
| #define TF_TFACTOR_5                6 | ||||
| #define TF_STATE_SIZE               7 | ||||
|  | ||||
| #define TCL_CMD_0                 0 | ||||
| #define TCL_LIGHT_MODEL_CTL_0     1 | ||||
| #define TCL_LIGHT_MODEL_CTL_1     2 | ||||
| #define TCL_PER_LIGHT_CTL_0       3 | ||||
| #define TCL_PER_LIGHT_CTL_1       4 | ||||
| #define TCL_PER_LIGHT_CTL_2       5 | ||||
| #define TCL_PER_LIGHT_CTL_3       6 | ||||
| #define TCL_CMD_1                 7 | ||||
| #define TCL_UCP_VERT_BLEND_CTL    8 | ||||
| #define TCL_STATE_SIZE            9 | ||||
|  | ||||
| #define MSL_CMD_0                     0 | ||||
| #define MSL_MATRIX_SELECT_0           1 | ||||
| #define MSL_MATRIX_SELECT_1           2 | ||||
| #define MSL_MATRIX_SELECT_2           3 | ||||
| #define MSL_MATRIX_SELECT_3           4 | ||||
| #define MSL_MATRIX_SELECT_4           5 | ||||
| #define MSL_STATE_SIZE                6 | ||||
|  | ||||
| #define TCG_CMD_0                 0 | ||||
| #define TCG_TEX_PROC_CTL_2            1 | ||||
| #define TCG_TEX_PROC_CTL_3            2 | ||||
| #define TCG_TEX_PROC_CTL_0            3 | ||||
| #define TCG_TEX_PROC_CTL_1            4 | ||||
| #define TCG_TEX_CYL_WRAP_CTL      5 | ||||
| #define TCG_STATE_SIZE            6 | ||||
|  | ||||
| #define MTL_CMD_0            0	 | ||||
| #define MTL_EMMISSIVE_RED    1	 | ||||
| #define MTL_EMMISSIVE_GREEN  2	 | ||||
| #define MTL_EMMISSIVE_BLUE   3	 | ||||
| #define MTL_EMMISSIVE_ALPHA  4	 | ||||
| #define MTL_AMBIENT_RED      5 | ||||
| #define MTL_AMBIENT_GREEN    6 | ||||
| #define MTL_AMBIENT_BLUE     7 | ||||
| #define MTL_AMBIENT_ALPHA    8 | ||||
| #define MTL_DIFFUSE_RED      9 | ||||
| #define MTL_DIFFUSE_GREEN    10 | ||||
| #define MTL_DIFFUSE_BLUE     11 | ||||
| #define MTL_DIFFUSE_ALPHA    12 | ||||
| #define MTL_SPECULAR_RED     13 | ||||
| #define MTL_SPECULAR_GREEN   14 | ||||
| #define MTL_SPECULAR_BLUE    15 | ||||
| #define MTL_SPECULAR_ALPHA   16 | ||||
| #define MTL_CMD_1            17 | ||||
| #define MTL_SHININESS        18 | ||||
| #define MTL_STATE_SIZE       19 | ||||
|  | ||||
| #define VAP_CMD_0                   0 | ||||
| #define VAP_SE_VAP_CNTL             1 | ||||
| #define VAP_STATE_SIZE              2 | ||||
|  | ||||
| /* Replaces a lot of packet info from radeon | ||||
|  */ | ||||
| #define VTX_CMD_0                   0 | ||||
| #define VTX_VTXFMT_0            1 | ||||
| #define VTX_VTXFMT_1            2 | ||||
| #define VTX_TCL_OUTPUT_VTXFMT_0 3 | ||||
| #define VTX_TCL_OUTPUT_VTXFMT_1 4 | ||||
| #define VTX_CMD_1               5 | ||||
| #define VTX_TCL_OUTPUT_COMPSEL  6 | ||||
| #define VTX_CMD_2               7 | ||||
| #define VTX_STATE_CNTL          8 | ||||
| #define VTX_STATE_SIZE          9 | ||||
|  | ||||
|  | ||||
| #define VTX_COLOR(v,n)   (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\ | ||||
|                          R200_VTX_COLOR_MASK) | ||||
|  | ||||
| #define MAT_CMD_0              0 | ||||
| #define MAT_ELT_0              1 | ||||
| #define MAT_STATE_SIZE         17 | ||||
|  | ||||
| #define GRD_CMD_0                  0 | ||||
| #define GRD_VERT_GUARD_CLIP_ADJ    1 | ||||
| #define GRD_VERT_GUARD_DISCARD_ADJ 2 | ||||
| #define GRD_HORZ_GUARD_CLIP_ADJ    3 | ||||
| #define GRD_HORZ_GUARD_DISCARD_ADJ 4 | ||||
| #define GRD_STATE_SIZE             5 | ||||
|  | ||||
| /* position changes frequently when lighting in modelpos - separate | ||||
|  * out to new state item?   | ||||
|  */ | ||||
| #define LIT_CMD_0                  0 | ||||
| #define LIT_AMBIENT_RED            1 | ||||
| #define LIT_AMBIENT_GREEN          2 | ||||
| #define LIT_AMBIENT_BLUE           3 | ||||
| #define LIT_AMBIENT_ALPHA          4 | ||||
| #define LIT_DIFFUSE_RED            5 | ||||
| #define LIT_DIFFUSE_GREEN          6 | ||||
| #define LIT_DIFFUSE_BLUE           7 | ||||
| #define LIT_DIFFUSE_ALPHA          8 | ||||
| #define LIT_SPECULAR_RED           9 | ||||
| #define LIT_SPECULAR_GREEN         10 | ||||
| #define LIT_SPECULAR_BLUE          11 | ||||
| #define LIT_SPECULAR_ALPHA         12 | ||||
| #define LIT_POSITION_X             13 | ||||
| #define LIT_POSITION_Y             14 | ||||
| #define LIT_POSITION_Z             15 | ||||
| #define LIT_POSITION_W             16 | ||||
| #define LIT_DIRECTION_X            17 | ||||
| #define LIT_DIRECTION_Y            18 | ||||
| #define LIT_DIRECTION_Z            19 | ||||
| #define LIT_DIRECTION_W            20 | ||||
| #define LIT_ATTEN_CONST            21 | ||||
| #define LIT_ATTEN_LINEAR           22 | ||||
| #define LIT_ATTEN_QUADRATIC        23 | ||||
| #define LIT_ATTEN_XXX              24 | ||||
| #define LIT_CMD_1                  25 | ||||
| #define LIT_SPOT_DCD               26 | ||||
| #define LIT_SPOT_DCM               27 | ||||
| #define LIT_SPOT_EXPONENT          28 | ||||
| #define LIT_SPOT_CUTOFF            29 | ||||
| #define LIT_SPECULAR_THRESH        30 | ||||
| #define LIT_RANGE_CUTOFF           31 /* ? */ | ||||
| #define LIT_RANGE_ATTEN            32 /* ? */ | ||||
| #define LIT_STATE_SIZE             33 | ||||
|  | ||||
| /* Fog | ||||
|  */ | ||||
| #define FOG_CMD_0      0 | ||||
| #define FOG_R          1 | ||||
| #define FOG_C          2 | ||||
| #define FOG_D          3 | ||||
| #define FOG_PAD        4 | ||||
| #define FOG_STATE_SIZE 5 | ||||
|  | ||||
| /* UCP | ||||
|  */ | ||||
| #define UCP_CMD_0      0 | ||||
| #define UCP_X          1 | ||||
| #define UCP_Y          2 | ||||
| #define UCP_Z          3 | ||||
| #define UCP_W          4 | ||||
| #define UCP_STATE_SIZE 5 | ||||
|  | ||||
| /* GLT - Global ambient | ||||
|  */ | ||||
| #define GLT_CMD_0      0 | ||||
| #define GLT_RED        1 | ||||
| #define GLT_GREEN      2 | ||||
| #define GLT_BLUE       3 | ||||
| #define GLT_ALPHA      4 | ||||
| #define GLT_STATE_SIZE 5 | ||||
|  | ||||
| /* EYE | ||||
|  */ | ||||
| #define EYE_CMD_0          0 | ||||
| #define EYE_X              1 | ||||
| #define EYE_Y              2 | ||||
| #define EYE_Z              3 | ||||
| #define EYE_RESCALE_FACTOR 4 | ||||
| #define EYE_STATE_SIZE     5 | ||||
|  | ||||
| /* CST - constant state | ||||
|  */ | ||||
| #define CST_CMD_0                             0 | ||||
| #define CST_PP_CNTL_X                         1 | ||||
| #define CST_CMD_1                             2 | ||||
| #define CST_RB3D_DEPTHXY_OFFSET               3 | ||||
| #define CST_CMD_2                             4 | ||||
| #define CST_RE_AUX_SCISSOR_CNTL               5 | ||||
| #define CST_CMD_3                             6 | ||||
| #define CST_RE_SCISSOR_TL_0                   7 | ||||
| #define CST_RE_SCISSOR_BR_0                   8 | ||||
| #define CST_CMD_4                             9 | ||||
| #define CST_SE_VAP_CNTL_STATUS                10 | ||||
| #define CST_CMD_5                             11 | ||||
| #define CST_RE_POINTSIZE                      12 | ||||
| #define CST_CMD_6                             13 | ||||
| #define CST_SE_TCL_INPUT_VTX_0                14 | ||||
| #define CST_SE_TCL_INPUT_VTX_1                15 | ||||
| #define CST_SE_TCL_INPUT_VTX_2                16 | ||||
| #define CST_SE_TCL_INPUT_VTX_3                17 | ||||
| #define CST_STATE_SIZE                        18 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| struct r200_hw_state { | ||||
|    /* All state should be on one of these lists: | ||||
|     */ | ||||
|    struct r200_state_atom dirty; /* dirty list head placeholder */ | ||||
|    struct r200_state_atom clean; /* clean list head placeholder */ | ||||
|  | ||||
|    /* Hardware state, stored as cmdbuf commands:   | ||||
|     *   -- Need to doublebuffer for | ||||
|     *           - reviving state after loss of context | ||||
|     *           - eliding noop statechange loops? (except line stipple count) | ||||
|     */ | ||||
|    struct r200_state_atom ctx; | ||||
|    struct r200_state_atom set; | ||||
|    struct r200_state_atom vte; | ||||
|    struct r200_state_atom lin; | ||||
|    struct r200_state_atom msk; | ||||
|    struct r200_state_atom vpt; | ||||
|    struct r200_state_atom vap; | ||||
|    struct r200_state_atom vtx; | ||||
|    struct r200_state_atom tcl; | ||||
|    struct r200_state_atom msl; | ||||
|    struct r200_state_atom tcg; | ||||
|    struct r200_state_atom msc; | ||||
|    struct r200_state_atom cst; | ||||
|    struct r200_state_atom tam; | ||||
|    struct r200_state_atom tf; | ||||
|    struct r200_state_atom tex[2]; | ||||
|    struct r200_state_atom cube[2]; | ||||
|    struct r200_state_atom zbs; | ||||
|    struct r200_state_atom mtl[2];  | ||||
|    struct r200_state_atom mat[5];  | ||||
|    struct r200_state_atom lit[8]; /* includes vec, scl commands */ | ||||
|    struct r200_state_atom ucp[6]; | ||||
|    struct r200_state_atom pix[6]; /* pixshader stages */ | ||||
|    struct r200_state_atom eye; /* eye pos */ | ||||
|    struct r200_state_atom grd; /* guard band clipping */ | ||||
|    struct r200_state_atom fog;  | ||||
|    struct r200_state_atom glt;  | ||||
| }; | ||||
|  | ||||
| struct r200_state { | ||||
|    /* Derived state for internal purposes: | ||||
|     */ | ||||
|    struct r200_colorbuffer_state color; | ||||
|    struct r200_depthbuffer_state depth; | ||||
|    struct r200_pixel_state pixel; | ||||
|    struct r200_scissor_state scissor; | ||||
|    struct r200_stencilbuffer_state stencil; | ||||
|    struct r200_stipple_state stipple; | ||||
|    struct r200_texture_state texture; | ||||
| }; | ||||
|  | ||||
| struct r200_texture { | ||||
|    r200TexObj objects[R200_NR_TEX_HEAPS]; | ||||
|    r200TexObj swapped; | ||||
|  | ||||
|    memHeap_t *heap[R200_NR_TEX_HEAPS]; | ||||
|    GLint age[R200_NR_TEX_HEAPS]; | ||||
|  | ||||
|    GLint numHeaps; | ||||
| }; | ||||
|  | ||||
| /* Need refcounting on dma buffers: | ||||
|  */ | ||||
| struct r200_dma_buffer { | ||||
|    int refcount;		/* the number of retained regions in buf */ | ||||
|    drmBufPtr buf; | ||||
| }; | ||||
|  | ||||
| #define GET_START(rvb) (rmesa->r200Screen->agp_buffer_offset +		\ | ||||
| 			(rvb)->address - rmesa->dma.buf0_address +	\ | ||||
| 			(rvb)->start) | ||||
|  | ||||
| /* A retained region, eg vertices for indexed vertices. | ||||
|  */ | ||||
| struct r200_dma_region { | ||||
|    struct r200_dma_buffer *buf; | ||||
|    char *address;		/* == buf->address */ | ||||
|    int start, end, ptr;		/* offsets from start of buf */ | ||||
|    int aos_start; | ||||
|    int aos_stride; | ||||
|    int aos_size; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_dma { | ||||
|    /* Active dma region.  Allocations for vertices and retained | ||||
|     * regions come from here.  Also used for emitting random vertices, | ||||
|     * these may be flushed by calling flush_current(); | ||||
|     */ | ||||
|    struct r200_dma_region current; | ||||
|     | ||||
|    void (*flush)( r200ContextPtr ); | ||||
|  | ||||
|    char *buf0_address;		/* start of buf[0], for index calcs */ | ||||
|    GLuint nr_released_bufs;	/* flush after so many buffers released */ | ||||
| }; | ||||
|  | ||||
| struct r200_dri_mirror { | ||||
|    __DRIcontextPrivate	*context;	/* DRI context */ | ||||
|    __DRIscreenPrivate	*screen;	/* DRI screen */ | ||||
|    __DRIdrawablePrivate	*drawable;	/* DRI drawable bound to this ctx */ | ||||
|  | ||||
|    drmContext hwContext; | ||||
|    drmLock *hwLock; | ||||
|    int fd; | ||||
|    int drmMinor; | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define R200_CMD_BUF_SZ  (8*1024)  | ||||
|  | ||||
| struct r200_store { | ||||
|    GLuint statenr; | ||||
|    GLuint primnr; | ||||
|    char cmd_buf[R200_CMD_BUF_SZ]; | ||||
|    int cmd_used;    | ||||
|    int elts_start; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* r200_tcl.c | ||||
|  */ | ||||
| struct r200_tcl_info { | ||||
|    GLuint vertex_format; | ||||
|    GLint last_offset; | ||||
|    GLuint hw_primitive; | ||||
|  | ||||
|    struct r200_dma_region *aos_components[8]; | ||||
|    GLuint nr_aos_components; | ||||
|  | ||||
|    GLuint *Elts; | ||||
|  | ||||
|    struct r200_dma_region indexed_verts; | ||||
|    struct r200_dma_region obj; | ||||
|    struct r200_dma_region rgba; | ||||
|    struct r200_dma_region spec; | ||||
|    struct r200_dma_region fog; | ||||
|    struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; | ||||
|    struct r200_dma_region norm; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* r200_swtcl.c | ||||
|  */ | ||||
| struct r200_swtcl_info { | ||||
|    GLuint SetupIndex; | ||||
|    GLuint SetupNewInputs; | ||||
|    GLuint RenderIndex; | ||||
|    GLuint vertex_size; | ||||
|    GLuint vertex_stride_shift; | ||||
|    GLuint vertex_format; | ||||
|    char *verts; | ||||
|  | ||||
|    /* Fallback rasterization functions | ||||
|     */ | ||||
|    r200_point_func draw_point; | ||||
|    r200_line_func draw_line; | ||||
|    r200_tri_func draw_tri; | ||||
|  | ||||
|    GLuint hw_primitive; | ||||
|    GLenum render_primitive; | ||||
|    GLuint numverts; | ||||
|  | ||||
|    struct r200_dma_region indexed_verts; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_ioctl { | ||||
|    GLuint vertex_offset; | ||||
|    GLuint vertex_size; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| #define R200_MAX_PRIMS 64 | ||||
|  | ||||
|  | ||||
| /* Want to keep a cache of these around.  Each is parameterized by | ||||
|  * only a single value which has only a small range.  Only expect a | ||||
|  * few, so just rescan the list each time? | ||||
|  */ | ||||
| struct dynfn { | ||||
|    struct dynfn *next, *prev; | ||||
|    int key[2]; | ||||
|    char *code; | ||||
| }; | ||||
|  | ||||
| struct dfn_lists { | ||||
|    struct dynfn Vertex2f; | ||||
|    struct dynfn Vertex2fv; | ||||
|    struct dynfn Vertex3f; | ||||
|    struct dynfn Vertex3fv; | ||||
|    struct dynfn Color4ub; | ||||
|    struct dynfn Color4ubv; | ||||
|    struct dynfn Color3ub; | ||||
|    struct dynfn Color3ubv; | ||||
|    struct dynfn Color4f; | ||||
|    struct dynfn Color4fv; | ||||
|    struct dynfn Color3f; | ||||
|    struct dynfn Color3fv; | ||||
|    struct dynfn SecondaryColor3ubEXT; | ||||
|    struct dynfn SecondaryColor3ubvEXT; | ||||
|    struct dynfn SecondaryColor3fEXT; | ||||
|    struct dynfn SecondaryColor3fvEXT; | ||||
|    struct dynfn Normal3f; | ||||
|    struct dynfn Normal3fv; | ||||
|    struct dynfn TexCoord2f; | ||||
|    struct dynfn TexCoord2fv; | ||||
|    struct dynfn TexCoord1f; | ||||
|    struct dynfn TexCoord1fv; | ||||
|    struct dynfn MultiTexCoord2fARB; | ||||
|    struct dynfn MultiTexCoord2fvARB; | ||||
|    struct dynfn MultiTexCoord1fARB; | ||||
|    struct dynfn MultiTexCoord1fvARB; | ||||
| }; | ||||
|  | ||||
| struct _vb; | ||||
|  | ||||
| struct dfn_generators { | ||||
|    struct dynfn *(*Vertex2f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Vertex2fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Vertex3f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Vertex3fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color4ub)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color4ubv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color3ub)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color3ubv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color4f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color4fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color3f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Color3fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Normal3f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*Normal3fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*TexCoord2f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*TexCoord2fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*TexCoord1f)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*TexCoord1fv)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * ); | ||||
|    struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * ); | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct r200_vb { | ||||
|    /* Keep these first: referenced from codegen templates: | ||||
|     */ | ||||
|    GLint counter, initial_counter; | ||||
|    GLint *dmaptr; | ||||
|    void (*notify)( void ); | ||||
|    GLint vertex_size; | ||||
|  | ||||
|    /* A maximum total of 15 elements per vertex:  3 floats for position, 3 | ||||
|     * floats for normal, 4 floats for color, 4 bytes for secondary color, | ||||
|     * 2 floats for each texture unit (4 floats total). | ||||
|     *  | ||||
|     * As soon as the 3rd TMU is supported or cube maps (or 3D textures) are | ||||
|     * supported, this value will grow. | ||||
|     *  | ||||
|     * The position data is never actually stored here, so 3 elements could be | ||||
|     * trimmed out of the buffer. | ||||
|     */ | ||||
|    union { float f; int i; r200_color_t color; } vertex[15]; | ||||
|  | ||||
|    GLfloat *normalptr; | ||||
|    GLfloat *floatcolorptr; | ||||
|    r200_color_t *colorptr; | ||||
|    GLfloat *floatspecptr; | ||||
|    r200_color_t *specptr; | ||||
|    GLfloat *texcoordptr[2]; | ||||
|  | ||||
|    GLcontext *context;		/* current context : Single thread only! */ | ||||
| }; | ||||
|  | ||||
| struct r200_prim { | ||||
|    GLuint start; | ||||
|    GLuint end; | ||||
|    GLuint prim; | ||||
| }; | ||||
|  | ||||
| struct r200_vbinfo { | ||||
|    GLenum *prim;		/* &ctx->Driver.CurrentExecPrimitive */ | ||||
|    GLuint primflags; | ||||
|    GLboolean enabled;		/* R200_NO_VTXFMT//R200_NO_TCL env vars */ | ||||
|    GLboolean installed; | ||||
|    GLboolean fell_back; | ||||
|    GLboolean recheck; | ||||
|    GLint initial_counter; | ||||
|    GLint nrverts; | ||||
|    GLuint vtxfmt_0, vtxfmt_1; | ||||
|  | ||||
|    GLuint installed_vertex_format; | ||||
|    GLuint installed_color_3f_sz; | ||||
|  | ||||
|    struct r200_prim primlist[R200_MAX_PRIMS]; | ||||
|    int nrprims; | ||||
|  | ||||
|    struct dfn_lists dfn_cache; | ||||
|    struct dfn_generators codegen; | ||||
|    GLvertexformat vtxfmt; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| struct r200_context { | ||||
|    GLcontext *glCtx;			/* Mesa context */ | ||||
|  | ||||
|    /* Driver and hardware state management | ||||
|     */ | ||||
|    struct r200_hw_state hw; | ||||
|    struct r200_state state; | ||||
|  | ||||
|    /* Texture object bookkeeping | ||||
|     */ | ||||
|    struct r200_texture texture; | ||||
|  | ||||
|  | ||||
|    /* Rasterization and vertex state: | ||||
|     */ | ||||
|    GLuint TclFallback; | ||||
|    GLuint Fallback; | ||||
|    GLuint NewGLState; | ||||
|  | ||||
|     | ||||
|    /* Temporaries for translating away float colors: | ||||
|     */ | ||||
|    struct gl_client_array UbyteColor; | ||||
|    struct gl_client_array UbyteSecondaryColor; | ||||
|  | ||||
|    /* Vertex buffers | ||||
|     */ | ||||
|    struct r200_ioctl ioctl; | ||||
|    struct r200_dma dma; | ||||
|    struct r200_store store; | ||||
|  | ||||
|    /* Page flipping | ||||
|     */ | ||||
|    GLuint doPageFlip; | ||||
|  | ||||
|    /* Busy waiting | ||||
|     */ | ||||
|    GLuint do_usleeps; | ||||
|    GLuint do_irqs; | ||||
|    GLuint irqsEmitted; | ||||
|    drmRadeonIrqWait iw; | ||||
|  | ||||
|    /* Clientdata textures; | ||||
|     */ | ||||
|    GLuint prefer_agp_client_texturing; | ||||
|  | ||||
|    /* Drawable, cliprect and scissor information | ||||
|     */ | ||||
|    GLuint numClipRects;			/* Cliprects for the draw buffer */ | ||||
|    XF86DRIClipRectPtr pClipRects; | ||||
|    unsigned int lastStamp; | ||||
|    GLboolean lost_context; | ||||
|    r200ScreenPtr r200Screen;	/* Screen private DRI data */ | ||||
|    RADEONSAREAPrivPtr sarea;		/* Private SAREA data */ | ||||
|  | ||||
|    /* TCL stuff | ||||
|     */ | ||||
|    GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; | ||||
|    GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS]; | ||||
|    GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS]; | ||||
|    GLuint TexMatEnabled; | ||||
|    GLuint TexMatCompSel; | ||||
|    GLuint TexGenEnabled; | ||||
|    GLuint TexGenInputs; | ||||
|    GLuint TexGenCompSel; | ||||
|    GLmatrix tmpmat; | ||||
|  | ||||
|    /* VBI | ||||
|     */ | ||||
|    GLuint vbl_seq; | ||||
|  | ||||
|    /* r200_tcl.c | ||||
|     */ | ||||
|    struct r200_tcl_info tcl; | ||||
|  | ||||
|    /* r200_swtcl.c | ||||
|     */ | ||||
|    struct r200_swtcl_info swtcl; | ||||
|  | ||||
|    /* r200_vtxfmt.c | ||||
|     */ | ||||
|    struct r200_vbinfo vb; | ||||
|  | ||||
|    /* Mirrors of some DRI state | ||||
|     */ | ||||
|    struct r200_dri_mirror dri; | ||||
| }; | ||||
|  | ||||
| #define R200_CONTEXT(ctx)		((r200ContextPtr)(ctx->DriverCtx)) | ||||
|  | ||||
|  | ||||
| static __inline GLuint r200PackColor( GLuint cpp, | ||||
| 					GLubyte r, GLubyte g, | ||||
| 					GLubyte b, GLubyte a ) | ||||
| { | ||||
|    switch ( cpp ) { | ||||
|    case 2: | ||||
|       return PACK_COLOR_565( r, g, b ); | ||||
|    case 4: | ||||
|       return PACK_COLOR_8888( a, r, g, b ); | ||||
|    default: | ||||
|       return 0; | ||||
|    } | ||||
| } | ||||
|  | ||||
| #define R200_OLD_PACKETS 0 | ||||
|  | ||||
|  | ||||
| extern void r200DestroyContext( __DRIcontextPrivate *driContextPriv ); | ||||
| extern GLboolean r200CreateContext( const __GLcontextModes *glVisual, | ||||
| 				    __DRIcontextPrivate *driContextPriv, | ||||
| 				    void *sharedContextPrivate); | ||||
| extern void r200SwapBuffers( __DRIdrawablePrivate *dPriv ); | ||||
| extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv, | ||||
| 				  __DRIdrawablePrivate *driDrawPriv, | ||||
| 				  __DRIdrawablePrivate *driReadPriv ); | ||||
| extern GLboolean r200UnbindContext( __DRIcontextPrivate *driContextPriv ); | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Debugging: | ||||
|  */ | ||||
| #define DO_DEBUG		1 | ||||
|  | ||||
| #if DO_DEBUG | ||||
| extern int R200_DEBUG; | ||||
| #else | ||||
| #define R200_DEBUG		0 | ||||
| #endif | ||||
|  | ||||
| #define DEBUG_TEXTURE	0x001 | ||||
| #define DEBUG_STATE	0x002 | ||||
| #define DEBUG_IOCTL	0x004 | ||||
| #define DEBUG_PRIMS	0x008 | ||||
| #define DEBUG_VERTS	0x010 | ||||
| #define DEBUG_FALLBACKS	0x020 | ||||
| #define DEBUG_VFMT	0x040 | ||||
| #define DEBUG_CODEGEN	0x080 | ||||
| #define DEBUG_VERBOSE	0x100 | ||||
| #define DEBUG_DRI       0x200 | ||||
| #define DEBUG_DMA       0x400 | ||||
| #define DEBUG_SANITY    0x800 | ||||
| #define DEBUG_SYNC      0x1000 | ||||
| #define DEBUG_PIXEL     0x2000 | ||||
| #define DEBUG_MEMORY    0x4000 | ||||
|  | ||||
| #endif | ||||
| #endif /* __R200_CONTEXT_H__ */ | ||||
							
								
								
									
										934
									
								
								src/mesa/drivers/dri/r200/r200_ioctl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										934
									
								
								src/mesa/drivers/dri/r200/r200_ioctl.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,934 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "macros.h" | ||||
| #include "context.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_sanity.h" | ||||
| #include "radeon_reg.h" | ||||
|  | ||||
| #include <unistd.h>  /* for usleep() */ | ||||
| #include <errno.h> | ||||
|  | ||||
|  | ||||
| #define R200_TIMEOUT             512 | ||||
| #define R200_IDLE_RETRY           16 | ||||
|  | ||||
|  | ||||
| static void do_usleep( int nr, const char *caller ) | ||||
| { | ||||
|    //if (1) fprintf(stderr, "usleep %d in %s\n", nr, caller ); | ||||
|    if (1) usleep( nr ); | ||||
| } | ||||
|  | ||||
| static void r200WaitForIdle( r200ContextPtr rmesa ); | ||||
|  | ||||
|  | ||||
| int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) | ||||
| { | ||||
|    int ret, i; | ||||
|    drmRadeonCmdBuffer cmd; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) { | ||||
|       fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);  | ||||
|  | ||||
|       if (0 & R200_DEBUG & DEBUG_VERBOSE)  | ||||
| 	 for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) | ||||
| 	    fprintf(stderr, "%d: %x\n", i/4,  | ||||
| 		    *(int *)(&rmesa->store.cmd_buf[i])); | ||||
|    } | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_DMA) | ||||
|       fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, | ||||
| 	      rmesa->dma.nr_released_bufs); | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SANITY) { | ||||
|       if (rmesa->state.scissor.enabled)  | ||||
| 	 ret = r200SanityCmdBuffer( rmesa,  | ||||
| 				    rmesa->state.scissor.numClipRects, | ||||
| 				    rmesa->state.scissor.pClipRects); | ||||
|       else | ||||
| 	 ret = r200SanityCmdBuffer( rmesa,  | ||||
| 				    rmesa->numClipRects, | ||||
| 				    rmesa->pClipRects); | ||||
|       if (ret) { | ||||
| 	 fprintf(stderr, "drmSanityCommandWrite: %d\n", ret);	  | ||||
| 	 goto out; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_MEMORY) { | ||||
|       if (!r200ValidateTexObjs( rmesa )) { | ||||
| 	 fprintf(stderr, " -- tex memory is inconsistent - expect mangled textures\n"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|  | ||||
|    cmd.bufsz = rmesa->store.cmd_used; | ||||
|    cmd.buf = rmesa->store.cmd_buf; | ||||
|  | ||||
|    if (rmesa->state.scissor.enabled) { | ||||
|       cmd.nbox = rmesa->state.scissor.numClipRects; | ||||
|       cmd.boxes = (drmClipRect *)rmesa->state.scissor.pClipRects; | ||||
|    } else { | ||||
|       cmd.nbox = rmesa->numClipRects; | ||||
|       cmd.boxes = (drmClipRect *)rmesa->pClipRects; | ||||
|    } | ||||
|  | ||||
|    ret = drmCommandWrite( rmesa->dri.fd, | ||||
| 			  DRM_RADEON_CMDBUF, | ||||
| 			  &cmd, sizeof(cmd) ); | ||||
|  | ||||
|    if (ret) | ||||
|       fprintf(stderr, "drmCommandWrite: %d\n", ret); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SYNC) { | ||||
|       fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); | ||||
|       r200WaitForIdleLocked( rmesa ); | ||||
|    } | ||||
|  | ||||
|  | ||||
|  out: | ||||
|    rmesa->store.primnr = 0; | ||||
|    rmesa->store.statenr = 0; | ||||
|    rmesa->store.cmd_used = 0; | ||||
|    rmesa->dma.nr_released_bufs = 0; | ||||
| /*    rmesa->lost_context = 0; */ | ||||
|    rmesa->lost_context = 1;	 | ||||
|    return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Note: does not emit any commands to avoid recursion on | ||||
|  * r200AllocCmdBuf. | ||||
|  */ | ||||
| void r200FlushCmdBuf( r200ContextPtr rmesa, const char *caller ) | ||||
| { | ||||
|    int ret; | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    ret = r200FlushCmdBufLocked( rmesa, caller ); | ||||
|  | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if (ret) { | ||||
|       fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret); | ||||
|       exit(ret); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ============================================================= | ||||
|  * Hardware vertex buffer handling | ||||
|  */ | ||||
|  | ||||
|  | ||||
| void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) | ||||
| { | ||||
|    struct r200_dma_buffer *dmabuf; | ||||
|    int fd = rmesa->dri.fd; | ||||
|    int index = 0; | ||||
|    int size = 0; | ||||
|    drmDMAReq dma; | ||||
|    int ret; | ||||
|  | ||||
|    if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__);   | ||||
|  | ||||
|    if (rmesa->dma.flush) { | ||||
|       rmesa->dma.flush( rmesa ); | ||||
|    } | ||||
|  | ||||
|    if (rmesa->dma.current.buf) | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); | ||||
|  | ||||
|    if (rmesa->dma.nr_released_bufs > 4) | ||||
|       r200FlushCmdBuf( rmesa, __FUNCTION__ ); | ||||
|  | ||||
|    dma.context = rmesa->dri.hwContext; | ||||
|    dma.send_count = 0; | ||||
|    dma.send_list = NULL; | ||||
|    dma.send_sizes = NULL; | ||||
|    dma.flags = 0; | ||||
|    dma.request_count = 1; | ||||
|    dma.request_size = RADEON_BUFFER_SIZE; | ||||
|    dma.request_list = &index; | ||||
|    dma.request_sizes = &size; | ||||
|    dma.granted_count = 0; | ||||
|  | ||||
|    LOCK_HARDWARE(rmesa);	/* no need to validate */ | ||||
|  | ||||
|    while (1) { | ||||
|       ret = drmDMA( fd, &dma ); | ||||
|       if (ret == 0) | ||||
| 	 break; | ||||
|     | ||||
|       if (rmesa->dma.nr_released_bufs) { | ||||
| 	 r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); | ||||
|       } | ||||
|        | ||||
|       if (rmesa->do_usleeps) { | ||||
| 	 UNLOCK_HARDWARE( rmesa ); | ||||
| 	 do_usleep(1, __FUNCTION__); | ||||
| 	 LOCK_HARDWARE( rmesa ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    UNLOCK_HARDWARE(rmesa); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_DMA) | ||||
|       fprintf(stderr, "Allocated buffer %d\n", index); | ||||
|  | ||||
|    dmabuf = CALLOC_STRUCT( r200_dma_buffer ); | ||||
|    dmabuf->buf = &rmesa->r200Screen->buffers->list[index]; | ||||
|    dmabuf->refcount = 1; | ||||
|  | ||||
|    rmesa->dma.current.buf = dmabuf; | ||||
|    rmesa->dma.current.address = dmabuf->buf->address; | ||||
|    rmesa->dma.current.end = dmabuf->buf->total; | ||||
|    rmesa->dma.current.start = 0; | ||||
|    rmesa->dma.current.ptr = 0; | ||||
| } | ||||
|  | ||||
| void r200ReleaseDmaRegion( r200ContextPtr rmesa, | ||||
| 			     struct r200_dma_region *region, | ||||
| 			     const char *caller ) | ||||
| { | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);  | ||||
|     | ||||
|    if (!region->buf) | ||||
|       return; | ||||
|  | ||||
|    if (rmesa->dma.flush) | ||||
|       rmesa->dma.flush( rmesa ); | ||||
|  | ||||
|    if (--region->buf->refcount == 0) { | ||||
|       drmRadeonCmdHeader *cmd; | ||||
|  | ||||
|       if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) | ||||
| 	 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, | ||||
| 		 region->buf->buf->idx);   | ||||
|        | ||||
|       cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sizeof(*cmd),  | ||||
| 						     __FUNCTION__ ); | ||||
|       cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; | ||||
|       cmd->dma.buf_idx = region->buf->buf->idx; | ||||
|       FREE(region->buf); | ||||
|       rmesa->dma.nr_released_bufs++; | ||||
|    } | ||||
|  | ||||
|    region->buf = 0; | ||||
|    region->start = 0; | ||||
| } | ||||
|  | ||||
| /* Allocates a region from rmesa->dma.current.  If there isn't enough | ||||
|  * space in current, grab a new buffer (and discard what was left of current) | ||||
|  */ | ||||
| void r200AllocDmaRegion( r200ContextPtr rmesa,  | ||||
| 			   struct r200_dma_region *region, | ||||
| 			   int bytes, | ||||
| 			   int alignment ) | ||||
| { | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); | ||||
|  | ||||
|    if (rmesa->dma.flush) | ||||
|       rmesa->dma.flush( rmesa ); | ||||
|  | ||||
|    if (region->buf) | ||||
|       r200ReleaseDmaRegion( rmesa, region, __FUNCTION__ ); | ||||
|  | ||||
|    alignment--; | ||||
|    rmesa->dma.current.start = rmesa->dma.current.ptr =  | ||||
|       (rmesa->dma.current.ptr + alignment) & ~alignment; | ||||
|  | ||||
|    if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )  | ||||
|       r200RefillCurrentDmaRegion( rmesa ); | ||||
|  | ||||
|    region->start = rmesa->dma.current.start; | ||||
|    region->ptr = rmesa->dma.current.start; | ||||
|    region->end = rmesa->dma.current.start + bytes; | ||||
|    region->address = rmesa->dma.current.address; | ||||
|    region->buf = rmesa->dma.current.buf; | ||||
|    region->buf->refcount++; | ||||
|  | ||||
|    rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ | ||||
|    rmesa->dma.current.start =  | ||||
|       rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;   | ||||
| } | ||||
|  | ||||
| void r200AllocDmaRegionVerts( r200ContextPtr rmesa,  | ||||
| 				struct r200_dma_region *region, | ||||
| 				int numverts, | ||||
| 				int vertsize, | ||||
| 				int alignment ) | ||||
| { | ||||
|    r200AllocDmaRegion( rmesa, region, vertsize * numverts, alignment ); | ||||
| } | ||||
|  | ||||
| /* ================================================================ | ||||
|  * SwapBuffers with client-side throttling | ||||
|  */ | ||||
|  | ||||
| static GLuint r200GetLastFrame(r200ContextPtr rmesa) | ||||
| { | ||||
|    drmRadeonGetParam gp; | ||||
|    int ret; | ||||
|    GLuint frame; | ||||
|  | ||||
|    gp.param = RADEON_PARAM_LAST_FRAME; | ||||
|    gp.value = (int *)&frame; | ||||
|    ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM, | ||||
| 			      &gp, sizeof(gp) ); | ||||
|    if ( ret ) { | ||||
|       fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); | ||||
|       exit(1); | ||||
|    } | ||||
|  | ||||
|    return frame; | ||||
| } | ||||
|  | ||||
| static void r200EmitIrqLocked( r200ContextPtr rmesa ) | ||||
| { | ||||
|    drmRadeonIrqEmit ie; | ||||
|    int ret; | ||||
|  | ||||
|    ie.irq_seq = &rmesa->iw.irq_seq; | ||||
|    ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT,  | ||||
| 			      &ie, sizeof(ie) ); | ||||
|    if ( ret ) { | ||||
|       fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret ); | ||||
|       exit(1); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200WaitIrq( r200ContextPtr rmesa ) | ||||
| { | ||||
|    int ret; | ||||
|  | ||||
|    do { | ||||
|       ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT, | ||||
| 			     &rmesa->iw, sizeof(rmesa->iw) ); | ||||
|    } while (ret && (errno == EINTR || errno == EAGAIN)); | ||||
|  | ||||
|    if ( ret ) { | ||||
|       fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); | ||||
|       exit(1); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) | ||||
| { | ||||
|    RADEONSAREAPrivPtr sarea = rmesa->sarea; | ||||
|  | ||||
|    if (rmesa->do_irqs) { | ||||
|       if (r200GetLastFrame(rmesa) < sarea->last_frame) { | ||||
| 	 if (!rmesa->irqsEmitted) { | ||||
| 	    while (r200GetLastFrame (rmesa) < sarea->last_frame) | ||||
| 	       ; | ||||
| 	 } | ||||
| 	 else { | ||||
| 	    UNLOCK_HARDWARE( rmesa );  | ||||
| 	    r200WaitIrq( rmesa );	 | ||||
| 	    LOCK_HARDWARE( rmesa );  | ||||
| 	 } | ||||
| 	 rmesa->irqsEmitted = 10; | ||||
|       } | ||||
|  | ||||
|       if (rmesa->irqsEmitted) { | ||||
| 	 r200EmitIrqLocked( rmesa ); | ||||
| 	 rmesa->irqsEmitted--; | ||||
|       } | ||||
|    }  | ||||
|    else { | ||||
|       while (r200GetLastFrame (rmesa) < sarea->last_frame) { | ||||
| 	 UNLOCK_HARDWARE( rmesa );  | ||||
| 	 if (rmesa->do_usleeps)  | ||||
| 	    do_usleep(1, __FUNCTION__);  | ||||
| 	 LOCK_HARDWARE( rmesa );  | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Copy the back color buffer to the front color buffer. | ||||
|  */ | ||||
| void r200CopyBuffer( const __DRIdrawablePrivate *dPriv ) | ||||
| { | ||||
|    r200ContextPtr rmesa; | ||||
|    GLint nbox, i, ret; | ||||
|  | ||||
|    assert(dPriv); | ||||
|    assert(dPriv->driContextPriv); | ||||
|    assert(dPriv->driContextPriv->driverPrivate); | ||||
|  | ||||
|    rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_IOCTL ) { | ||||
|       fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx ); | ||||
|    } | ||||
|  | ||||
|    R200_FIREVERTICES( rmesa ); | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|  | ||||
|    /* Throttle the frame rate -- only allow one pending swap buffers | ||||
|     * request at a time. | ||||
|     */ | ||||
|    r200WaitForFrameCompletion( rmesa ); | ||||
|  | ||||
|    r200WaitForVBlank( rmesa ); | ||||
|  | ||||
|    nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ | ||||
|  | ||||
|    for ( i = 0 ; i < nbox ; ) { | ||||
|       GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); | ||||
|       XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects; | ||||
|       XF86DRIClipRectPtr b = rmesa->sarea->boxes; | ||||
|       GLint n = 0; | ||||
|  | ||||
|       for ( ; i < nr ; i++ ) { | ||||
| 	 *b++ = box[i]; | ||||
| 	 n++; | ||||
|       } | ||||
|       rmesa->sarea->nbox = n; | ||||
|  | ||||
|       ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); | ||||
|  | ||||
|       if ( ret ) { | ||||
| 	 fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret ); | ||||
| 	 UNLOCK_HARDWARE( rmesa ); | ||||
| 	 exit( 1 ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|    rmesa->lost_context = 1; | ||||
| } | ||||
|  | ||||
| void r200PageFlip( const __DRIdrawablePrivate *dPriv ) | ||||
| { | ||||
|    r200ContextPtr rmesa; | ||||
|    GLint ret; | ||||
|  | ||||
|    assert(dPriv); | ||||
|    assert(dPriv->driContextPriv); | ||||
|    assert(dPriv->driContextPriv->driverPrivate); | ||||
|  | ||||
|    rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_IOCTL ) { | ||||
|       fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, | ||||
| 	      rmesa->sarea->pfCurrentPage); | ||||
|    } | ||||
|  | ||||
|    R200_FIREVERTICES( rmesa ); | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if (!rmesa->dri.drawable->numClipRects) { | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       usleep( 10000 );		/* throttle invisible client 10ms */ | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    /* Need to do this for the perf box placement: | ||||
|     */ | ||||
|    { | ||||
|       XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects; | ||||
|       XF86DRIClipRectPtr b = rmesa->sarea->boxes; | ||||
|       b[0] = box[0]; | ||||
|       rmesa->sarea->nbox = 1; | ||||
|    } | ||||
|  | ||||
|    /* Throttle the frame rate -- only allow a few pending swap buffers | ||||
|     * request at a time. | ||||
|     */ | ||||
|    r200WaitForFrameCompletion( rmesa ); | ||||
|  | ||||
|    r200WaitForVBlank( rmesa ); | ||||
|  | ||||
|    ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); | ||||
|  | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if ( ret ) { | ||||
|       fprintf( stderr, "DRM_R200_FLIP: return = %d\n", ret ); | ||||
|       exit( 1 ); | ||||
|    } | ||||
|  | ||||
|    if ( rmesa->sarea->pfCurrentPage == 1 ) { | ||||
| 	 rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; | ||||
| 	 rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch; | ||||
|    } else { | ||||
| 	 rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; | ||||
| 	 rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch; | ||||
|    } | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, ctx ); | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Buffer clear | ||||
|  */ | ||||
| static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, | ||||
| 			 GLint cx, GLint cy, GLint cw, GLint ch ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    GLuint flags = 0; | ||||
|    GLuint color_mask = 0; | ||||
|    GLint ret, i; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_IOCTL ) { | ||||
|       fprintf( stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n", | ||||
| 	       __FUNCTION__, all, cx, cy, cw, ch ); | ||||
|    } | ||||
|  | ||||
|    { | ||||
|       LOCK_HARDWARE( rmesa ); | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       if ( dPriv->numClipRects == 0 )  | ||||
| 	 return; | ||||
|    } | ||||
|  | ||||
|    r200EmitState( rmesa ); | ||||
|  | ||||
|    /* Need to cope with lostcontext here as kernel relies on | ||||
|     * some residual state: | ||||
|     */ | ||||
|    R200_FIREVERTICES( rmesa );  | ||||
|  | ||||
|    if ( mask & DD_FRONT_LEFT_BIT ) { | ||||
|       flags |= RADEON_FRONT; | ||||
|       color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; | ||||
|       mask &= ~DD_FRONT_LEFT_BIT; | ||||
|    } | ||||
|  | ||||
|    if ( mask & DD_BACK_LEFT_BIT ) { | ||||
|       flags |= RADEON_BACK; | ||||
|       color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; | ||||
|       mask &= ~DD_BACK_LEFT_BIT; | ||||
|    } | ||||
|  | ||||
|    if ( mask & DD_DEPTH_BIT ) { | ||||
|       if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */ | ||||
|       mask &= ~DD_DEPTH_BIT; | ||||
|    } | ||||
|  | ||||
|    if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) { | ||||
|       flags |= RADEON_STENCIL; | ||||
|       mask &= ~DD_STENCIL_BIT; | ||||
|    } | ||||
|  | ||||
|    if ( mask ) | ||||
|       _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); | ||||
|  | ||||
|    if ( !flags )  | ||||
|       return; | ||||
|  | ||||
|    /* Flip top to bottom */ | ||||
|    cx += dPriv->x; | ||||
|    cy  = dPriv->y + dPriv->h - cy - ch; | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    /* Throttle the number of clear ioctls we do. | ||||
|     */ | ||||
|    while ( 1 ) { | ||||
|       drmRadeonGetParam gp; | ||||
|       int ret; | ||||
|       int clear; | ||||
|  | ||||
|       gp.param = RADEON_PARAM_LAST_CLEAR; | ||||
|       gp.value = (int *)&clear; | ||||
|       ret = drmCommandWriteRead( rmesa->dri.fd, | ||||
| 		      DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); | ||||
|  | ||||
|       if ( ret ) { | ||||
| 	 fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); | ||||
| 	 exit(1); | ||||
|       } | ||||
|  | ||||
|       /* Clear throttling needs more thought. | ||||
|        */ | ||||
|       if ( rmesa->sarea->last_clear - clear <= 25 ) { | ||||
| 	 break; | ||||
|       } | ||||
|        | ||||
|       if (rmesa->do_usleeps) { | ||||
| 	 UNLOCK_HARDWARE( rmesa ); | ||||
| 	 do_usleep(1, __FUNCTION__); | ||||
| 	 LOCK_HARDWARE( rmesa ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|  | ||||
|    for ( i = 0 ; i < dPriv->numClipRects ; ) { | ||||
|       GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); | ||||
|       XF86DRIClipRectPtr box = dPriv->pClipRects; | ||||
|       XF86DRIClipRectPtr b = rmesa->sarea->boxes; | ||||
|       drmRadeonClearType clear; | ||||
|       drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; | ||||
|       GLint n = 0; | ||||
|  | ||||
|       if ( !all ) { | ||||
| 	 for ( ; i < nr ; i++ ) { | ||||
| 	    GLint x = box[i].x1; | ||||
| 	    GLint y = box[i].y1; | ||||
| 	    GLint w = box[i].x2 - x; | ||||
| 	    GLint h = box[i].y2 - y; | ||||
|  | ||||
| 	    if ( x < cx ) w -= cx - x, x = cx; | ||||
| 	    if ( y < cy ) h -= cy - y, y = cy; | ||||
| 	    if ( x + w > cx + cw ) w = cx + cw - x; | ||||
| 	    if ( y + h > cy + ch ) h = cy + ch - y; | ||||
| 	    if ( w <= 0 ) continue; | ||||
| 	    if ( h <= 0 ) continue; | ||||
|  | ||||
| 	    b->x1 = x; | ||||
| 	    b->y1 = y; | ||||
| 	    b->x2 = x + w; | ||||
| 	    b->y2 = y + h; | ||||
| 	    b++; | ||||
| 	    n++; | ||||
| 	 } | ||||
|       } else { | ||||
| 	 for ( ; i < nr ; i++ ) { | ||||
| 	    *b++ = box[i]; | ||||
| 	    n++; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       rmesa->sarea->nbox = n; | ||||
|  | ||||
|       clear.flags       = flags; | ||||
|       clear.clear_color = rmesa->state.color.clear; | ||||
|       clear.clear_depth = 0;	/* not used */ | ||||
|       clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; | ||||
|       clear.depth_mask  = rmesa->state.stencil.clear; | ||||
|       clear.depth_boxes = depth_boxes; | ||||
|  | ||||
|       n--; | ||||
|       b = rmesa->sarea->boxes; | ||||
|       for ( ; n >= 0 ; n-- ) { | ||||
| 	 depth_boxes[n].f[RADEON_CLEAR_X1] = (float)b[n].x1; | ||||
| 	 depth_boxes[n].f[RADEON_CLEAR_Y1] = (float)b[n].y1; | ||||
| 	 depth_boxes[n].f[RADEON_CLEAR_X2] = (float)b[n].x2; | ||||
| 	 depth_boxes[n].f[RADEON_CLEAR_Y2] = (float)b[n].y2; | ||||
| 	 depth_boxes[n].f[RADEON_CLEAR_DEPTH] = ctx->Depth.Clear; | ||||
|       } | ||||
|  | ||||
|       ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR, | ||||
| 			     &clear, sizeof(drmRadeonClearType)); | ||||
|  | ||||
|  | ||||
|       if ( ret ) { | ||||
| 	 UNLOCK_HARDWARE( rmesa ); | ||||
| 	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); | ||||
| 	 exit( 1 ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|    rmesa->lost_context = 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200WaitForIdleLocked( r200ContextPtr rmesa ) | ||||
| { | ||||
|     int ret; | ||||
|     int i = 0; | ||||
|      | ||||
|     do { | ||||
|        ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE); | ||||
|        if (ret)  | ||||
| 	  do_usleep( 1, __FUNCTION__ ); | ||||
|     } while (ret && ++i < 100); | ||||
|      | ||||
|     if ( ret < 0 ) { | ||||
|        UNLOCK_HARDWARE( rmesa ); | ||||
|        fprintf( stderr, "Error: R200 timed out... exiting\n" ); | ||||
|        exit( -1 ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void r200WaitForIdle( r200ContextPtr rmesa ) | ||||
| { | ||||
|    LOCK_HARDWARE(rmesa); | ||||
|    r200WaitForIdleLocked( rmesa ); | ||||
|    UNLOCK_HARDWARE(rmesa); | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200WaitForVBlank( r200ContextPtr rmesa ) | ||||
| { | ||||
| #if 0 | ||||
|     drmVBlank vbl; | ||||
|     int ret; | ||||
|  | ||||
|     if ( !rmesa->r200Screen->irq ) | ||||
| 	return; | ||||
|  | ||||
|     if ( getenv("LIBGL_SYNC_REFRESH") ) { | ||||
| 	/* Wait for until the next vertical blank */ | ||||
| 	vbl.request.type = DRM_VBLANK_RELATIVE; | ||||
| 	vbl.request.sequence = 1; | ||||
|     } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { | ||||
| 	/* Wait for at least one vertical blank since the last call */ | ||||
| 	vbl.request.type = DRM_VBLANK_ABSOLUTE; | ||||
| 	vbl.request.sequence = rmesa->vbl_seq + 1; | ||||
|     } else { | ||||
| 	return; | ||||
|     } | ||||
|  | ||||
|     UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|     if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) { | ||||
| 	fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" | ||||
| 		" working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" | ||||
| 		" and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); | ||||
| 	exit(1); | ||||
|     } else if (R200_DEBUG & DEBUG_IOCTL) | ||||
| 	fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); | ||||
|  | ||||
|     rmesa->vbl_seq = vbl.reply.sequence; | ||||
|  | ||||
|     LOCK_HARDWARE( rmesa ); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void r200Flush( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    if (rmesa->dma.flush) | ||||
|       rmesa->dma.flush( rmesa ); | ||||
|  | ||||
|    if (!is_empty_list(&rmesa->hw.dirty))  | ||||
|       r200EmitState( rmesa ); | ||||
|     | ||||
|    if (rmesa->store.cmd_used) | ||||
|       r200FlushCmdBuf( rmesa, __FUNCTION__ ); | ||||
| } | ||||
|  | ||||
| /* Make sure all commands have been sent to the hardware and have | ||||
|  * completed processing. | ||||
|  */ | ||||
| void r200Finish( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200Flush( ctx ); | ||||
|  | ||||
|    if (rmesa->do_irqs) { | ||||
|       LOCK_HARDWARE( rmesa ); | ||||
|       r200EmitIrqLocked( rmesa ); | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       r200WaitIrq( rmesa ); | ||||
|    } | ||||
|    else  | ||||
|       r200WaitForIdle( rmesa ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This version of AllocateMemoryNV allocates only agp memory, and | ||||
|  * only does so after the point at which the driver has been | ||||
|  * initialized. | ||||
|  * | ||||
|  * Theoretically a valid context isn't required.  However, in this | ||||
|  * implementation, it is, as I'm using the hardware lock to protect | ||||
|  * the kernel data structures, and the current context to get the | ||||
|  * device fd. | ||||
|  */ | ||||
| void *r200AllocateMemoryNV(GLsizei size, GLfloat readfreq, | ||||
| 			    GLfloat writefreq, GLfloat priority) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    r200ContextPtr rmesa; | ||||
|    int region_offset; | ||||
|    drmRadeonMemAlloc alloc; | ||||
|    int ret; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,  | ||||
| 	      writefreq, priority); | ||||
|  | ||||
|    if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI )  | ||||
|       return NULL; | ||||
|  | ||||
|    if (getenv("R200_NO_ALLOC")) | ||||
|       return NULL; | ||||
|     | ||||
|    if (rmesa->dri.drmMinor < 6)  | ||||
|       return NULL; | ||||
|        | ||||
|    alloc.region = RADEON_MEM_REGION_AGP; | ||||
|    alloc.alignment = 0; | ||||
|    alloc.size = size; | ||||
|    alloc.region_offset = ®ion_offset; | ||||
|  | ||||
|    ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd, | ||||
| 			      DRM_RADEON_ALLOC, | ||||
| 			      &alloc, sizeof(alloc)); | ||||
|     | ||||
|    if (ret) { | ||||
|       fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret); | ||||
|       return NULL; | ||||
|    } | ||||
|     | ||||
|    { | ||||
|       char *region_start = (char *)rmesa->r200Screen->agpTextures.map; | ||||
|       return (void *)(region_start + region_offset); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Called via glXFreeMemoryNV() */ | ||||
| void r200FreeMemoryNV(GLvoid *pointer) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    r200ContextPtr rmesa; | ||||
|    int region_offset; | ||||
|    drmRadeonMemFree memfree; | ||||
|    int ret; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "%s %p\n", __FUNCTION__, pointer); | ||||
|  | ||||
|    if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI ) { | ||||
|       fprintf(stderr, "%s: no context\n", __FUNCTION__); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    if (rmesa->dri.drmMinor < 6)  | ||||
|       return; | ||||
|  | ||||
|    region_offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; | ||||
|  | ||||
|    if (region_offset < 0 ||  | ||||
|        region_offset > rmesa->r200Screen->agpTextures.size) { | ||||
|       fprintf(stderr, "offset %d outside range 0..%d\n", region_offset, | ||||
| 	      rmesa->r200Screen->agpTextures.size); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    memfree.region = RADEON_MEM_REGION_AGP; | ||||
|    memfree.region_offset = region_offset; | ||||
|     | ||||
|    ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd, | ||||
| 			  DRM_RADEON_FREE, | ||||
| 			  &memfree, sizeof(memfree)); | ||||
|     | ||||
|    if (ret)  | ||||
|       fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret); | ||||
| } | ||||
|  | ||||
| /* Called via glXGetAGPOffsetMESA() */ | ||||
| GLuint r200GetAGPOffset(const GLvoid *pointer) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    r200ContextPtr rmesa; | ||||
|    GLuint card_offset; | ||||
|  | ||||
|    if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) { | ||||
|       fprintf(stderr, "%s: no context\n", __FUNCTION__); | ||||
|       return ~0; | ||||
|    } | ||||
|  | ||||
|    if (!r200IsAgpMemory( rmesa, pointer, 0 )) | ||||
|       return ~0; | ||||
|  | ||||
|    if (rmesa->dri.drmMinor < 6)  | ||||
|       return ~0; | ||||
|  | ||||
|    card_offset = r200AgpOffsetFromVirtual( rmesa, pointer ); | ||||
|  | ||||
|    return card_offset - rmesa->r200Screen->agp_base; | ||||
| } | ||||
|  | ||||
|  | ||||
| GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer, | ||||
| 			   GLint size ) | ||||
| { | ||||
|    int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; | ||||
|    int valid = (size >= 0 && | ||||
| 		offset >= 0 && | ||||
| 		offset + size < rmesa->r200Screen->agpTextures.size); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_IOCTL) | ||||
|       fprintf(stderr, "r200IsAgpMemory( %p ) : %d\n", pointer, valid ); | ||||
|     | ||||
|    return valid; | ||||
| } | ||||
|  | ||||
|  | ||||
| GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer ) | ||||
| { | ||||
|    int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; | ||||
|  | ||||
|    if (offset < 0 || offset > rmesa->r200Screen->agpTextures.size) | ||||
|       return ~0; | ||||
|    else | ||||
|       return rmesa->r200Screen->agp_texture_offset + offset; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200InitIoctlFuncs( GLcontext *ctx ) | ||||
| { | ||||
|     ctx->Driver.Clear = r200Clear; | ||||
|     ctx->Driver.Finish = r200Finish; | ||||
|     ctx->Driver.Flush = r200Flush; | ||||
| } | ||||
|  | ||||
							
								
								
									
										188
									
								
								src/mesa/drivers/dri/r200/r200_ioctl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								src/mesa/drivers/dri/r200/r200_ioctl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_IOCTL_H__ | ||||
| #define __R200_IOCTL_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "simple_list.h" | ||||
| #include "radeon_dri.h" | ||||
| #include "r200_lock.h" | ||||
|  | ||||
| #include "xf86drm.h" | ||||
| #include "radeon_common.h" | ||||
|  | ||||
| extern void r200EmitState( r200ContextPtr rmesa ); | ||||
| extern void r200EmitVertexAOS( r200ContextPtr rmesa, | ||||
| 				 GLuint vertex_size, | ||||
| 				 GLuint offset ); | ||||
|  | ||||
| extern void r200EmitVbufPrim( r200ContextPtr rmesa, | ||||
| 				GLuint primitive, | ||||
| 				GLuint vertex_nr ); | ||||
|  | ||||
| extern void r200FlushElts( r200ContextPtr rmesa ); | ||||
|  | ||||
| extern GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, | ||||
| 					   GLuint primitive, | ||||
| 					   GLuint min_nr ); | ||||
|  | ||||
| extern void r200EmitAOS( r200ContextPtr rmesa, | ||||
| 			   struct r200_dma_region **regions, | ||||
| 			   GLuint n, | ||||
| 			   GLuint offset ); | ||||
|  | ||||
| extern void r200EmitBlit( r200ContextPtr rmesa, | ||||
| 			  GLuint color_fmt, | ||||
| 			  GLuint src_pitch, | ||||
| 			  GLuint src_offset, | ||||
| 			  GLuint dst_pitch, | ||||
| 			  GLuint dst_offset, | ||||
| 			  GLint srcx, GLint srcy, | ||||
| 			  GLint dstx, GLint dsty, | ||||
| 			  GLuint w, GLuint h ); | ||||
|  | ||||
| extern void r200EmitWait( r200ContextPtr rmesa, GLuint flags ); | ||||
|  | ||||
| extern void r200FlushCmdBuf( r200ContextPtr rmesa, const char * ); | ||||
| extern int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ); | ||||
|  | ||||
| extern void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ); | ||||
|  | ||||
| extern void r200AllocDmaRegion( r200ContextPtr rmesa, | ||||
| 				  struct r200_dma_region *region, | ||||
| 				  int bytes,  | ||||
| 				  int alignment ); | ||||
|  | ||||
| extern void r200AllocDmaRegionVerts( r200ContextPtr rmesa, | ||||
| 				       struct r200_dma_region *region, | ||||
| 				       int numverts, | ||||
| 				       int vertsize,  | ||||
| 				       int alignment ); | ||||
|  | ||||
| extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, | ||||
| 				    struct r200_dma_region *region, | ||||
| 				    const char *caller ); | ||||
|  | ||||
| extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable ); | ||||
| extern void r200PageFlip( const __DRIdrawablePrivate *drawable ); | ||||
| extern void r200Flush( GLcontext *ctx ); | ||||
| extern void r200Finish( GLcontext *ctx ); | ||||
| extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); | ||||
| extern void r200WaitForVBlank( r200ContextPtr rmesa ); | ||||
| extern void r200InitIoctlFuncs( GLcontext *ctx ); | ||||
|  | ||||
| extern void *r200AllocateMemoryNV( GLsizei size, GLfloat readfreq, | ||||
| 				   GLfloat writefreq, GLfloat priority ); | ||||
| extern void r200FreeMemoryNV( GLvoid *pointer ); | ||||
| extern GLuint r200GetAGPOffset( const GLvoid *pointer ); | ||||
| extern GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer, | ||||
| 				  GLint size ); | ||||
|  | ||||
| extern GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa,  | ||||
| 					const GLvoid *pointer ); | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Helper macros: | ||||
|  */ | ||||
|  | ||||
| /* Close off the last primitive, if it exists. | ||||
|  */ | ||||
| #define R200_NEWPRIM( rmesa )			\ | ||||
| do {						\ | ||||
|    if ( rmesa->dma.flush )			\ | ||||
|       rmesa->dma.flush( rmesa );	\ | ||||
| } while (0) | ||||
|  | ||||
| /* Can accomodate several state changes and primitive changes without | ||||
|  * actually firing the buffer. | ||||
|  */ | ||||
| #define R200_STATECHANGE( rmesa, ATOM )			\ | ||||
| do {								\ | ||||
|    R200_NEWPRIM( rmesa );					\ | ||||
|    move_to_head( &(rmesa->hw.dirty), &(rmesa->hw.ATOM));	\ | ||||
| } while (0) | ||||
|  | ||||
| #define R200_DB_STATE( ATOM )			        \ | ||||
|    memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd,	\ | ||||
| 	   rmesa->hw.ATOM.cmd_size * 4) | ||||
|  | ||||
| static __inline int R200_DB_STATECHANGE(  | ||||
|    r200ContextPtr rmesa, | ||||
|    struct r200_state_atom *atom ) | ||||
| { | ||||
|    if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) { | ||||
|       int *tmp; | ||||
|       R200_NEWPRIM( rmesa ); | ||||
|       move_to_head( &(rmesa->hw.dirty), atom ); | ||||
|       tmp = atom->cmd;  | ||||
|       atom->cmd = atom->lastcmd; | ||||
|       atom->lastcmd = tmp; | ||||
|       return 1; | ||||
|    } | ||||
|    else | ||||
|       return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Fire the buffered vertices no matter what. | ||||
|  */ | ||||
| #define R200_FIREVERTICES( rmesa )			\ | ||||
| do {							\ | ||||
|    if ( rmesa->store.cmd_used || rmesa->dma.flush ) {	\ | ||||
|       r200Flush( rmesa->glCtx );			\ | ||||
|    }							\ | ||||
| } while (0) | ||||
|  | ||||
| /* Alloc space in the command buffer | ||||
|  */ | ||||
| static __inline char *r200AllocCmdBuf( r200ContextPtr rmesa, | ||||
| 					 int bytes, const char *where ) | ||||
| { | ||||
|    if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) | ||||
|       r200FlushCmdBuf( rmesa, __FUNCTION__ ); | ||||
|     | ||||
|    { | ||||
|       char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used; | ||||
|       rmesa->store.cmd_used += bytes; | ||||
|       return head; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif | ||||
| #endif /* __R200_IOCTL_H__ */ | ||||
							
								
								
									
										118
									
								
								src/mesa/drivers/dri/r200/r200_lock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/mesa/drivers/dri/r200/r200_lock.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_lock.h" | ||||
| #include "r200_tex.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
|  | ||||
| #if DEBUG_LOCKING | ||||
| char *prevLockFile = NULL; | ||||
| int prevLockLine = 0; | ||||
| #endif | ||||
|  | ||||
| /* Turn on/off page flipping according to the flags in the sarea: | ||||
|  */ | ||||
| static void | ||||
| r200UpdatePageFlipping( r200ContextPtr rmesa ) | ||||
| { | ||||
|    int use_back; | ||||
|    rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; | ||||
|  | ||||
|    use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT); | ||||
|    use_back ^= (rmesa->sarea->pfCurrentPage == 1); | ||||
|     | ||||
|    if (use_back) { | ||||
| 	 rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; | ||||
| 	 rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch; | ||||
|    } else { | ||||
| 	 rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; | ||||
| 	 rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch; | ||||
|    } | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, ctx ); | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Update the hardware state.  This is called if another context has | ||||
|  * grabbed the hardware lock, which includes the X server.  This | ||||
|  * function also updates the driver's window state after the X server | ||||
|  * moves, resizes or restacks a window -- the change will be reflected | ||||
|  * in the drawable position and clip rects.  Since the X server grabs | ||||
|  * the hardware lock when it changes the window state, this routine will | ||||
|  * automatically be called after such a change. | ||||
|  */ | ||||
| void r200GetLock( r200ContextPtr rmesa, GLuint flags ) | ||||
| { | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    __DRIscreenPrivate *sPriv = rmesa->dri.screen; | ||||
|    RADEONSAREAPrivPtr sarea = rmesa->sarea; | ||||
|    int i; | ||||
|  | ||||
|    drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); | ||||
|  | ||||
|    /* The window might have moved, so we might need to get new clip | ||||
|     * rects. | ||||
|     * | ||||
|     * NOTE: This releases and regrabs the hw lock to allow the X server | ||||
|     * to respond to the DRI protocol request for new drawable info. | ||||
|     * Since the hardware state depends on having the latest drawable | ||||
|     * clip rects, all state checking must be done _after_ this call. | ||||
|     */ | ||||
|    DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); | ||||
|  | ||||
|    if ( rmesa->lastStamp != dPriv->lastStamp ) { | ||||
|       r200UpdatePageFlipping( rmesa ); | ||||
|       if (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT) | ||||
|          r200SetCliprects( rmesa, GL_BACK_LEFT ); | ||||
|       else | ||||
|          r200SetCliprects( rmesa, GL_FRONT_LEFT ); | ||||
|       r200UpdateViewportOffset( rmesa->glCtx ); | ||||
|       rmesa->lastStamp = dPriv->lastStamp; | ||||
|    } | ||||
|  | ||||
|    if ( sarea->ctxOwner != rmesa->dri.hwContext ) { | ||||
|       sarea->ctxOwner = rmesa->dri.hwContext; | ||||
|    } | ||||
|  | ||||
|    for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { | ||||
|       if ( sarea->texAge[i] != rmesa->texture.age[i] ) { | ||||
| 	 r200AgeTextures( rmesa, i ); | ||||
|       } | ||||
|    } | ||||
| } | ||||
							
								
								
									
										111
									
								
								src/mesa/drivers/dri/r200/r200_lock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/mesa/drivers/dri/r200/r200_lock.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_LOCK_H__ | ||||
| #define __R200_LOCK_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| extern void r200GetLock( r200ContextPtr rmesa, GLuint flags ); | ||||
|  | ||||
| /* Turn DEBUG_LOCKING on to find locking conflicts. | ||||
|  */ | ||||
| #define DEBUG_LOCKING	0 | ||||
|  | ||||
| #if DEBUG_LOCKING | ||||
| extern char *prevLockFile; | ||||
| extern int prevLockLine; | ||||
|  | ||||
| #define DEBUG_LOCK()							\ | ||||
|    do {									\ | ||||
|       prevLockFile = (__FILE__);					\ | ||||
|       prevLockLine = (__LINE__);					\ | ||||
|    } while (0) | ||||
|  | ||||
| #define DEBUG_RESET()							\ | ||||
|    do {									\ | ||||
|       prevLockFile = 0;							\ | ||||
|       prevLockLine = 0;							\ | ||||
|    } while (0) | ||||
|  | ||||
| #define DEBUG_CHECK_LOCK()						\ | ||||
|    do {									\ | ||||
|       if ( prevLockFile ) {						\ | ||||
| 	 fprintf( stderr,						\ | ||||
| 		  "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n",	\ | ||||
| 		  prevLockFile, prevLockLine, __FILE__, __LINE__ );	\ | ||||
| 	 exit( 1 );							\ | ||||
|       }									\ | ||||
|    } while (0) | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define DEBUG_LOCK() | ||||
| #define DEBUG_RESET() | ||||
| #define DEBUG_CHECK_LOCK() | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * !!! We may want to separate locks from locks with validation.  This | ||||
|  * could be used to improve performance for those things commands that | ||||
|  * do not do any drawing !!! | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* Lock the hardware and validate our state. | ||||
|  */ | ||||
| #define LOCK_HARDWARE( rmesa )					\ | ||||
|    do {								\ | ||||
|       char __ret = 0;						\ | ||||
|       DEBUG_CHECK_LOCK();					\ | ||||
|       DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext,		\ | ||||
| 	       (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret );	\ | ||||
|       if ( __ret )						\ | ||||
| 	 r200GetLock( rmesa, 0 );				\ | ||||
|       DEBUG_LOCK();						\ | ||||
|    } while (0) | ||||
|  | ||||
| /* Unlock the hardware. | ||||
|  */ | ||||
| #define UNLOCK_HARDWARE( rmesa )					\ | ||||
|    do {									\ | ||||
|       DRM_UNLOCK( rmesa->dri.fd,					\ | ||||
| 		  rmesa->dri.hwLock,					\ | ||||
| 		  rmesa->dri.hwContext );				\ | ||||
|       DEBUG_RESET();							\ | ||||
|    } while (0) | ||||
|  | ||||
| #endif | ||||
| #endif /* __R200_LOCK_H__ */ | ||||
							
								
								
									
										12
									
								
								src/mesa/drivers/dri/r200/r200_maos.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/mesa/drivers/dri/r200/r200_maos.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
|  | ||||
|  | ||||
| /* If using new packets, can choose either verts or arrays. | ||||
|  * Otherwise, must use verts. | ||||
|  */ | ||||
| #include "r200_context.h" | ||||
| #define R200_MAOS_VERTS 0 | ||||
| #if (R200_MAOS_VERTS) || (R200_OLD_PACKETS) | ||||
| #include "r200_maos_verts.c" | ||||
| #else | ||||
| #include "r200_maos_arrays.c" | ||||
| #endif | ||||
							
								
								
									
										46
									
								
								src/mesa/drivers/dri/r200/r200_maos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/mesa/drivers/dri/r200/r200_maos.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_MAOS_H__ | ||||
| #define __R200_MAOS_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "r200_context.h" | ||||
|  | ||||
| extern void r200EmitArrays( GLcontext *ctx, GLuint inputs ); | ||||
| extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										481
									
								
								src/mesa/drivers/dri/r200/r200_maos_arrays.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										481
									
								
								src/mesa/drivers/dri/r200/r200_maos_arrays.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,481 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "mtypes.h" | ||||
| #include "colormac.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h" | ||||
| #include "macros.h" | ||||
|  | ||||
| #include "swrast_setup/swrast_setup.h" | ||||
| #include "math/m_translate.h" | ||||
| #include "tnl/tnl.h" | ||||
| #include "tnl/t_context.h" | ||||
| #include "tnl/t_imm_debug.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_maos.h" | ||||
|  | ||||
| /* Usage: | ||||
|  *   - from r200_tcl_render | ||||
|  *   - call r200EmitArrays to ensure uptodate arrays in dma | ||||
|  *   - emit primitives (new type?) which reference the data | ||||
|  *       -- need to use elts for lineloop, quads, quadstrip/flat | ||||
|  *       -- other primitives are all well-formed (need tristrip-1,fake-poly) | ||||
|  * | ||||
|  */ | ||||
| static void emit_ubyte_rgba3( GLcontext *ctx, | ||||
| 		       struct r200_dma_region *rvb, | ||||
| 		       char *data, | ||||
| 		       int stride, | ||||
| 		       int count ) | ||||
| { | ||||
|    int i; | ||||
|    r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d stride %d out %p\n", | ||||
| 	      __FUNCTION__, count, stride, out); | ||||
|  | ||||
|    for (i = 0; i < count; i++) { | ||||
|       out->red   = *data; | ||||
|       out->green = *(data+1); | ||||
|       out->blue  = *(data+2); | ||||
|       out->alpha = 0xFF; | ||||
|       out++; | ||||
|       data += stride; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| #if defined(USE_X86_ASM) | ||||
| #define COPY_DWORDS( dst, src, nr )					\ | ||||
| do {									\ | ||||
| 	int __tmp;							\ | ||||
| 	__asm__ __volatile__( "rep ; movsl"				\ | ||||
| 			      : "=%c" (__tmp), "=D" (dst), "=S" (__tmp)	\ | ||||
| 			      : "0" (nr),				\ | ||||
| 			        "D" ((long)dst),			\ | ||||
| 			        "S" ((long)src) );			\ | ||||
| } while (0) | ||||
| #else | ||||
| #define COPY_DWORDS( dst, src, nr )		\ | ||||
| do {						\ | ||||
|    int j;					\ | ||||
|    for ( j = 0 ; j < nr ; j++ )			\ | ||||
|       dst[j] = ((int *)src)[j];			\ | ||||
|    dst += nr;					\ | ||||
| } while (0) | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| static void emit_ubyte_rgba4( GLcontext *ctx, | ||||
| 			      struct r200_dma_region *rvb, | ||||
| 			      char *data, | ||||
| 			      int stride, | ||||
| 			      int count ) | ||||
| { | ||||
|    int i; | ||||
|    int *out = (int *)(rvb->address + rvb->start); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d stride %d\n", | ||||
| 	      __FUNCTION__, count, stride); | ||||
|  | ||||
|    if (stride == 4) { | ||||
|       for (i = 0; i < count; i++) | ||||
| 	 ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]); | ||||
|    } else { | ||||
|       for (i = 0; i < count; i++) { | ||||
| 	 *(int *)out++ = LE32_TO_CPU(*(int *)data); | ||||
| 	 data += stride; | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void emit_ubyte_rgba( GLcontext *ctx, | ||||
| 			     struct r200_dma_region *rvb, | ||||
| 			     char *data, | ||||
| 			     int size, | ||||
| 			     int stride, | ||||
| 			     int count ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); | ||||
|  | ||||
|    assert (!rvb->buf); | ||||
|  | ||||
|    if (stride == 0) { | ||||
|       r200AllocDmaRegion( rmesa, rvb, 4, 4 ); | ||||
|       count = 1; | ||||
|       rvb->aos_start = GET_START(rvb); | ||||
|       rvb->aos_stride = 0; | ||||
|       rvb->aos_size = 1; | ||||
|    } | ||||
|    else { | ||||
|       r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 );	/* alignment? */ | ||||
|       rvb->aos_start = GET_START(rvb); | ||||
|       rvb->aos_stride = 1; | ||||
|       rvb->aos_size = 1; | ||||
|    } | ||||
|  | ||||
|    /* Emit the data | ||||
|     */ | ||||
|    switch (size) { | ||||
|    case 3: | ||||
|       emit_ubyte_rgba3( ctx, rvb, data, stride, count ); | ||||
|       break; | ||||
|    case 4: | ||||
|       emit_ubyte_rgba4( ctx, rvb, data, stride, count ); | ||||
|       break; | ||||
|    default: | ||||
|       assert(0); | ||||
|       exit(1); | ||||
|       break; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static void emit_vec8( GLcontext *ctx, | ||||
| 		       struct r200_dma_region *rvb, | ||||
| 		       char *data, | ||||
| 		       int stride, | ||||
| 		       int count ) | ||||
| { | ||||
|    int i; | ||||
|    int *out = (int *)(rvb->address + rvb->start); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d stride %d\n", | ||||
| 	      __FUNCTION__, count, stride); | ||||
|  | ||||
|    if (stride == 8) | ||||
|       COPY_DWORDS( out, data, count*2 ); | ||||
|    else | ||||
|       for (i = 0; i < count; i++) { | ||||
| 	 out[0] = *(int *)data; | ||||
| 	 out[1] = *(int *)(data+4); | ||||
| 	 out += 2; | ||||
| 	 data += stride; | ||||
|       } | ||||
| } | ||||
|  | ||||
| static void emit_vec12( GLcontext *ctx, | ||||
| 		       struct r200_dma_region *rvb, | ||||
| 		       char *data, | ||||
| 		       int stride, | ||||
| 		       int count ) | ||||
| { | ||||
|    int i; | ||||
|    int *out = (int *)(rvb->address + rvb->start); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d stride %d out %p data %p\n", | ||||
| 	      __FUNCTION__, count, stride, out, data); | ||||
|  | ||||
|    if (stride == 12) | ||||
|       COPY_DWORDS( out, data, count*3 ); | ||||
|    else | ||||
|       for (i = 0; i < count; i++) { | ||||
| 	 out[0] = *(int *)data; | ||||
| 	 out[1] = *(int *)(data+4); | ||||
| 	 out[2] = *(int *)(data+8); | ||||
| 	 out += 3; | ||||
| 	 data += stride; | ||||
|       } | ||||
| } | ||||
|  | ||||
| static void emit_vec16( GLcontext *ctx, | ||||
| 			struct r200_dma_region *rvb, | ||||
| 			char *data, | ||||
| 			int stride, | ||||
| 			int count ) | ||||
| { | ||||
|    int i; | ||||
|    int *out = (int *)(rvb->address + rvb->start); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d stride %d\n", | ||||
| 	      __FUNCTION__, count, stride); | ||||
|  | ||||
|    if (stride == 16) | ||||
|       COPY_DWORDS( out, data, count*4 ); | ||||
|    else | ||||
|       for (i = 0; i < count; i++) { | ||||
| 	 out[0] = *(int *)data; | ||||
| 	 out[1] = *(int *)(data+4); | ||||
| 	 out[2] = *(int *)(data+8); | ||||
| 	 out[3] = *(int *)(data+12); | ||||
| 	 out += 4; | ||||
| 	 data += stride; | ||||
|       } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void emit_vector( GLcontext *ctx, | ||||
| 			 struct r200_dma_region *rvb, | ||||
| 			 char *data, | ||||
| 			 int size, | ||||
| 			 int stride, | ||||
| 			 int count ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s count %d size %d stride %d\n", | ||||
| 	      __FUNCTION__, count, size, stride); | ||||
|  | ||||
|    assert (!rvb->buf); | ||||
|  | ||||
|    if (stride == 0) { | ||||
|       r200AllocDmaRegion( rmesa, rvb, size * 4, 4 ); | ||||
|       count = 1; | ||||
|       rvb->aos_start = GET_START(rvb); | ||||
|       rvb->aos_stride = 0; | ||||
|       rvb->aos_size = size; | ||||
|    } | ||||
|    else { | ||||
|       r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 );	/* alignment? */ | ||||
|       rvb->aos_start = GET_START(rvb); | ||||
|       rvb->aos_stride = size; | ||||
|       rvb->aos_size = size; | ||||
|    } | ||||
|  | ||||
|    /* Emit the data | ||||
|     */ | ||||
|    switch (size) { | ||||
|    case 2: | ||||
|       emit_vec8( ctx, rvb, data, stride, count ); | ||||
|       break; | ||||
|    case 3: | ||||
|       emit_vec12( ctx, rvb, data, stride, count ); | ||||
|       break; | ||||
|    case 4: | ||||
|       emit_vec16( ctx, rvb, data, stride, count ); | ||||
|       break; | ||||
|    default: | ||||
|       assert(0); | ||||
|       exit(1); | ||||
|       break; | ||||
|    } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Emit any changed arrays to new agp memory, re-emit a packet to | ||||
|  * update the arrays.   | ||||
|  */ | ||||
| void r200EmitArrays( GLcontext *ctx, GLuint inputs ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; | ||||
|    struct r200_dma_region **component = rmesa->tcl.aos_components; | ||||
|    GLuint nr = 0; | ||||
|    GLuint vfmt0 = 0, vfmt1 = 0; | ||||
|    GLuint count = VB->Count; | ||||
|     | ||||
|    if (R200_DEBUG & DEBUG_VERTS)  | ||||
|       _tnl_print_vert_flags( __FUNCTION__, inputs ); | ||||
|  | ||||
|    if (1) { | ||||
|       if (!rmesa->tcl.obj.buf)  | ||||
| 	 emit_vector( ctx,  | ||||
| 		      &rmesa->tcl.obj,  | ||||
| 		      (char *)VB->ObjPtr->data, | ||||
| 		      VB->ObjPtr->size, | ||||
| 		      VB->ObjPtr->stride, | ||||
| 		      count); | ||||
|  | ||||
|       switch( VB->ObjPtr->size ) { | ||||
|       case 4: vfmt0 |= R200_VTX_W0; | ||||
|       case 3: vfmt0 |= R200_VTX_Z0; | ||||
|       case 2:  | ||||
|       default: | ||||
| 	break; | ||||
|       } | ||||
|       component[nr++] = &rmesa->tcl.obj; | ||||
|    } | ||||
|     | ||||
|  | ||||
|    if (inputs & VERT_BIT_NORMAL) { | ||||
|       if (!rmesa->tcl.norm.buf) | ||||
| 	 emit_vector( ctx,  | ||||
| 		      &(rmesa->tcl.norm),  | ||||
| 		      (char *)VB->NormalPtr->data, | ||||
| 		      3, | ||||
| 		      VB->NormalPtr->stride, | ||||
| 		      count); | ||||
|  | ||||
|       vfmt0 |= R200_VTX_N0; | ||||
|       component[nr++] = &rmesa->tcl.norm; | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_COLOR0) { | ||||
|       if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) { | ||||
| 	 if (!rmesa->tcl.rgba.buf) | ||||
| 	    emit_ubyte_rgba( ctx,  | ||||
| 			     &rmesa->tcl.rgba,  | ||||
| 			     (char *)VB->ColorPtr[0]->Ptr, | ||||
| 			     VB->ColorPtr[0]->Size, | ||||
| 			     VB->ColorPtr[0]->StrideB, | ||||
| 			     count); | ||||
|  | ||||
| 	 vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;  | ||||
|       } | ||||
|       else { | ||||
| 	 int emitsize; | ||||
|  | ||||
| 	 if (VB->ColorPtr[0]->Size == 4 && | ||||
| 	     (VB->ColorPtr[0]->StrideB != 0 || | ||||
| 	      ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) {  | ||||
| 	    vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;  | ||||
| 	    emitsize = 4; | ||||
| 	 } | ||||
| 	 else {  | ||||
| 	    vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT;  | ||||
| 	    emitsize = 3; | ||||
| 	 } | ||||
|  | ||||
| 	 if (!rmesa->tcl.rgba.buf) | ||||
| 	    emit_vector( ctx,  | ||||
| 			 &(rmesa->tcl.rgba),  | ||||
| 			 (char *)VB->ColorPtr[0]->Ptr, | ||||
| 			 emitsize, | ||||
| 			 VB->ColorPtr[0]->StrideB, | ||||
| 			 count); | ||||
|       } | ||||
|  | ||||
|       component[nr++] = &rmesa->tcl.rgba; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if (inputs & VERT_BIT_COLOR1) { | ||||
|       if (!rmesa->tcl.spec.buf) { | ||||
| 	 if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) | ||||
| 	    r200_import_float_spec_colors( ctx ); | ||||
|  | ||||
| 	 emit_ubyte_rgba( ctx,  | ||||
| 			  &rmesa->tcl.spec,  | ||||
| 			  (char *)VB->SecondaryColorPtr[0]->Ptr, | ||||
| 			  3, | ||||
| 			  VB->SecondaryColorPtr[0]->StrideB, | ||||
| 			  count); | ||||
|       } | ||||
|  | ||||
|       /* How does this work? | ||||
|        */ | ||||
|       vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT;  | ||||
|       component[nr++] = &rmesa->tcl.spec; | ||||
|    } | ||||
|  | ||||
| /*    vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */ | ||||
| /* 	  ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */ | ||||
|        | ||||
|    if (inputs & VERT_BIT_TEX0) { | ||||
|       if (!rmesa->tcl.tex[0].buf) | ||||
| 	 emit_vector( ctx,  | ||||
| 		      &(rmesa->tcl.tex[0]),  | ||||
| 		      (char *)VB->TexCoordPtr[0]->data, | ||||
| 		      VB->TexCoordPtr[0]->size, | ||||
| 		      VB->TexCoordPtr[0]->stride, | ||||
| 		      count ); | ||||
|  | ||||
|       vfmt1 |= VB->TexCoordPtr[0]->size << R200_VTX_TEX0_COMP_CNT_SHIFT; | ||||
|       component[nr++] = &rmesa->tcl.tex[0]; | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_TEX1) { | ||||
|       if (!rmesa->tcl.tex[1].buf) | ||||
| 	 emit_vector( ctx,  | ||||
| 		      &(rmesa->tcl.tex[1]),  | ||||
| 		      (char *)VB->TexCoordPtr[1]->data, | ||||
| 		      VB->TexCoordPtr[1]->size, | ||||
| 		      VB->TexCoordPtr[1]->stride, | ||||
| 		      count ); | ||||
| 	  | ||||
|       vfmt1 |= VB->TexCoordPtr[1]->size << R200_VTX_TEX1_COMP_CNT_SHIFT; | ||||
|       component[nr++] = &rmesa->tcl.tex[1]; | ||||
|    } | ||||
|  | ||||
|    if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || | ||||
|        vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {  | ||||
|       R200_STATECHANGE( rmesa, vtx );  | ||||
|       rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0; | ||||
|       rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; | ||||
|    }  | ||||
|  | ||||
|  | ||||
| /*    fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */ | ||||
|      | ||||
|    rmesa->tcl.nr_aos_components = nr; | ||||
|    rmesa->tcl.vertex_format = vfmt0; | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS)  | ||||
|       _tnl_print_vert_flags( __FUNCTION__, newinputs ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_POS)  | ||||
|      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_NORMAL)  | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_COLOR0)  | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_COLOR1)  | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_TEX0) | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ ); | ||||
|  | ||||
|    if (newinputs & VERT_BIT_TEX1) | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ ); | ||||
| } | ||||
							
								
								
									
										378
									
								
								src/mesa/drivers/dri/r200/r200_maos_vbtmp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								src/mesa/drivers/dri/r200/r200_maos_vbtmp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,378 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef LOCALVARS | ||||
| #define LOCALVARS | ||||
| #endif | ||||
|  | ||||
| #undef TCL_DEBUG | ||||
| #ifndef TCL_DEBUG | ||||
| #define TCL_DEBUG 0 | ||||
| #endif | ||||
|  | ||||
| static void TAG(emit)( GLcontext *ctx, | ||||
| 		       GLuint start, GLuint end, | ||||
| 		       void *dest ) | ||||
| { | ||||
|    LOCALVARS | ||||
|       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | ||||
|    GLuint (*tc0)[4], (*tc1)[4]; | ||||
|    GLfloat *fog; | ||||
|    GLuint (*tc2)[4], (*norm)[3]; | ||||
|    GLubyte (*col)[4], (*spec)[4]; | ||||
|    GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; | ||||
|    GLuint tc2_stride, norm_stride; | ||||
|    GLuint (*coord)[4]; | ||||
|    GLuint coord_stride; | ||||
|    GLubyte dummy[4]; | ||||
|    int i; | ||||
|  | ||||
|    union emit_union *v = (union emit_union *)dest; | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__);  | ||||
|  | ||||
|    /* The vertex code expects Obj to be clean to element 3.  To fix | ||||
|     * this, add more vertex code (for obj-2, obj-3) or preferably move | ||||
|     * to maos.   | ||||
|     */ | ||||
|    if (VB->ObjPtr->size < 3) { | ||||
|       if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { | ||||
| 	 VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); | ||||
|       } | ||||
|       _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 2 ); | ||||
|    } | ||||
|  | ||||
|    if (DO_W && VB->ObjPtr->size < 4) { | ||||
|       if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { | ||||
| 	 VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); | ||||
|       } | ||||
|       _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 3 ); | ||||
|    } | ||||
|  | ||||
|    coord = (GLuint (*)[4])VB->ObjPtr->data; | ||||
|    coord_stride = VB->ObjPtr->stride; | ||||
|  | ||||
|    if (DO_TEX2) { | ||||
|       const GLuint t2 = GET_TEXSOURCE(2); | ||||
|       tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data; | ||||
|       tc2_stride = VB->TexCoordPtr[t2]->stride; | ||||
|       if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { | ||||
| 	 if (VB->TexCoordPtr[t2]->flags & VEC_NOT_WRITEABLE) { | ||||
| 	    VB->import_data( ctx, VERT_TEX2, VEC_NOT_WRITEABLE ); | ||||
| 	 } | ||||
| 	 _mesa_vector4f_clean_elem( VB->TexCoordPtr[t2], VB->Count, 3 ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (DO_TEX1) { | ||||
|       if (VB->TexCoordPtr[1]) { | ||||
| 	 const GLuint t1 = GET_TEXSOURCE(1); | ||||
| 	 tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data; | ||||
| 	 tc1_stride = VB->TexCoordPtr[t1]->stride; | ||||
| 	 if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { | ||||
| 	    if (VB->TexCoordPtr[t1]->flags & VEC_NOT_WRITEABLE) { | ||||
| 	       VB->import_data( ctx, VERT_TEX1, VEC_NOT_WRITEABLE ); | ||||
| 	    } | ||||
| 	    _mesa_vector4f_clean_elem( VB->TexCoordPtr[t1], VB->Count, 3 ); | ||||
| 	 } | ||||
|       } else { | ||||
| 	 tc1 = (GLuint (*)[4])&ctx->Current.Texcoord[1]; /* could be anything, really */ | ||||
| 	 tc1_stride = 0; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (DO_TEX0) { | ||||
|       if (VB->TexCoordPtr[0]) { | ||||
| 	 const GLuint t0 = GET_TEXSOURCE(0); | ||||
| 	 tc0_stride = VB->TexCoordPtr[t0]->stride; | ||||
| 	 tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data; | ||||
| 	 if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { | ||||
| 	    if (VB->TexCoordPtr[t0]->flags & VEC_NOT_WRITEABLE) { | ||||
| 	       VB->import_data( ctx, VERT_TEX0, VEC_NOT_WRITEABLE ); | ||||
| 	    } | ||||
| 	    _mesa_vector4f_clean_elem( VB->TexCoordPtr[t0], VB->Count, 3 ); | ||||
| 	 } | ||||
|       } else { | ||||
| 	 tc0 = (GLuint (*)[4])&ctx->Current.Texcoord[0]; /* could be anything, really */ | ||||
| 	 tc0_stride = 0; | ||||
|       } | ||||
| 	  | ||||
|    } | ||||
|  | ||||
|    if (DO_NORM) { | ||||
|       if (VB->NormalPtr) { | ||||
| 	 norm_stride = VB->NormalPtr->stride; | ||||
| 	 norm = (GLuint (*)[3])VB->NormalPtr->data; | ||||
|       } else { | ||||
| 	 norm_stride = 0; | ||||
| 	 norm = (GLuint (*)[3])&ctx->Current.Normal; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (DO_RGBA) { | ||||
|       if (VB->ColorPtr[0]) { | ||||
| 	 /* This is incorrect when colormaterial is enabled: | ||||
| 	  */ | ||||
| 	 if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) { | ||||
| 	    if (0) fprintf(stderr, "IMPORTING FLOAT COLORS\n"); | ||||
| 	    IMPORT_FLOAT_COLORS( ctx ); | ||||
| 	 } | ||||
| 	 col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; | ||||
| 	 col_stride = VB->ColorPtr[0]->StrideB; | ||||
|       } else { | ||||
| 	 col = &dummy; /* any old memory is fine */ | ||||
| 	 col_stride = 0; | ||||
|       } | ||||
|        | ||||
|    } | ||||
|  | ||||
|    if (DO_SPEC) { | ||||
|       if (VB->SecondaryColorPtr[0]) { | ||||
| 	 if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) | ||||
| 	    IMPORT_FLOAT_SPEC_COLORS( ctx ); | ||||
| 	 spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr; | ||||
| 	 spec_stride = VB->SecondaryColorPtr[0]->StrideB; | ||||
|       } else { | ||||
| 	 spec = &dummy; | ||||
| 	 spec_stride = 0; | ||||
|       } | ||||
| 	  | ||||
|    } | ||||
|  | ||||
|    if (DO_FOG) { | ||||
|       if (VB->FogCoordPtr) { | ||||
| 	 fog = VB->FogCoordPtr->data; | ||||
| 	 fog_stride = VB->FogCoordPtr->stride; | ||||
|       } else { | ||||
| 	 fog = (GLfloat *)&dummy; *fog = 0; | ||||
| 	 fog_stride = 0; | ||||
|       } | ||||
| 	       | ||||
|    } | ||||
|     | ||||
|     | ||||
|    if (VB->importable_data) { | ||||
|       if (start) { | ||||
| 	 coord =  (GLuint (*)[4])((GLubyte *)coord + start * coord_stride); | ||||
| 	 if (DO_TEX0) | ||||
| 	    tc0 =  (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride); | ||||
| 	 if (DO_TEX1)  | ||||
| 	    tc1 =  (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride); | ||||
| 	 if (DO_TEX2)  | ||||
| 	    tc2 =  (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride); | ||||
| 	 if (DO_NORM)  | ||||
| 	    norm =  (GLuint (*)[3])((GLubyte *)norm + start * norm_stride); | ||||
| 	 if (DO_RGBA)  | ||||
| 	    STRIDE_4UB(col, start * col_stride); | ||||
| 	 if (DO_SPEC) | ||||
| 	    STRIDE_4UB(spec, start * spec_stride); | ||||
| 	 if (DO_FOG) | ||||
| 	    STRIDE_F(fog, start * fog_stride); | ||||
|       } | ||||
|  | ||||
|       for (i=start; i < end; i++) { | ||||
| 	 v[0].ui = coord[0][0]; | ||||
| 	 v[1].ui = coord[0][1]; | ||||
| 	 v[2].ui = coord[0][2]; | ||||
| 	 if (TCL_DEBUG) fprintf(stderr, "%d: %.2f %.2f %.2f ", i, v[0].f, v[1].f, v[2].f); | ||||
| 	 if (DO_W) { | ||||
| 	    v[3].ui = coord[0][3]; | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[3].f); | ||||
| 	    v += 4; | ||||
| 	 }  | ||||
| 	 else | ||||
| 	    v += 3; | ||||
| 	 coord =  (GLuint (*)[4])((GLubyte *)coord +  coord_stride); | ||||
|  | ||||
| 	 if (DO_NORM) { | ||||
| 	    v[0].ui = norm[0][0]; | ||||
| 	    v[1].ui = norm[0][1]; | ||||
| 	    v[2].ui = norm[0][2]; | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "norm: %.2f %.2f %.2f ", v[0].f, v[1].f, v[2].f); | ||||
| 	    v += 3; | ||||
| 	    norm =  (GLuint (*)[3])((GLubyte *)norm +  norm_stride); | ||||
| 	 } | ||||
| 	 if (DO_RGBA) { | ||||
| 	    v[0].ui = LE32_TO_CPU(*(GLuint *)&col[0]); | ||||
| 	    STRIDE_4UB(col, col_stride); | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); | ||||
| 	    v++; | ||||
| 	 } | ||||
| 	 if (DO_SPEC || DO_FOG) { | ||||
| 	    if (DO_SPEC) { | ||||
| 	       v[0].ub[0] = spec[0][0]; | ||||
| 	       v[0].ub[1] = spec[0][1]; | ||||
| 	       v[0].ub[2] = spec[0][2]; | ||||
| 	       STRIDE_4UB(spec, spec_stride); | ||||
| 	    } | ||||
| 	    if (DO_FOG) { | ||||
| 	       v[0].ub[3] = fog[0] * 255.0; | ||||
| 	       STRIDE_F(fog, fog_stride); | ||||
| 	    } | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); | ||||
| 	    v++; | ||||
| 	 } | ||||
| 	 if (DO_TEX0) { | ||||
| 	    v[0].ui = tc0[0][0]; | ||||
| 	    v[1].ui = tc0[0][1]; | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f); | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc0[0][3]; | ||||
| 	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	    tc0 =  (GLuint (*)[4])((GLubyte *)tc0 +  tc0_stride); | ||||
| 	 } | ||||
| 	 if (DO_TEX1) { | ||||
| 	    v[0].ui = tc1[0][0]; | ||||
| 	    v[1].ui = tc1[0][1]; | ||||
| 	    if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f); | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc1[0][3]; | ||||
| 	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	    tc1 =  (GLuint (*)[4])((GLubyte *)tc1 +  tc1_stride); | ||||
| 	 }  | ||||
| 	 if (DO_TEX2) { | ||||
| 	    v[0].ui = tc2[0][0]; | ||||
| 	    v[1].ui = tc2[0][1]; | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc2[0][3]; | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	    tc2 =  (GLuint (*)[4])((GLubyte *)tc2 +  tc2_stride); | ||||
| 	 }  | ||||
| 	 if (TCL_DEBUG) fprintf(stderr, "\n"); | ||||
|       } | ||||
|    } else { | ||||
|       for (i=start; i < end; i++) { | ||||
| 	 v[0].ui = coord[i][0]; | ||||
| 	 v[1].ui = coord[i][1]; | ||||
| 	 v[2].ui = coord[i][2]; | ||||
| 	 if (DO_W) { | ||||
| 	    v[3].ui = coord[i][3]; | ||||
| 	    v += 4; | ||||
| 	 }  | ||||
| 	 else | ||||
| 	    v += 3; | ||||
|  | ||||
| 	 if (DO_NORM) { | ||||
| 	    v[0].ui = norm[i][0]; | ||||
| 	    v[1].ui = norm[i][1]; | ||||
| 	    v[2].ui = norm[i][2]; | ||||
| 	    v += 3; | ||||
| 	 } | ||||
| 	 if (DO_RGBA) { | ||||
| 	    v[0].ui = LE32_TO_CPU(*(GLuint *)&col[i]); | ||||
| 	    v++; | ||||
| 	 } | ||||
| 	 if (DO_SPEC || DO_FOG) { | ||||
| 	    if (DO_SPEC) { | ||||
| 	       v[0].ub[0] = spec[i][0]; | ||||
| 	       v[0].ub[1] = spec[i][1]; | ||||
| 	       v[0].ub[2] = spec[i][2]; | ||||
| 	    } | ||||
| 	    if (DO_FOG) { | ||||
| 	       v[0].ub[3] = fog[i] * 255.0; | ||||
| 	    } | ||||
| 	    v++; | ||||
| 	 } | ||||
| 	 if (DO_TEX0) { | ||||
| 	    v[0].ui = tc0[i][0]; | ||||
| 	    v[1].ui = tc0[i][1]; | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc0[i][3]; | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	 } | ||||
| 	 if (DO_TEX1) { | ||||
| 	    v[0].ui = tc1[i][0]; | ||||
| 	    v[1].ui = tc1[i][1]; | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc1[i][3]; | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	 }  | ||||
| 	 if (DO_TEX2) { | ||||
| 	    v[0].ui = tc2[i][0]; | ||||
| 	    v[1].ui = tc2[i][1]; | ||||
| 	    if (DO_PTEX) { | ||||
| 	       v[2].ui = tc2[i][3]; | ||||
| 	       v += 3; | ||||
| 	    }  | ||||
| 	    else | ||||
| 	       v += 2; | ||||
| 	 }  | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void TAG(init)( void ) | ||||
| { | ||||
|    int sz = 3; | ||||
|    if (DO_W) sz++; | ||||
|    if (DO_NORM) sz += 3; | ||||
|    if (DO_RGBA) sz++; | ||||
|    if (DO_SPEC || DO_FOG) sz++; | ||||
|    if (DO_TEX0) sz += 2; | ||||
|    if (DO_TEX0 && DO_PTEX) sz++; | ||||
|    if (DO_TEX1) sz += 2; | ||||
|    if (DO_TEX1 && DO_PTEX) sz++; | ||||
|    if (DO_TEX2) sz += 2; | ||||
|    if (DO_TEX2 && DO_PTEX) sz++; | ||||
|  | ||||
|    setup_tab[IDX].emit = TAG(emit); | ||||
|    setup_tab[IDX].vertex_format = IND; | ||||
|    setup_tab[IDX].vertex_size = sz; | ||||
| } | ||||
|  | ||||
|  | ||||
| #undef IND | ||||
| #undef TAG | ||||
| #undef IDX | ||||
							
								
								
									
										338
									
								
								src/mesa/drivers/dri/r200/r200_maos_verts.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								src/mesa/drivers/dri/r200/r200_maos_verts.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,338 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h" | ||||
| #include "mtypes.h" | ||||
| #include "enums.h" | ||||
| #include "colormac.h" | ||||
| #include "light.h" | ||||
|  | ||||
| #include "array_cache/acache.h" | ||||
| #include "tnl/tnl.h" | ||||
| #include "tnl/t_pipeline.h" | ||||
| #include "tnl/t_imm_debug.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_tex.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_maos.h" | ||||
|  | ||||
|  | ||||
| #define R200_TCL_MAX_SETUP 13 | ||||
|  | ||||
| union emit_union { float f; GLuint ui; GLubyte ub[4]; }; | ||||
|  | ||||
| static struct { | ||||
|    void   (*emit)( GLcontext *, GLuint, GLuint, void * ); | ||||
|    GLuint vertex_size; | ||||
|    GLuint vertex_format; | ||||
| } setup_tab[R200_TCL_MAX_SETUP]; | ||||
|  | ||||
| #define DO_W    (IND & R200_CP_VC_FRMT_W0) | ||||
| #define DO_RGBA (IND & R200_CP_VC_FRMT_PKCOLOR) | ||||
| #define DO_SPEC (IND & R200_CP_VC_FRMT_PKSPEC) | ||||
| #define DO_FOG  (IND & R200_CP_VC_FRMT_PKSPEC) | ||||
| #define DO_TEX0 (IND & R200_CP_VC_FRMT_ST0) | ||||
| #define DO_TEX1 (IND & R200_CP_VC_FRMT_ST1) | ||||
| #define DO_PTEX (IND & R200_CP_VC_FRMT_Q0) | ||||
| #define DO_NORM (IND & R200_CP_VC_FRMT_N0) | ||||
|  | ||||
| #define DO_TEX2 0 | ||||
| #define DO_TEX3 0 | ||||
|  | ||||
| #define GET_TEXSOURCE(n)  n | ||||
| #define GET_UBYTE_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteColor | ||||
| #define GET_UBYTE_SPEC_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteSecondaryColor | ||||
|  | ||||
| #define IMPORT_FLOAT_COLORS r200_import_float_colors | ||||
| #define IMPORT_FLOAT_SPEC_COLORS r200_import_float_spec_colors | ||||
|  | ||||
| /*********************************************************************** | ||||
|  *             Generate vertex emit functions               * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
|  | ||||
| /* Defined in order of increasing vertex size: | ||||
|  */ | ||||
| #define IDX 0 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR) | ||||
| #define TAG(x) x##_rgba | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 1 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 2 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0) | ||||
| #define TAG(x) x##_rgba_st | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 3 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_rgba_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 4 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_st_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 5 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1) | ||||
| #define TAG(x) x##_rgba_st_st | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 6 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_rgba_st_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 7 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_PKSPEC|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1) | ||||
| #define TAG(x) x##_rgba_spec_st_st | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 8 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_st_st_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 9 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_PKSPEC|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_rgpa_spec_st_st_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 10 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_Q0) | ||||
| #define TAG(x) x##_rgba_stq | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 11 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1|		\ | ||||
| 	     R200_CP_VC_FRMT_Q1|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_Q0) | ||||
| #define TAG(x) x##_rgba_stq_stq | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
| #define IDX 12 | ||||
| #define IND (R200_CP_VC_FRMT_XY|		\ | ||||
| 	     R200_CP_VC_FRMT_Z|		\ | ||||
| 	     R200_CP_VC_FRMT_W0|		\ | ||||
| 	     R200_CP_VC_FRMT_PKCOLOR|		\ | ||||
| 	     R200_CP_VC_FRMT_PKSPEC|		\ | ||||
| 	     R200_CP_VC_FRMT_ST0|		\ | ||||
| 	     R200_CP_VC_FRMT_Q0|		\ | ||||
| 	     R200_CP_VC_FRMT_ST1|		\ | ||||
| 	     R200_CP_VC_FRMT_Q1|		\ | ||||
| 	     R200_CP_VC_FRMT_N0) | ||||
| #define TAG(x) x##_w_rgpa_spec_stq_stq_n | ||||
| #include "r200_maos_vbtmp.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /*********************************************************************** | ||||
|  *                         Initialization  | ||||
|  ***********************************************************************/ | ||||
|  | ||||
|  | ||||
| static void init_tcl_verts( void ) | ||||
| { | ||||
|    init_rgba(); | ||||
|    init_n(); | ||||
|    init_rgba_n(); | ||||
|    init_rgba_st(); | ||||
|    init_st_n(); | ||||
|    init_rgba_st_st(); | ||||
|    init_rgba_st_n(); | ||||
|    init_rgba_spec_st_st(); | ||||
|    init_st_st_n(); | ||||
|    init_rgpa_spec_st_st_n(); | ||||
|    init_rgba_stq(); | ||||
|    init_rgba_stq_stq(); | ||||
|    init_w_rgpa_spec_stq_stq_n(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200EmitArrays( GLcontext *ctx, GLuint inputs ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | ||||
|    GLuint req = 0; | ||||
|    GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & | ||||
| 		 ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); | ||||
|    int i; | ||||
|    static int firsttime = 1; | ||||
|  | ||||
|    if (firsttime) { | ||||
|       init_tcl_verts(); | ||||
|       firsttime = 0; | ||||
|    } | ||||
| 		      | ||||
|    if (1) { | ||||
|       req |= R200_CP_VC_FRMT_Z; | ||||
|       if (VB->ObjPtr->size == 4) { | ||||
| 	 req |= R200_CP_VC_FRMT_W0; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_NORMAL) { | ||||
|       req |= R200_CP_VC_FRMT_N0; | ||||
|    } | ||||
|     | ||||
|    if (inputs & VERT_BIT_COLOR0) { | ||||
|       req |= R200_CP_VC_FRMT_PKCOLOR; | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_COLOR1) { | ||||
|       req |= R200_CP_VC_FRMT_PKSPEC; | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_TEX0) { | ||||
|       req |= R200_CP_VC_FRMT_ST0; | ||||
|  | ||||
|       if (VB->TexCoordPtr[0]->size == 4) { | ||||
| 	 req |= R200_CP_VC_FRMT_Q0; | ||||
| 	 vtx |= R200_TCL_VTX_Q0; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (inputs & VERT_BIT_TEX1) { | ||||
|       req |= R200_CP_VC_FRMT_ST1; | ||||
|  | ||||
|       if (VB->TexCoordPtr[1]->size == 4) { | ||||
| 	 req |= R200_CP_VC_FRMT_Q1; | ||||
| 	 vtx |= R200_TCL_VTX_Q1; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) { | ||||
|       R200_STATECHANGE( rmesa, tcl ); | ||||
|       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx; | ||||
|    } | ||||
|  | ||||
|    for (i = 0 ; i < R200_TCL_MAX_SETUP ; i++)  | ||||
|       if ((setup_tab[i].vertex_format & req) == req)  | ||||
| 	 break; | ||||
|  | ||||
|    if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format && | ||||
|        rmesa->tcl.indexed_verts.buf) | ||||
|       return; | ||||
|  | ||||
|    if (rmesa->tcl.indexed_verts.buf) | ||||
|       r200ReleaseArrays( ctx, ~0 ); | ||||
|  | ||||
|    r200AllocDmaRegionVerts( rmesa,  | ||||
| 			      &rmesa->tcl.indexed_verts,  | ||||
| 			      VB->Count, | ||||
| 			      setup_tab[i].vertex_size * 4,  | ||||
| 			      4); | ||||
|  | ||||
|    setup_tab[i].emit( ctx, 0, VB->Count,  | ||||
| 		      rmesa->tcl.indexed_verts.address +  | ||||
| 		      rmesa->tcl.indexed_verts.start ); | ||||
|  | ||||
|    rmesa->tcl.vertex_format = setup_tab[i].vertex_format; | ||||
|    rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts ); | ||||
|    rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size; | ||||
|    rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size; | ||||
|  | ||||
|    rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts; | ||||
|    rmesa->tcl.nr_aos_components = 1; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_VERTS)  | ||||
|       _tnl_print_vert_flags( __FUNCTION__, newinputs ); | ||||
|  | ||||
|    if (newinputs)  | ||||
|      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ ); | ||||
| } | ||||
							
								
								
									
										494
									
								
								src/mesa/drivers/dri/r200/r200_pixel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										494
									
								
								src/mesa/drivers/dri/r200/r200_pixel.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,494 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "enums.h" | ||||
| #include "mtypes.h" | ||||
| #include "macros.h" | ||||
| #include "texutil.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_pixel.h" | ||||
| #include "r200_swtcl.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLboolean | ||||
| check_color( const GLcontext *ctx, GLenum type, GLenum format, | ||||
| 	     const struct gl_pixelstore_attrib *packing, | ||||
| 	     const void *pixels, GLint sz, GLint pitch ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint cpp = rmesa->r200Screen->cpp; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    if (	(pitch & 63) || | ||||
| 	ctx->_ImageTransferState || | ||||
| 	packing->SwapBytes || | ||||
| 	packing->LsbFirst) { | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "%s: failed 1\n", __FUNCTION__); | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&  | ||||
| 	cpp == 4 &&  | ||||
| 	format == GL_BGRA ) { | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "%s: passed 2\n", __FUNCTION__); | ||||
|       return GL_TRUE; | ||||
|    } | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s: failed\n", __FUNCTION__); | ||||
|  | ||||
|    return GL_FALSE; | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| check_color_per_fragment_ops( const GLcontext *ctx ) | ||||
| { | ||||
|    int result; | ||||
|    result = (!(     ctx->Color.AlphaEnabled ||  | ||||
| 		    ctx->Depth.Test || | ||||
| 		    ctx->Fog.Enabled || | ||||
| 		    ctx->Scissor.Enabled || | ||||
| 		    ctx->Stencil.Enabled || | ||||
| 		    !ctx->Color.ColorMask[0] || | ||||
| 		    !ctx->Color.ColorMask[1] || | ||||
| 		    !ctx->Color.ColorMask[2] || | ||||
| 		    !ctx->Color.ColorMask[3] || | ||||
| 		    ctx->Color.ColorLogicOpEnabled || | ||||
| 		    ctx->Texture._EnabledUnits || | ||||
| 		    ctx->Depth.OcclusionTest | ||||
|            ) && | ||||
| 	   ctx->Current.RasterPosValid); | ||||
|     | ||||
|    return result; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLboolean | ||||
| clip_pixelrect( const GLcontext *ctx, | ||||
| 		const GLframebuffer *buffer, | ||||
| 		GLint *x, GLint *y, | ||||
| 		GLsizei *width, GLsizei *height, | ||||
| 		GLint *size ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    /* left clipping */ | ||||
|    if (*x < buffer->_Xmin) { | ||||
|       *width -= (buffer->_Xmin - *x); | ||||
|       *x = buffer->_Xmin; | ||||
|    } | ||||
|  | ||||
|    /* right clipping */ | ||||
|    if (*x + *width > buffer->_Xmax) | ||||
|       *width -= (*x + *width - buffer->_Xmax - 1); | ||||
|  | ||||
|    if (*width <= 0) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    /* bottom clipping */ | ||||
|    if (*y < buffer->_Ymin) { | ||||
|       *height -= (buffer->_Ymin - *y); | ||||
|       *y = buffer->_Ymin; | ||||
|    } | ||||
|  | ||||
|    /* top clipping */ | ||||
|    if (*y + *height > buffer->_Ymax) | ||||
|       *height -= (*y + *height - buffer->_Ymax - 1); | ||||
|  | ||||
|    if (*height <= 0) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    *size = ((*y + *height - 1) * rmesa->r200Screen->frontPitch + | ||||
| 	    (*x + *width - 1) * rmesa->r200Screen->cpp); | ||||
|  | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| static GLboolean | ||||
| r200TryReadPixels( GLcontext *ctx, | ||||
| 		  GLint x, GLint y, GLsizei width, GLsizei height, | ||||
| 		  GLenum format, GLenum type, | ||||
| 		  const struct gl_pixelstore_attrib *pack, | ||||
| 		  GLvoid *pixels ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLint size; | ||||
|    GLint pitch = pack->RowLength ? pack->RowLength : width; | ||||
|    GLint blit_format; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    /* Only accelerate reading to agp buffers. | ||||
|     */ | ||||
|    if ( !r200IsAgpMemory(rmesa, pixels,  | ||||
| 			 pitch * height * rmesa->r200Screen->cpp ) ) { | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from | ||||
|     * blitter: | ||||
|     */ | ||||
|    if (!pack->Invert) { | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    if (!check_color(ctx, type, format, pack, pixels, size, pitch)) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    switch ( rmesa->r200Screen->cpp ) { | ||||
|    case 4: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_ARGB8888; | ||||
|       break; | ||||
|    default: | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    /* Although the blits go on the command buffer, need to do this and | ||||
|     * fire with lock held to guarentee cliprects and drawOffset are | ||||
|     * correct. | ||||
|     * | ||||
|     * This is an unusual situation however, as the code which flushes | ||||
|     * a full command buffer expects to be called unlocked.  As a | ||||
|     * workaround, immediately flush the buffer on aquiring the lock. | ||||
|     */ | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if (rmesa->store.cmd_used) | ||||
|       r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); | ||||
|  | ||||
|    if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height, | ||||
| 		       &size)) { | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "%s totally clipped -- nothing to do\n", | ||||
| 		 __FUNCTION__); | ||||
|       return GL_TRUE; | ||||
|    } | ||||
|  | ||||
|    { | ||||
|       __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|       int nbox = dPriv->numClipRects; | ||||
|       int src_offset = rmesa->state.color.drawOffset; | ||||
|       int src_pitch = rmesa->state.color.drawPitch * rmesa->r200Screen->cpp; | ||||
|       int dst_offset = r200AgpOffsetFromVirtual( rmesa, pixels); | ||||
|       int dst_pitch = pitch * rmesa->r200Screen->cpp; | ||||
|       XF86DRIClipRectRec *box = dPriv->pClipRects; | ||||
|       int i; | ||||
|  | ||||
|       r200EmitWait( rmesa, RADEON_WAIT_3D );  | ||||
|  | ||||
|       y = dPriv->h - y - height; | ||||
|       x += dPriv->x; | ||||
|       y += dPriv->y; | ||||
|  | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	 fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", | ||||
| 		 src_pitch, dst_pitch); | ||||
|  | ||||
|       for (i = 0 ; i < nbox ; i++) | ||||
|       { | ||||
| 	 GLint bx = box[i].x1; | ||||
| 	 GLint by = box[i].y1; | ||||
| 	 GLint bw = box[i].x2 - bx; | ||||
| 	 GLint bh = box[i].y2 - by; | ||||
| 	  | ||||
| 	 if (bx < x) bw -= x - bx, bx = x; | ||||
| 	 if (by < y) bh -= y - by, by = y; | ||||
| 	 if (bx + bw > x + width) bw = x + width - bx; | ||||
| 	 if (by + bh > y + height) bh = y + height - by; | ||||
| 	 if (bw <= 0) continue; | ||||
| 	 if (bh <= 0) continue; | ||||
|  | ||||
| 	 r200EmitBlit( rmesa, | ||||
| 		       blit_format, | ||||
| 		       src_pitch, src_offset, | ||||
| 		       dst_pitch, dst_offset, | ||||
| 		       bx, by, | ||||
| 		       bx - x, by - y, | ||||
| 		       bw, bh ); | ||||
|       } | ||||
|  | ||||
|       r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); | ||||
|    } | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    r200Finish( ctx ); /* required by GL */ | ||||
|  | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| r200ReadPixels( GLcontext *ctx, | ||||
| 		 GLint x, GLint y, GLsizei width, GLsizei height, | ||||
| 		 GLenum format, GLenum type, | ||||
| 		 const struct gl_pixelstore_attrib *pack, | ||||
| 		 GLvoid *pixels ) | ||||
| { | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    if (!r200TryReadPixels( ctx, x, y, width, height, format, type, pack,  | ||||
| 			   pixels)) | ||||
|       _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,  | ||||
| 			  pixels); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static void do_draw_pix( GLcontext *ctx, | ||||
| 			 GLint x, GLint y, GLsizei width, GLsizei height, | ||||
| 			 GLint pitch, | ||||
| 			 const void *pixels, | ||||
| 			 GLuint dest, GLuint planemask) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    XF86DRIClipRectPtr box = dPriv->pClipRects; | ||||
|    int nbox = dPriv->numClipRects; | ||||
|    int i; | ||||
|    int blit_format; | ||||
|    int size; | ||||
|    int src_offset = r200AgpOffsetFromVirtual( rmesa, pixels); | ||||
|    int src_pitch = pitch * rmesa->r200Screen->cpp; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    switch ( rmesa->r200Screen->cpp ) { | ||||
|    case 2: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_RGB565; | ||||
|       break; | ||||
|    case 4: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_ARGB8888; | ||||
|       break; | ||||
|    default: | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if (rmesa->store.cmd_used) | ||||
|       r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); | ||||
|  | ||||
|    y -= height;			/* cope with pixel zoom */ | ||||
|     | ||||
|    if (!clip_pixelrect(ctx, ctx->DrawBuffer, | ||||
| 		       &x, &y, &width, &height, | ||||
| 		       &size)) { | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    y = dPriv->h - y - height; 	/* convert from gl to hardware coords */ | ||||
|    x += dPriv->x; | ||||
|    y += dPriv->y; | ||||
|  | ||||
|  | ||||
|    r200EmitWait( rmesa, RADEON_WAIT_3D ); | ||||
|  | ||||
|    for (i = 0 ; i < nbox ; i++ ) | ||||
|    { | ||||
|       GLint bx = box[i].x1; | ||||
|       GLint by = box[i].y1; | ||||
|       GLint bw = box[i].x2 - bx; | ||||
|       GLint bh = box[i].y2 - by; | ||||
|  | ||||
|       if (bx < x) bw -= x - bx, bx = x; | ||||
|       if (by < y) bh -= y - by, by = y; | ||||
|       if (bx + bw > x + width) bw = x + width - bx; | ||||
|       if (by + bh > y + height) bh = y + height - by; | ||||
|       if (bw <= 0) continue; | ||||
|       if (bh <= 0) continue; | ||||
|  | ||||
|       r200EmitBlit( rmesa, | ||||
| 		    blit_format, | ||||
| 		    src_pitch, src_offset, | ||||
| 		    rmesa->state.color.drawPitch * rmesa->r200Screen->cpp, | ||||
| 		    rmesa->state.color.drawOffset, | ||||
| 		    bx - x, by - y, | ||||
| 		    bx, by, | ||||
| 		    bw, bh ); | ||||
|    } | ||||
|  | ||||
|    r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); | ||||
|    r200WaitForIdleLocked( rmesa ); /* required by GL */ | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| static GLboolean | ||||
| r200TryDrawPixels( GLcontext *ctx, | ||||
| 		  GLint x, GLint y, GLsizei width, GLsizei height, | ||||
| 		  GLenum format, GLenum type, | ||||
| 		  const struct gl_pixelstore_attrib *unpack, | ||||
| 		  const GLvoid *pixels ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLint pitch = unpack->RowLength ? unpack->RowLength : width; | ||||
|    GLuint dest, planemask; | ||||
|    GLuint cpp = rmesa->r200Screen->cpp; | ||||
|    GLint size = width * pitch * cpp; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    switch (format) { | ||||
|    case GL_RGB: | ||||
|    case GL_RGBA: | ||||
|    case GL_BGRA: | ||||
|       dest = rmesa->state.color.drawOffset; | ||||
|  | ||||
|       planemask = r200PackColor(cpp, | ||||
| 				ctx->Color.ColorMask[RCOMP], | ||||
| 				ctx->Color.ColorMask[GCOMP], | ||||
| 				ctx->Color.ColorMask[BCOMP], | ||||
| 				ctx->Color.ColorMask[ACOMP]); | ||||
|  | ||||
|       if (cpp == 2) | ||||
| 	 planemask |= planemask << 16; | ||||
|  | ||||
|       if (planemask != ~0) | ||||
| 	 return GL_FALSE;	/* fix me -- should be possible */ | ||||
|  | ||||
|       /* Can't do conversions on agp reads/draws.  | ||||
|        */ | ||||
|       if ( !r200IsAgpMemory( rmesa, pixels, size ) ) { | ||||
| 	 if (R200_DEBUG & DEBUG_PIXEL) | ||||
| 	    fprintf(stderr, "%s: not agp memory\n", __FUNCTION__); | ||||
| 	 return GL_FALSE; | ||||
|       } | ||||
|  | ||||
|       if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { | ||||
| 	 return GL_FALSE; | ||||
|       } | ||||
|       if (!check_color_per_fragment_ops(ctx)) { | ||||
| 	 return GL_FALSE; | ||||
|       } | ||||
|  | ||||
|       if (ctx->Pixel.ZoomX != 1.0F || | ||||
| 	  ctx->Pixel.ZoomY != -1.0F) | ||||
| 	 return GL_FALSE; | ||||
|       break; | ||||
|  | ||||
|    default: | ||||
|       return GL_FALSE; | ||||
|    } | ||||
|  | ||||
|    if ( r200IsAgpMemory(rmesa, pixels, size) ) | ||||
|    { | ||||
|       do_draw_pix( ctx, x, y, width, height, pitch, pixels, | ||||
| 		   dest, planemask ); | ||||
|       return GL_TRUE; | ||||
|    } | ||||
|    else if (0) | ||||
|    { | ||||
|       /* Pixels is in regular memory -- get dma buffers and perform | ||||
|        * upload through them. | ||||
|        */ | ||||
|    } | ||||
|    else | ||||
|       return GL_FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| r200DrawPixels( GLcontext *ctx, | ||||
| 		 GLint x, GLint y, GLsizei width, GLsizei height, | ||||
| 		 GLenum format, GLenum type, | ||||
| 		 const struct gl_pixelstore_attrib *unpack, | ||||
| 		 const GLvoid *pixels ) | ||||
| { | ||||
|    if (R200_DEBUG & DEBUG_PIXEL) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    if (!r200TryDrawPixels( ctx, x, y, width, height, format, type, | ||||
| 			  unpack, pixels )) | ||||
|       _swrast_DrawPixels( ctx, x, y, width, height, format, type, | ||||
| 			  unpack, pixels ); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| r200Bitmap( GLcontext *ctx, GLint px, GLint py, | ||||
| 		  GLsizei width, GLsizei height, | ||||
| 		  const struct gl_pixelstore_attrib *unpack, | ||||
| 		  const GLubyte *bitmap ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (rmesa->Fallback) | ||||
|       _swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap ); | ||||
|    else | ||||
|       r200PointsBitmap( ctx, px, py, width, height, unpack, bitmap ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200InitPixelFuncs( GLcontext *ctx ) | ||||
| { | ||||
|    /* Pixel path fallbacks. | ||||
|     */ | ||||
|    ctx->Driver.Accum = _swrast_Accum; | ||||
|    ctx->Driver.Bitmap = _swrast_Bitmap; | ||||
|    ctx->Driver.CopyPixels = _swrast_CopyPixels; | ||||
|    ctx->Driver.DrawPixels = _swrast_DrawPixels; | ||||
|    ctx->Driver.ReadPixels = _swrast_ReadPixels; | ||||
|  | ||||
|    if (!getenv("R200_NO_BLITS") && R200_CONTEXT(ctx)->dri.drmMinor >= 6) { | ||||
|       ctx->Driver.ReadPixels = r200ReadPixels;   | ||||
|       ctx->Driver.DrawPixels = r200DrawPixels;  | ||||
|       if (getenv("R200_HW_BITMAP"))  | ||||
| 	 ctx->Driver.Bitmap = r200Bitmap; | ||||
|    } | ||||
| } | ||||
							
								
								
									
										43
									
								
								src/mesa/drivers/dri/r200/r200_pixel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/mesa/drivers/dri/r200/r200_pixel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_PIXEL_H__ | ||||
| #define __R200_PIXEL_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| extern void r200InitPixelFuncs( GLcontext *ctx ); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										1438
									
								
								src/mesa/drivers/dri/r200/r200_reg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1438
									
								
								src/mesa/drivers/dri/r200/r200_reg.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1436
									
								
								src/mesa/drivers/dri/r200/r200_sanity.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1436
									
								
								src/mesa/drivers/dri/r200/r200_sanity.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								src/mesa/drivers/dri/r200/r200_sanity.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/mesa/drivers/dri/r200/r200_sanity.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #ifndef R200_SANITY_H | ||||
| #define R200_SANITY_H | ||||
|  | ||||
| extern int r200SanityCmdBuffer( r200ContextPtr rmesa, | ||||
| 				int nbox, | ||||
| 				XF86DRIClipRectRec *boxes ); | ||||
|  | ||||
|  | ||||
| extern int r200ValidateTexObjs( r200ContextPtr rmesa ); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										434
									
								
								src/mesa/drivers/dri/r200/r200_screen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								src/mesa/drivers/dri/r200/r200_screen.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,434 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "context.h" | ||||
|  | ||||
| #include "r200_screen.h" | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
|  | ||||
|  | ||||
| #if 1 | ||||
| /* Including xf86PciInfo.h introduces a bunch of errors... | ||||
|  */ | ||||
| #define PCI_CHIP_R200_QD	0x5144 | ||||
| #define PCI_CHIP_R200_QE	0x5145 | ||||
| #define PCI_CHIP_R200_QF	0x5146 | ||||
| #define PCI_CHIP_R200_QG	0x5147 | ||||
| #define PCI_CHIP_R200_QY	0x5159 | ||||
| #define PCI_CHIP_R200_QZ	0x515A | ||||
| #define PCI_CHIP_R200_LW	0x4C57  | ||||
| #define PCI_CHIP_R200_LY	0x4C59 | ||||
| #define PCI_CHIP_R200_LZ	0x4C5A | ||||
| #define PCI_CHIP_RV200_QW	0x5157  | ||||
| #endif | ||||
|  | ||||
| static r200ScreenPtr __r200Screen; | ||||
|  | ||||
| /* Create the device specific screen private data struct. | ||||
|  */ | ||||
| static r200ScreenPtr  | ||||
| r200CreateScreen( __DRIscreenPrivate *sPriv ) | ||||
| { | ||||
|    r200ScreenPtr r200Screen; | ||||
|    RADEONDRIPtr r200DRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; | ||||
|  | ||||
|    /* Check the DRI extension version */ | ||||
|    if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { | ||||
|        __driUtilMessage( "R200 DRI driver expected DRI version 4.0.x " | ||||
|                          "but got version %d.%d.%d", | ||||
|                          sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); | ||||
|        return NULL; | ||||
|    } | ||||
|  | ||||
|    /* Check that the DDX driver version is compatible */ | ||||
|    if ( sPriv->ddxMajor != 4 || | ||||
| 	sPriv->ddxMinor < 0 ) { | ||||
|       __driUtilMessage( "R200 DRI driver expected DDX driver version 4.0.x " | ||||
| 			"but got version %d.%d.%d",  | ||||
| 			sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    /* Check that the DRM driver version is compatible  | ||||
|     *    -- R200 support added at 1.5.0. | ||||
|     */ | ||||
|    if ( sPriv->drmMajor != 1 || | ||||
| 	sPriv->drmMinor < 5) { | ||||
|       __driUtilMessage( "R200 DRI driver expected DRM driver version 1.5.x " | ||||
| 			"but got version %d.%d.%d",  | ||||
| 			sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    /* Allocate the private area */ | ||||
|    r200Screen = (r200ScreenPtr) CALLOC( sizeof(*r200Screen) ); | ||||
|    if ( !r200Screen ) { | ||||
|       __driUtilMessage("%s: CALLOC r200Screen struct failed", | ||||
| 		       __FUNCTION__); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    /* Check if kernel module is new enough to support cube maps */ | ||||
|    if (sPriv->drmMajor * 100 + sPriv->drmMinor >= 107) | ||||
|       r200Screen->drmSupportsCubeMaps = GL_TRUE; | ||||
|    else | ||||
|       r200Screen->drmSupportsCubeMaps = GL_FALSE; | ||||
|  | ||||
|    switch ( r200DRIPriv->deviceID ) { | ||||
|    case PCI_CHIP_R200_QD: | ||||
|    case PCI_CHIP_R200_QE: | ||||
|    case PCI_CHIP_R200_QF: | ||||
|    case PCI_CHIP_R200_QG: | ||||
|    case PCI_CHIP_R200_QY: | ||||
|    case PCI_CHIP_R200_QZ: | ||||
|    case PCI_CHIP_RV200_QW: | ||||
|    case PCI_CHIP_R200_LW: | ||||
|    case PCI_CHIP_R200_LY: | ||||
|    case PCI_CHIP_R200_LZ: | ||||
|       __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n"); | ||||
|       FREE( r200Screen ); | ||||
|       return NULL;       | ||||
|    default: | ||||
|       r200Screen->chipset = R200_CHIPSET_R200; | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    /* This is first since which regions we map depends on whether or | ||||
|     * not we are using a PCI card. | ||||
|     */ | ||||
|    r200Screen->IsPCI = r200DRIPriv->IsPCI; | ||||
|  | ||||
|    { | ||||
|       int ret; | ||||
|       drmRadeonGetParam gp; | ||||
|  | ||||
|       gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET; | ||||
|       gp.value = &r200Screen->agp_buffer_offset; | ||||
|  | ||||
|       ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, | ||||
| 				 &gp, sizeof(gp)); | ||||
|       if (ret) { | ||||
| 	 FREE( r200Screen ); | ||||
| 	 fprintf(stderr, "drmR200GetParam: %d\n", ret); | ||||
| 	 return NULL; | ||||
|       } | ||||
|  | ||||
|       r200Screen->agp_texture_offset =  | ||||
| 	 r200Screen->agp_buffer_offset + 2*1024*1024; | ||||
|  | ||||
|  | ||||
|       if (sPriv->drmMinor >= 6) { | ||||
| 	 gp.param = RADEON_PARAM_AGP_BASE; | ||||
| 	 gp.value = &r200Screen->agp_base; | ||||
|  | ||||
| 	 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, | ||||
| 				    &gp, sizeof(gp)); | ||||
| 	 if (ret) { | ||||
| 	    FREE( r200Screen ); | ||||
| 	    fprintf(stderr, "drmR200GetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); | ||||
| 	    return NULL; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       if (sPriv->drmMinor >= 6) { | ||||
| 	 gp.param = RADEON_PARAM_IRQ_NR; | ||||
| 	 gp.value = &r200Screen->irq; | ||||
|  | ||||
| 	 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, | ||||
| 				    &gp, sizeof(gp)); | ||||
| 	 if (ret) { | ||||
| 	    FREE( r200Screen ); | ||||
| 	    fprintf(stderr, "drmR200GetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); | ||||
| 	    return NULL; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|    } | ||||
|  | ||||
|    r200Screen->mmio.handle = r200DRIPriv->registerHandle; | ||||
|    r200Screen->mmio.size   = r200DRIPriv->registerSize; | ||||
|    if ( drmMap( sPriv->fd, | ||||
| 		r200Screen->mmio.handle, | ||||
| 		r200Screen->mmio.size, | ||||
| 		&r200Screen->mmio.map ) ) { | ||||
|       FREE( r200Screen ); | ||||
|       __driUtilMessage("r200CreateScreen(): drmMap failed\n"); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    r200Screen->status.handle = r200DRIPriv->statusHandle; | ||||
|    r200Screen->status.size   = r200DRIPriv->statusSize; | ||||
|    if ( drmMap( sPriv->fd, | ||||
| 		r200Screen->status.handle, | ||||
| 		r200Screen->status.size, | ||||
| 		&r200Screen->status.map ) ) { | ||||
|       drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); | ||||
|       FREE( r200Screen ); | ||||
|       __driUtilMessage("r200CreateScreen(): drmMap (2) failed\n"); | ||||
|       return NULL; | ||||
|    } | ||||
|    r200Screen->scratch = (__volatile__ GLuint *) | ||||
|       ((GLubyte *)r200Screen->status.map + RADEON_SCRATCH_REG_OFFSET); | ||||
|  | ||||
|    r200Screen->buffers = drmMapBufs( sPriv->fd ); | ||||
|    if ( !r200Screen->buffers ) { | ||||
|       drmUnmap( r200Screen->status.map, r200Screen->status.size ); | ||||
|       drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); | ||||
|       FREE( r200Screen ); | ||||
|       __driUtilMessage("r200CreateScreen(): drmMapBufs failed\n"); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    if ( !r200Screen->IsPCI ) { | ||||
|       r200Screen->agpTextures.handle = r200DRIPriv->agpTexHandle; | ||||
|       r200Screen->agpTextures.size   = r200DRIPriv->agpTexMapSize; | ||||
|       if ( drmMap( sPriv->fd, | ||||
| 		   r200Screen->agpTextures.handle, | ||||
| 		   r200Screen->agpTextures.size, | ||||
| 		   (drmAddressPtr)&r200Screen->agpTextures.map ) ) { | ||||
| 	 drmUnmapBufs( r200Screen->buffers ); | ||||
| 	 drmUnmap( r200Screen->status.map, r200Screen->status.size ); | ||||
| 	 drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); | ||||
| 	 FREE( r200Screen ); | ||||
|          __driUtilMessage("r200CreateScreen(): IsPCI failed\n"); | ||||
| 	 return NULL; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|  | ||||
|  | ||||
|    r200Screen->cpp = r200DRIPriv->bpp / 8; | ||||
|    r200Screen->AGPMode = r200DRIPriv->AGPMode; | ||||
|  | ||||
|    r200Screen->frontOffset	= r200DRIPriv->frontOffset; | ||||
|    r200Screen->frontPitch	= r200DRIPriv->frontPitch; | ||||
|    r200Screen->backOffset	= r200DRIPriv->backOffset; | ||||
|    r200Screen->backPitch	= r200DRIPriv->backPitch; | ||||
|    r200Screen->depthOffset	= r200DRIPriv->depthOffset; | ||||
|    r200Screen->depthPitch	= r200DRIPriv->depthPitch; | ||||
|  | ||||
|    r200Screen->texOffset[RADEON_CARD_HEAP] = r200DRIPriv->textureOffset; | ||||
|    r200Screen->texSize[RADEON_CARD_HEAP] = r200DRIPriv->textureSize; | ||||
|    r200Screen->logTexGranularity[RADEON_CARD_HEAP] = | ||||
|       r200DRIPriv->log2TexGran; | ||||
|  | ||||
|    if ( r200Screen->IsPCI ) { | ||||
|       r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; | ||||
|       r200Screen->texOffset[RADEON_AGP_HEAP] = 0; | ||||
|       r200Screen->texSize[RADEON_AGP_HEAP] = 0; | ||||
|       r200Screen->logTexGranularity[RADEON_AGP_HEAP] = 0; | ||||
|    } else { | ||||
|       r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS; | ||||
|       r200Screen->texOffset[RADEON_AGP_HEAP] = | ||||
| 	 r200DRIPriv->agpTexOffset + R200_AGP_TEX_OFFSET; | ||||
|       r200Screen->texSize[RADEON_AGP_HEAP] = r200DRIPriv->agpTexMapSize; | ||||
|       r200Screen->logTexGranularity[RADEON_AGP_HEAP] = | ||||
| 	 r200DRIPriv->log2AGPTexGran; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    r200Screen->driScreen = sPriv; | ||||
|    r200Screen->sarea_priv_offset = r200DRIPriv->sarea_priv_offset; | ||||
|    return r200Screen; | ||||
| } | ||||
|  | ||||
| /* Destroy the device specific screen private data struct. | ||||
|  */ | ||||
| static void  | ||||
| r200DestroyScreen( __DRIscreenPrivate *sPriv ) | ||||
| { | ||||
|    r200ScreenPtr r200Screen = (r200ScreenPtr)sPriv->private; | ||||
|  | ||||
|    if (!r200Screen) | ||||
|       return; | ||||
|  | ||||
|    if ( !r200Screen->IsPCI ) { | ||||
|       drmUnmap( r200Screen->agpTextures.map, | ||||
| 		r200Screen->agpTextures.size ); | ||||
|    } | ||||
|    drmUnmapBufs( r200Screen->buffers ); | ||||
|    drmUnmap( r200Screen->status.map, r200Screen->status.size ); | ||||
|    drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); | ||||
|  | ||||
|    FREE( r200Screen ); | ||||
|    sPriv->private = NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Initialize the driver specific screen private data. | ||||
|  */ | ||||
| static GLboolean | ||||
| r200InitDriver( __DRIscreenPrivate *sPriv ) | ||||
| { | ||||
|    __r200Screen = r200CreateScreen( sPriv ); | ||||
|  | ||||
|    sPriv->private = (void *) __r200Screen; | ||||
|  | ||||
|    return sPriv->private ? GL_TRUE : GL_FALSE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Create and initialize the Mesa and driver specific pixmap buffer | ||||
|  * data. | ||||
|  */ | ||||
| static GLboolean | ||||
| r200CreateBuffer( __DRIscreenPrivate *driScrnPriv, | ||||
|                   __DRIdrawablePrivate *driDrawPriv, | ||||
|                   const __GLcontextModes *mesaVis, | ||||
|                   GLboolean isPixmap ) | ||||
| { | ||||
|    if (isPixmap) { | ||||
|       return GL_FALSE; /* not implemented */ | ||||
|    } | ||||
|    else { | ||||
|       const GLboolean swDepth = GL_FALSE; | ||||
|       const GLboolean swAlpha = GL_FALSE; | ||||
|       const GLboolean swAccum = mesaVis->accumRedBits > 0; | ||||
|       const GLboolean swStencil = mesaVis->stencilBits > 0 && | ||||
|          mesaVis->depthBits != 24; | ||||
|       driDrawPriv->driverPrivate = (void *) | ||||
|          _mesa_create_framebuffer( mesaVis, | ||||
|                                    swDepth, | ||||
|                                    swStencil, | ||||
|                                    swAccum, | ||||
|                                    swAlpha ); | ||||
|       return (driDrawPriv->driverPrivate != NULL); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) | ||||
| { | ||||
|    _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Fullscreen mode isn't used for much -- could be a way to shrink | ||||
|  * front/back buffers & get more texture memory if the client has | ||||
|  * changed the video resolution. | ||||
|  *  | ||||
|  * Pageflipping is now done automatically whenever there is a single | ||||
|  * 3d client. | ||||
|  */ | ||||
| static GLboolean | ||||
| r200OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) | ||||
| { | ||||
|    return GL_TRUE; | ||||
| } | ||||
|  | ||||
| static struct __DriverAPIRec r200API = { | ||||
|    r200InitDriver, | ||||
|    r200DestroyScreen, | ||||
|    r200CreateContext, | ||||
|    r200DestroyContext, | ||||
|    r200CreateBuffer, | ||||
|    r200DestroyBuffer, | ||||
|    r200SwapBuffers, | ||||
|    r200MakeCurrent, | ||||
|    r200UnbindContext, | ||||
|    r200OpenCloseFullScreen, | ||||
|    r200OpenCloseFullScreen | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This is the bootstrap function for the driver. | ||||
|  * The __driCreateScreen name is the symbol that libGL.so fetches. | ||||
|  * Return:  pointer to a __DRIscreenPrivate. | ||||
|  * | ||||
|  */ | ||||
| void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, | ||||
|                         int numConfigs, __GLXvisualConfig *config) | ||||
| { | ||||
|    __DRIscreenPrivate *psp; | ||||
|    psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API); | ||||
|    return (void *) psp; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This function is called by libGL.so to allow the driver to dynamically | ||||
|  * extend libGL.  We can add new GLX functions and/or new GL functions. | ||||
|  * Note that _mesa_create_context() will probably add most of the newer | ||||
|  * OpenGL extension functions into the dispatcher. | ||||
|  */ | ||||
| void | ||||
| __driRegisterExtensions( void ) | ||||
| { | ||||
|    /* dlopen ourself */ | ||||
|    void *dll = dlopen(NULL, RTLD_GLOBAL); | ||||
|    if (dll) { | ||||
|       typedef void *(*registerFunc)(const char *funcName, void *funcAddr); | ||||
|       typedef void (*registerString)(const char *extName); | ||||
|  | ||||
|       /* Get pointers to libGL's __glXRegisterGLXFunction | ||||
|        * and __glXRegisterGLXExtensionString, if they exist. | ||||
|        */ | ||||
|       registerFunc regFunc = (registerFunc) dlsym(dll, "__glXRegisterGLXFunction"); | ||||
|       registerString regString = (registerString) dlsym(dll, "__glXRegisterGLXExtensionString"); | ||||
|  | ||||
|       if (regFunc) { | ||||
|          /* register our GLX extensions with libGL */ | ||||
|          void *p; | ||||
|          p = regFunc("glXAllocateMemoryNV", (void *) r200AllocateMemoryNV); | ||||
|          if (p) | ||||
|             ;  /* XXX already registered - what to do, wrap? */ | ||||
|  | ||||
|          p = regFunc("glXFreeMemoryNV", (void *) r200FreeMemoryNV); | ||||
|          if (p) | ||||
|             ;  /* XXX already registered - what to do, wrap? */ | ||||
|  | ||||
|          p = regFunc("glXGetAGPOffsetMESA", (void *) r200GetAGPOffset); | ||||
|          if (p) | ||||
|             ;  /* XXX already registered - what to do, wrap? */ | ||||
|       } | ||||
|  | ||||
|       if (regString) { | ||||
|          regString("GLX_NV_vertex_array_range"); | ||||
|          regString("GLX_MESA_agp_offset"); | ||||
|       } | ||||
|  | ||||
|       dlclose(dll); | ||||
|    } | ||||
| } | ||||
							
								
								
									
										96
									
								
								src/mesa/drivers/dri/r200/r200_screen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/mesa/drivers/dri/r200/r200_screen.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_SCREEN_H__ | ||||
| #define __R200_SCREEN_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "dri_util.h" | ||||
| #include "radeon_common.h" | ||||
| #include "radeon_sarea.h" | ||||
|  | ||||
| typedef struct { | ||||
|    drmHandle handle;			/* Handle to the DRM region */ | ||||
|    drmSize size;			/* Size of the DRM region */ | ||||
|    drmAddress map;			/* Mapping of the DRM region */ | ||||
| } r200RegionRec, *r200RegionPtr; | ||||
|  | ||||
| #define R200_CHIPSET_R200   1 | ||||
| #define R200_CHIPSET_MOBILITY 2 | ||||
|  | ||||
|  | ||||
| #define R200_NR_TEX_HEAPS 2 | ||||
|  | ||||
| typedef struct { | ||||
|  | ||||
|    int chipset; | ||||
|    int cpp; | ||||
|    int IsPCI;				/* Current card is a PCI card */ | ||||
|    int AGPMode; | ||||
|    unsigned int irq;			/* IRQ number (0 means none) */ | ||||
|  | ||||
|    unsigned int frontOffset; | ||||
|    unsigned int frontPitch; | ||||
|    unsigned int backOffset; | ||||
|    unsigned int backPitch; | ||||
|  | ||||
|    unsigned int depthOffset; | ||||
|    unsigned int depthPitch; | ||||
|  | ||||
|     /* Shared texture data */ | ||||
|    int numTexHeaps; | ||||
|    int texOffset[R200_NR_TEX_HEAPS]; | ||||
|    int texSize[R200_NR_TEX_HEAPS]; | ||||
|    int logTexGranularity[R200_NR_TEX_HEAPS]; | ||||
|  | ||||
|    r200RegionRec mmio; | ||||
|    r200RegionRec status; | ||||
|    r200RegionRec agpTextures; | ||||
|  | ||||
|    drmBufMapPtr buffers; | ||||
|  | ||||
|    __volatile__ GLuint *scratch; | ||||
|  | ||||
|    __DRIscreenPrivate *driScreen; | ||||
|    unsigned int sarea_priv_offset; | ||||
|    unsigned int agp_buffer_offset;	/* offset in card memory space */ | ||||
|    unsigned int agp_texture_offset;	/* offset in card memory space */ | ||||
|    unsigned int agp_base; | ||||
|  | ||||
|    GLboolean drmSupportsCubeMaps;       /* need radeon kernel module >=1.7 */ | ||||
| } r200ScreenRec, *r200ScreenPtr; | ||||
|  | ||||
| #endif | ||||
| #endif /* __R200_SCREEN_H__ */ | ||||
							
								
								
									
										430
									
								
								src/mesa/drivers/dri/r200/r200_span.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										430
									
								
								src/mesa/drivers/dri/r200/r200_span.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,430 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "swrast/swrast.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_span.h" | ||||
| #include "r200_tex.h" | ||||
|  | ||||
| #define DBG 0 | ||||
|  | ||||
| #define LOCAL_VARS							\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx);			\ | ||||
|    r200ScreenPtr r200Screen = rmesa->r200Screen;			\ | ||||
|    __DRIscreenPrivate *sPriv = rmesa->dri.screen;			\ | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;			\ | ||||
|    GLuint pitch = r200Screen->frontPitch * r200Screen->cpp;		\ | ||||
|    GLuint height = dPriv->h;						\ | ||||
|    char *buf = (char *)(sPriv->pFB +					\ | ||||
| 			rmesa->state.color.drawOffset +			\ | ||||
| 			(dPriv->x * r200Screen->cpp) +		\ | ||||
| 			(dPriv->y * pitch));				\ | ||||
|    char *read_buf = (char *)(sPriv->pFB +				\ | ||||
| 			     rmesa->state.pixel.readOffset +		\ | ||||
| 			     (dPriv->x * r200Screen->cpp) +		\ | ||||
| 			     (dPriv->y * pitch));			\ | ||||
|    GLuint p;								\ | ||||
|    (void) read_buf; (void) buf; (void) p | ||||
|  | ||||
| #define LOCAL_DEPTH_VARS						\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx);			\ | ||||
|    r200ScreenPtr r200Screen = rmesa->r200Screen;			\ | ||||
|    __DRIscreenPrivate *sPriv = rmesa->dri.screen;			\ | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;			\ | ||||
|    GLuint height = dPriv->h;						\ | ||||
|    GLuint xo = dPriv->x;						\ | ||||
|    GLuint yo = dPriv->y;						\ | ||||
|    char *buf = (char *)(sPriv->pFB + r200Screen->depthOffset);	\ | ||||
|    (void) buf | ||||
|  | ||||
| #define LOCAL_STENCIL_VARS	LOCAL_DEPTH_VARS | ||||
|  | ||||
|  | ||||
| #define CLIPPIXEL( _x, _y )						\ | ||||
|    ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) | ||||
|  | ||||
|  | ||||
| #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )				\ | ||||
|    if ( _y < miny || _y >= maxy ) {					\ | ||||
|       _n1 = 0, _x1 = x;							\ | ||||
|    } else {								\ | ||||
|       _n1 = _n;								\ | ||||
|       _x1 = _x;								\ | ||||
|       if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ | ||||
|       if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);		        \ | ||||
|    } | ||||
|  | ||||
| #define Y_FLIP( _y )		(height - _y - 1) | ||||
|  | ||||
|  | ||||
| #define HW_LOCK()  | ||||
|  | ||||
| #define HW_CLIPLOOP()							\ | ||||
|    do {									\ | ||||
|       __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;		\ | ||||
|       int _nc = dPriv->numClipRects;					\ | ||||
| 									\ | ||||
|       while ( _nc-- ) {							\ | ||||
| 	 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x;		\ | ||||
| 	 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y;		\ | ||||
| 	 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;		\ | ||||
| 	 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; | ||||
|  | ||||
| #define HW_ENDCLIPLOOP()						\ | ||||
|       }									\ | ||||
|    } while (0) | ||||
|  | ||||
| #define HW_UNLOCK()							 | ||||
|  | ||||
|  | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Color buffer | ||||
|  */ | ||||
|  | ||||
| /* 16 bit, RGB565 color spanline and pixel functions | ||||
|  */ | ||||
| #define INIT_MONO_PIXEL(p, color) \ | ||||
|   p = PACK_COLOR_565( color[0], color[1], color[2] ) | ||||
|  | ||||
| #define WRITE_RGBA( _x, _y, r, g, b, a )				\ | ||||
|    *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) |	\ | ||||
| 					   (((int)g & 0xfc) << 3) |	\ | ||||
| 					   (((int)b & 0xf8) >> 3)) | ||||
|  | ||||
| #define WRITE_PIXEL( _x, _y, p )					\ | ||||
|    *(GLushort *)(buf + _x*2 + _y*pitch) = p | ||||
|  | ||||
| #define READ_RGBA( rgba, _x, _y )					\ | ||||
|    do {									\ | ||||
|       GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch);		\ | ||||
|       rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;				\ | ||||
|       rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;				\ | ||||
|       rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;				\ | ||||
|       rgba[3] = 0xff;							\ | ||||
|    } while (0) | ||||
|  | ||||
| #define TAG(x) r200##x##_RGB565 | ||||
| #include "spantmp.h" | ||||
|  | ||||
| /* 32 bit, ARGB8888 color spanline and pixel functions | ||||
|  */ | ||||
| #undef INIT_MONO_PIXEL | ||||
| #define INIT_MONO_PIXEL(p, color) \ | ||||
|   p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] ) | ||||
|  | ||||
| #define WRITE_RGBA( _x, _y, r, g, b, a )			\ | ||||
| do {								\ | ||||
|    *(GLuint *)(buf + _x*4 + _y*pitch) = ((b <<  0) |		\ | ||||
| 					 (g <<  8) |		\ | ||||
| 					 (r << 16) |		\ | ||||
| 					 (a << 24) );		\ | ||||
| } while (0) | ||||
|  | ||||
| #define WRITE_PIXEL( _x, _y, p ) 			\ | ||||
| do {							\ | ||||
|    *(GLuint *)(buf + _x*4 + _y*pitch) = p;		\ | ||||
| } while (0) | ||||
|  | ||||
| #define READ_RGBA( rgba, _x, _y )				\ | ||||
| do {								\ | ||||
|    volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \ | ||||
|    GLuint p = *ptr;					\ | ||||
|    rgba[0] = (p >> 16) & 0xff;					\ | ||||
|    rgba[1] = (p >>  8) & 0xff;					\ | ||||
|    rgba[2] = (p >>  0) & 0xff;					\ | ||||
|    rgba[3] = (p >> 24) & 0xff;					\ | ||||
| } while (0) | ||||
|  | ||||
| #define TAG(x) r200##x##_ARGB8888 | ||||
| #include "spantmp.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Depth buffer | ||||
|  */ | ||||
|  | ||||
| /* The R200 has depth tiling on all the time, so we have to convert | ||||
|  * the x,y coordinates into the memory bus address (mba) in the same | ||||
|  * manner as the engine.  In each case, the linear block address (ba) | ||||
|  * is calculated, and then wired with x and y to produce the final | ||||
|  * memory address. | ||||
|  */ | ||||
|  | ||||
| #define BIT(x,b) ((x & (1<<b))>>b) | ||||
| static GLuint r200_mba_z32( r200ContextPtr rmesa, | ||||
| 				       GLint x, GLint y ) | ||||
| { | ||||
|    GLuint pitch = rmesa->r200Screen->frontPitch; | ||||
|    GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x3FF) >> 5); | ||||
|    GLuint a =  | ||||
|       (BIT(x,0) << 2) | | ||||
|       (BIT(y,0) << 3) | | ||||
|       (BIT(x,1) << 4) | | ||||
|       (BIT(y,1) << 5) | | ||||
|       (BIT(x,3) << 6) | | ||||
|       (BIT(x,4) << 7) | | ||||
|       (BIT(x,2) << 8) | | ||||
|       (BIT(y,2) << 9) | | ||||
|       (BIT(y,3) << 10) | | ||||
|       (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | | ||||
|       ((b >> 1) << 12); | ||||
|    return a; | ||||
| } | ||||
|  | ||||
| static GLuint r200_mba_z16( r200ContextPtr rmesa, GLint x, GLint y ) | ||||
| { | ||||
|    GLuint pitch = rmesa->r200Screen->frontPitch; | ||||
|    GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x3FF) >> 6); | ||||
|    GLuint a =  | ||||
|       (BIT(x,0) << 1) | | ||||
|       (BIT(y,0) << 2) | | ||||
|       (BIT(x,1) << 3) | | ||||
|       (BIT(y,1) << 4) | | ||||
|       (BIT(x,2) << 5) | | ||||
|       (BIT(x,4) << 6) | | ||||
|       (BIT(x,5) << 7) | | ||||
|       (BIT(x,3) << 8) | | ||||
|       (BIT(y,2) << 9) | | ||||
|       (BIT(y,3) << 10) | | ||||
|       (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | | ||||
|       ((b >> 1) << 12); | ||||
|    return a; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* 16-bit depth buffer functions | ||||
|  */ | ||||
| #define WRITE_DEPTH( _x, _y, d )					\ | ||||
|    *(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo )) = d; | ||||
|  | ||||
| #define READ_DEPTH( d, _x, _y )						\ | ||||
|    d = *(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo )); | ||||
|  | ||||
| #define TAG(x) r200##x##_16 | ||||
| #include "depthtmp.h" | ||||
|  | ||||
| /* 24 bit depth, 8 bit stencil depthbuffer functions | ||||
|  */ | ||||
| #define WRITE_DEPTH( _x, _y, d )					\ | ||||
| do {									\ | ||||
|    GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo );		\ | ||||
|    GLuint tmp = *(GLuint *)(buf + offset);				\ | ||||
|    tmp &= 0xff000000;							\ | ||||
|    tmp |= ((d) & 0x00ffffff);						\ | ||||
|    *(GLuint *)(buf + offset) = tmp;					\ | ||||
| } while (0) | ||||
|  | ||||
| #define READ_DEPTH( d, _x, _y )						\ | ||||
|    d = *(GLuint *)(buf + r200_mba_z32( rmesa, _x + xo,		\ | ||||
| 					 _y + yo )) & 0x00ffffff; | ||||
|  | ||||
| #define TAG(x) r200##x##_24_8 | ||||
| #include "depthtmp.h" | ||||
|  | ||||
|  | ||||
| /* ================================================================ | ||||
|  * Stencil buffer | ||||
|  */ | ||||
|  | ||||
| /* 24 bit depth, 8 bit stencil depthbuffer functions | ||||
|  */ | ||||
| #define WRITE_STENCIL( _x, _y, d )					\ | ||||
| do {									\ | ||||
|    GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo );		\ | ||||
|    GLuint tmp = *(GLuint *)(buf + offset);				\ | ||||
|    tmp &= 0x00ffffff;							\ | ||||
|    tmp |= (((d) & 0xff) << 24);						\ | ||||
|    *(GLuint *)(buf + offset) = tmp;					\ | ||||
| } while (0) | ||||
|  | ||||
| #define READ_STENCIL( d, _x, _y )					\ | ||||
| do {									\ | ||||
|    GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo );		\ | ||||
|    GLuint tmp = *(GLuint *)(buf + offset);				\ | ||||
|    tmp &= 0xff000000;							\ | ||||
|    d = tmp >> 24;							\ | ||||
| } while (0) | ||||
|  | ||||
| #define TAG(x) r200##x##_24_8 | ||||
| #include "stenciltmp.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * This function is called to specify which buffer to read and write | ||||
|  * for software rasterization (swrast) fallbacks.  This doesn't necessarily | ||||
|  * correspond to glDrawBuffer() or glReadBuffer() calls. | ||||
|  */ | ||||
| static void r200SetBuffer( GLcontext *ctx, | ||||
|                            GLframebuffer *colorBuffer, | ||||
|                            GLuint bufferBit ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    switch ( bufferBit ) { | ||||
|    case FRONT_LEFT_BIT: | ||||
|       if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { | ||||
|         rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset; | ||||
|         rmesa->state.pixel.readPitch  = rmesa->r200Screen->backPitch; | ||||
|         rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; | ||||
|         rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch; | ||||
|       } else { | ||||
|       	rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset; | ||||
|       	rmesa->state.pixel.readPitch  = rmesa->r200Screen->frontPitch; | ||||
|       	rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; | ||||
|       	rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch; | ||||
|       } | ||||
|       break; | ||||
|    case BACK_LEFT_BIT: | ||||
|       if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { | ||||
|       	rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset; | ||||
|       	rmesa->state.pixel.readPitch  = rmesa->r200Screen->frontPitch; | ||||
|       	rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; | ||||
|       	rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch; | ||||
|       } else { | ||||
|         rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset; | ||||
|         rmesa->state.pixel.readPitch  = rmesa->r200Screen->backPitch; | ||||
|         rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; | ||||
|         rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch; | ||||
|       } | ||||
|       break; | ||||
|    default: | ||||
|       _mesa_problem(ctx, "Bad bufferBit in r200SetBuffer()"); | ||||
|       break; | ||||
|    } | ||||
| } | ||||
|  | ||||
| /* Move locking out to get reasonable span performance (10x better | ||||
|  * than doing this in HW_LOCK above).  WaitForIdle() is the main | ||||
|  * culprit. | ||||
|  */ | ||||
|  | ||||
| static void r200SpanRenderStart( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|  | ||||
|    R200_FIREVERTICES( rmesa ); | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|    r200WaitForIdleLocked( rmesa ); | ||||
|  | ||||
|    /* Read & rewrite the first pixel in the frame buffer.  This should | ||||
|     * be a noop, right?  In fact without this conform fails as reading | ||||
|     * from the framebuffer sometimes produces old results -- the | ||||
|     * on-card read cache gets mixed up and doesn't notice that the | ||||
|     * framebuffer has been updated. | ||||
|     * | ||||
|     * In the worst case this is buggy too as p might get the wrong | ||||
|     * value first time, so really need a hidden pixel somewhere for this. | ||||
|     */ | ||||
|    { | ||||
|       int p; | ||||
|       volatile int *read_buf = (volatile int *)(rmesa->dri.screen->pFB +  | ||||
| 						rmesa->state.pixel.readOffset); | ||||
|       p = *read_buf; | ||||
|       *read_buf = p; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200SpanRenderFinish( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|    _swrast_flush( ctx ); | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
| } | ||||
|  | ||||
| void r200InitSpanFuncs( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); | ||||
|  | ||||
|    swdd->SetBuffer = r200SetBuffer; | ||||
|  | ||||
|    switch ( rmesa->r200Screen->cpp ) { | ||||
|    case 2: | ||||
|       swdd->WriteRGBASpan	= r200WriteRGBASpan_RGB565; | ||||
|       swdd->WriteRGBSpan	= r200WriteRGBSpan_RGB565; | ||||
|       swdd->WriteMonoRGBASpan	= r200WriteMonoRGBASpan_RGB565; | ||||
|       swdd->WriteRGBAPixels	= r200WriteRGBAPixels_RGB565; | ||||
|       swdd->WriteMonoRGBAPixels	= r200WriteMonoRGBAPixels_RGB565; | ||||
|       swdd->ReadRGBASpan	= r200ReadRGBASpan_RGB565; | ||||
|       swdd->ReadRGBAPixels      = r200ReadRGBAPixels_RGB565; | ||||
|       break; | ||||
|  | ||||
|    case 4: | ||||
|       swdd->WriteRGBASpan	= r200WriteRGBASpan_ARGB8888; | ||||
|       swdd->WriteRGBSpan	= r200WriteRGBSpan_ARGB8888; | ||||
|       swdd->WriteMonoRGBASpan   = r200WriteMonoRGBASpan_ARGB8888; | ||||
|       swdd->WriteRGBAPixels     = r200WriteRGBAPixels_ARGB8888; | ||||
|       swdd->WriteMonoRGBAPixels = r200WriteMonoRGBAPixels_ARGB8888; | ||||
|       swdd->ReadRGBASpan	= r200ReadRGBASpan_ARGB8888; | ||||
|       swdd->ReadRGBAPixels      = r200ReadRGBAPixels_ARGB8888; | ||||
|       break; | ||||
|  | ||||
|    default: | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    switch ( rmesa->glCtx->Visual.depthBits ) { | ||||
|    case 16: | ||||
|       swdd->ReadDepthSpan	= r200ReadDepthSpan_16; | ||||
|       swdd->WriteDepthSpan	= r200WriteDepthSpan_16; | ||||
|       swdd->ReadDepthPixels	= r200ReadDepthPixels_16; | ||||
|       swdd->WriteDepthPixels	= r200WriteDepthPixels_16; | ||||
|       break; | ||||
|  | ||||
|    case 24: | ||||
|       swdd->ReadDepthSpan	= r200ReadDepthSpan_24_8; | ||||
|       swdd->WriteDepthSpan	= r200WriteDepthSpan_24_8; | ||||
|       swdd->ReadDepthPixels	= r200ReadDepthPixels_24_8; | ||||
|       swdd->WriteDepthPixels	= r200WriteDepthPixels_24_8; | ||||
|  | ||||
|       swdd->ReadStencilSpan	= r200ReadStencilSpan_24_8; | ||||
|       swdd->WriteStencilSpan	= r200WriteStencilSpan_24_8; | ||||
|       swdd->ReadStencilPixels	= r200ReadStencilPixels_24_8; | ||||
|       swdd->WriteStencilPixels	= r200WriteStencilPixels_24_8; | ||||
|       break; | ||||
|  | ||||
|    default: | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    swdd->SpanRenderStart          = r200SpanRenderStart; | ||||
|    swdd->SpanRenderFinish         = r200SpanRenderFinish;  | ||||
| } | ||||
							
								
								
									
										43
									
								
								src/mesa/drivers/dri/r200/r200_span.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/mesa/drivers/dri/r200/r200_span.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_SPAN_H__ | ||||
| #define __R200_SPAN_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| extern void r200InitSpanFuncs( GLcontext *ctx ); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										2155
									
								
								src/mesa/drivers/dri/r200/r200_state.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2155
									
								
								src/mesa/drivers/dri/r200/r200_state.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										68
									
								
								src/mesa/drivers/dri/r200/r200_state.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/mesa/drivers/dri/r200/r200_state.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_STATE_H__ | ||||
| #define __R200_STATE_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "r200_context.h" | ||||
|  | ||||
| extern void r200InitState( r200ContextPtr rmesa ); | ||||
| extern void r200InitStateFuncs( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200UpdateMaterial( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ); | ||||
| extern void r200RecalcScissorRects( r200ContextPtr rmesa ); | ||||
| extern void r200UpdateViewportOffset( GLcontext *ctx ); | ||||
| extern void r200UpdateWindow( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200ValidateState( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200PrintDirty( r200ContextPtr rmesa, | ||||
| 			      const char *msg ); | ||||
|  | ||||
|  | ||||
| extern void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); | ||||
| #define FALLBACK( rmesa, bit, mode ) do {				\ | ||||
|    if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n",		\ | ||||
| 		     __FUNCTION__, bit, mode );				\ | ||||
|    r200Fallback( rmesa->glCtx, bit, mode );				\ | ||||
| } while (0) | ||||
|  | ||||
| extern void r200LightingSpaceChange( GLcontext *ctx ); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										692
									
								
								src/mesa/drivers/dri/r200/r200_state_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										692
									
								
								src/mesa/drivers/dri/r200/r200_state_init.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,692 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h" | ||||
| #include "enums.h" | ||||
| #include "colormac.h" | ||||
| #include "api_arrayelt.h" | ||||
|  | ||||
| #include "swrast/swrast.h" | ||||
| #include "array_cache/acache.h" | ||||
| #include "tnl/tnl.h" | ||||
| #include "tnl/t_pipeline.h" | ||||
| #include "swrast_setup/swrast_setup.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_tex.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_vtxfmt.h" | ||||
|  | ||||
| /* ============================================================= | ||||
|  * State initialization | ||||
|  */ | ||||
|  | ||||
| void r200PrintDirty( r200ContextPtr rmesa, const char *msg ) | ||||
| { | ||||
|    struct r200_state_atom *l; | ||||
|  | ||||
|    fprintf(stderr, msg); | ||||
|    fprintf(stderr, ": "); | ||||
|  | ||||
|    foreach(l, &(rmesa->hw.dirty)) { | ||||
|       fprintf(stderr, "%s, ", l->name); | ||||
|    } | ||||
|  | ||||
|    fprintf(stderr, "\n"); | ||||
| } | ||||
|  | ||||
| static int cmdpkt( int id )  | ||||
| { | ||||
|    drmRadeonCmdHeader h; | ||||
|    h.i = 0; | ||||
|    h.packet.cmd_type = RADEON_CMD_PACKET; | ||||
|    h.packet.packet_id = id; | ||||
|    return h.i; | ||||
| } | ||||
|  | ||||
| static int cmdvec( int offset, int stride, int count )  | ||||
| { | ||||
|    drmRadeonCmdHeader h; | ||||
|    h.i = 0; | ||||
|    h.vectors.cmd_type = RADEON_CMD_VECTORS; | ||||
|    h.vectors.offset = offset; | ||||
|    h.vectors.stride = stride; | ||||
|    h.vectors.count = count; | ||||
|    return h.i; | ||||
| } | ||||
|  | ||||
| static int cmdscl( int offset, int stride, int count )  | ||||
| { | ||||
|    drmRadeonCmdHeader h; | ||||
|    h.i = 0; | ||||
|    h.scalars.cmd_type = RADEON_CMD_SCALARS; | ||||
|    h.scalars.offset = offset; | ||||
|    h.scalars.stride = stride; | ||||
|    h.scalars.count = count; | ||||
|    return h.i; | ||||
| } | ||||
|  | ||||
| static int cmdscl2( int offset, int stride, int count )  | ||||
| { | ||||
|    drmRadeonCmdHeader h; | ||||
|    h.i = 0; | ||||
|    h.scalars.cmd_type = RADEON_CMD_SCALARS2; | ||||
|    h.scalars.offset = offset - 0x100; | ||||
|    h.scalars.stride = stride; | ||||
|    h.scalars.count = count; | ||||
|    return h.i; | ||||
| } | ||||
|  | ||||
| #define CHECK( NM, FLAG )				\ | ||||
| static GLboolean check_##NM( GLcontext *ctx, int idx )	\ | ||||
| {							\ | ||||
|    (void) idx;						\ | ||||
|    return FLAG;						\ | ||||
| } | ||||
|  | ||||
| #define TCL_CHECK( NM, FLAG )				\ | ||||
| static GLboolean check_##NM( GLcontext *ctx, int idx )	\ | ||||
| {							\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx);		\ | ||||
|    (void) idx;						\ | ||||
|    return !rmesa->TclFallback && (FLAG);		\ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| CHECK( always, GL_TRUE ) | ||||
| CHECK( tex_any, ctx->Texture._EnabledUnits ) | ||||
| CHECK( tex, ctx->Texture.Unit[idx]._ReallyEnabled ) | ||||
| CHECK( fog, ctx->Fog.Enabled ) | ||||
| TCL_CHECK( tcl, GL_TRUE ) | ||||
| TCL_CHECK( tcl_tex_any, ctx->Texture._EnabledUnits ) | ||||
| TCL_CHECK( tcl_tex, ctx->Texture.Unit[idx]._ReallyEnabled ) | ||||
| TCL_CHECK( tcl_lighting, ctx->Light.Enabled ) | ||||
| TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled ) | ||||
| TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[idx].Enabled ) | ||||
| TCL_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << idx)) ) | ||||
| /* TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled )  */ | ||||
|  | ||||
|  | ||||
| static GLboolean check_tcl_eyespace_or_fog( GLcontext *ctx, int idx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    int res; | ||||
|    (void) idx; | ||||
|    res = !rmesa->TclFallback && (ctx->_NeedEyeCoords || ctx->Fog.Enabled); | ||||
|    fprintf(stderr, "%s: %d\n", __FUNCTION__, res); | ||||
|    return res; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Initialize the context's hardware state. | ||||
|  */ | ||||
| void r200InitState( r200ContextPtr rmesa ) | ||||
| { | ||||
|    GLcontext *ctx = rmesa->glCtx; | ||||
|    GLuint color_fmt, depth_fmt, i; | ||||
|  | ||||
|    switch ( rmesa->r200Screen->cpp ) { | ||||
|    case 2: | ||||
|       color_fmt = R200_COLOR_FORMAT_RGB565; | ||||
|       break; | ||||
|    case 4: | ||||
|       color_fmt = R200_COLOR_FORMAT_ARGB8888; | ||||
|       break; | ||||
|    default: | ||||
|       fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); | ||||
|       exit( -1 ); | ||||
|    } | ||||
|  | ||||
|    rmesa->state.color.clear = 0x00000000; | ||||
|  | ||||
|    switch ( ctx->Visual.depthBits ) { | ||||
|    case 16: | ||||
|       rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; | ||||
|       depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z; | ||||
|       rmesa->state.stencil.clear = 0x00000000; | ||||
|       break; | ||||
|    case 24: | ||||
|       rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; | ||||
|       depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z; | ||||
|       rmesa->state.stencil.clear = 0xff000000; | ||||
|       break; | ||||
|    default: | ||||
|       fprintf( stderr, "Error: Unsupported depth %d... exiting\n", | ||||
| 	       ctx->Visual.depthBits ); | ||||
|       exit( -1 ); | ||||
|    } | ||||
|  | ||||
|    /* Only have hw stencil when depth buffer is 24 bits deep */ | ||||
|    rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && | ||||
| 				     ctx->Visual.depthBits == 24 ); | ||||
|  | ||||
|    rmesa->Fallback = 0; | ||||
|  | ||||
|    if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { | ||||
|       rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; | ||||
|       rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch; | ||||
|    } else { | ||||
|       rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; | ||||
|       rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch; | ||||
|    } | ||||
|  | ||||
|    rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; | ||||
|    rmesa->state.pixel.readPitch  = rmesa->state.color.drawPitch; | ||||
|  | ||||
|    /* Initialize lists: | ||||
|     */ | ||||
|    make_empty_list(&(rmesa->hw.dirty)); rmesa->hw.dirty.name = "DIRTY"; | ||||
|    make_empty_list(&(rmesa->hw.clean)); rmesa->hw.clean.name = "CLEAN"; | ||||
|  | ||||
|  | ||||
| #define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX )				\ | ||||
|    do {								\ | ||||
|       rmesa->hw.ATOM.cmd_size = SZ;				\ | ||||
|       rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int));	\ | ||||
|       rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int));	\ | ||||
|       rmesa->hw.ATOM.name = NM;					\ | ||||
|       rmesa->hw.ATOM.idx = IDX;					\ | ||||
|       rmesa->hw.ATOM.check = check_##CHK;				\ | ||||
|       insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM));	\ | ||||
|    } while (0) | ||||
|        | ||||
|        | ||||
|    /* Allocate state buffers: | ||||
|     */ | ||||
|    ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 ); | ||||
|    ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 ); | ||||
|    ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); | ||||
|    ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); | ||||
|    ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 ); | ||||
|    ALLOC_STATE( vtx, always, VTX_STATE_SIZE, "VTX/vertex", 0 ); | ||||
|    ALLOC_STATE( vap, always, VAP_STATE_SIZE, "VAP/vap", 0 ); | ||||
|    ALLOC_STATE( vte, always, VTE_STATE_SIZE, "VTE/vte", 0 ); | ||||
|    ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 ); | ||||
|    ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 ); | ||||
|    ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 ); | ||||
|    ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 ); | ||||
|    ALLOC_STATE( tf, tex_any, TF_STATE_SIZE, "TF/tfactor", 0 ); | ||||
|    ALLOC_STATE( tex[0], tex_any, TEX_STATE_SIZE, "TEX/tex-0", 0 ); | ||||
|    ALLOC_STATE( tex[1], tex_any, TEX_STATE_SIZE, "TEX/tex-1", 1 ); | ||||
|    ALLOC_STATE( cube[0], tex_any, CUBE_STATE_SIZE, "CUBE/tex-0", 0 ); | ||||
|    ALLOC_STATE( cube[1], tex_any, CUBE_STATE_SIZE, "CUBE/tex-1", 1 ); | ||||
|  | ||||
|    ALLOC_STATE( tcl, tcl, TCL_STATE_SIZE, "TCL/tcl", 0 ); | ||||
|    ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 ); | ||||
|    ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 ); | ||||
|    ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 ); | ||||
|    ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 ); | ||||
|    ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 ); | ||||
|    ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 ); | ||||
|    ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 ); | ||||
|    ALLOC_STATE( mat[R200_MTX_MV], tcl, MAT_STATE_SIZE, "MAT/modelview", 0 ); | ||||
|    ALLOC_STATE( mat[R200_MTX_IMV], tcl, MAT_STATE_SIZE, "MAT/it-modelview", 0 ); | ||||
|    ALLOC_STATE( mat[R200_MTX_MVP], tcl, MAT_STATE_SIZE, "MAT/modelproject", 0 ); | ||||
|    ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex, MAT_STATE_SIZE, "MAT/texmat0", 0 ); | ||||
|    ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex, MAT_STATE_SIZE, "MAT/texmat1", 1 ); | ||||
|    ALLOC_STATE( ucp[0], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-0", 0 ); | ||||
|    ALLOC_STATE( ucp[1], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-1", 1 ); | ||||
|    ALLOC_STATE( ucp[2], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-2", 2 ); | ||||
|    ALLOC_STATE( ucp[3], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-3", 3 ); | ||||
|    ALLOC_STATE( ucp[4], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-4", 4 ); | ||||
|    ALLOC_STATE( ucp[5], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-5", 5 ); | ||||
|    ALLOC_STATE( lit[0], tcl_light, LIT_STATE_SIZE, "LIT/light-0", 0 ); | ||||
|    ALLOC_STATE( lit[1], tcl_light, LIT_STATE_SIZE, "LIT/light-1", 1 ); | ||||
|    ALLOC_STATE( lit[2], tcl_light, LIT_STATE_SIZE, "LIT/light-2", 2 ); | ||||
|    ALLOC_STATE( lit[3], tcl_light, LIT_STATE_SIZE, "LIT/light-3", 3 ); | ||||
|    ALLOC_STATE( lit[4], tcl_light, LIT_STATE_SIZE, "LIT/light-4", 4 ); | ||||
|    ALLOC_STATE( lit[5], tcl_light, LIT_STATE_SIZE, "LIT/light-5", 5 ); | ||||
|    ALLOC_STATE( lit[6], tcl_light, LIT_STATE_SIZE, "LIT/light-6", 6 ); | ||||
|    ALLOC_STATE( lit[7], tcl_light, LIT_STATE_SIZE, "LIT/light-7", 7 ); | ||||
|    ALLOC_STATE( pix[0], always, PIX_STATE_SIZE, "PIX/pixstage-0", 0 ); | ||||
|    ALLOC_STATE( pix[1], tex, PIX_STATE_SIZE, "PIX/pixstage-1", 1 ); | ||||
|  | ||||
|  | ||||
|    /* Fill in the packet headers: | ||||
|     */ | ||||
|    rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC); | ||||
|    rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL); | ||||
|    rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH); | ||||
|    rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN); | ||||
|    rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH); | ||||
|    rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK); | ||||
|    rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE); | ||||
|    rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL); | ||||
|    rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_0] = cmdpkt(R200_EMIT_PP_CNTL_X); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_1] = cmdpkt(R200_EMIT_RB3D_DEPTHXY_OFFSET); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_2] = cmdpkt(R200_EMIT_RE_AUX_SCISSOR_CNTL); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_3] = cmdpkt(R200_EMIT_RE_SCISSOR_TL_0); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_4] = cmdpkt(R200_EMIT_SE_VAP_CNTL_STATUS); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_5] = cmdpkt(R200_EMIT_RE_POINTSIZE); | ||||
|    rmesa->hw.cst.cmd[CST_CMD_6] = cmdpkt(R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0); | ||||
|    rmesa->hw.tam.cmd[TAM_CMD_0] = cmdpkt(R200_EMIT_PP_TAM_DEBUG3); | ||||
|    rmesa->hw.tf.cmd[TF_CMD_0]   = cmdpkt(R200_EMIT_TFACTOR_0); | ||||
|    rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_0); | ||||
|    rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_0); | ||||
|    rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_1); | ||||
|    rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_1); | ||||
|    rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_0); | ||||
|    rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_0); | ||||
|    rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_1); | ||||
|    rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_1); | ||||
|    rmesa->hw.pix[0].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_0); | ||||
|    rmesa->hw.pix[1].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_1); | ||||
|    rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR); | ||||
|    rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(R200_EMIT_TCL_LIGHT_MODEL_CTL_0); | ||||
|    rmesa->hw.tcl.cmd[TCL_CMD_1] = cmdpkt(R200_EMIT_TCL_UCP_VERT_BLEND_CTL); | ||||
|    rmesa->hw.tcg.cmd[TCG_CMD_0] = cmdpkt(R200_EMIT_TEX_PROC_CTL_2); | ||||
|    rmesa->hw.msl.cmd[MSL_CMD_0] = cmdpkt(R200_EMIT_MATRIX_SELECT_0); | ||||
|    rmesa->hw.vap.cmd[VAP_CMD_0] = cmdpkt(R200_EMIT_VAP_CTL); | ||||
|    rmesa->hw.vtx.cmd[VTX_CMD_0] = cmdpkt(R200_EMIT_VTX_FMT_0); | ||||
|    rmesa->hw.vtx.cmd[VTX_CMD_1] = cmdpkt(R200_EMIT_OUTPUT_VTX_COMP_SEL); | ||||
|    rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(R200_EMIT_SE_VTX_STATE_CNTL); | ||||
|    rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(R200_EMIT_VTE_CNTL); | ||||
|    rmesa->hw.mtl[0].cmd[MTL_CMD_0] =  | ||||
|       cmdvec( R200_VS_MAT_0_EMISS, 1, 16 ); | ||||
|    rmesa->hw.mtl[0].cmd[MTL_CMD_1] =  | ||||
|       cmdscl2( R200_SS_MAT_0_SHININESS, 1, 1 ); | ||||
|    rmesa->hw.grd.cmd[GRD_CMD_0] =  | ||||
|       cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); | ||||
|    rmesa->hw.fog.cmd[FOG_CMD_0] =  | ||||
|       cmdvec( R200_VS_FOG_PARAM_ADDR, 1, 4 ); | ||||
|    rmesa->hw.glt.cmd[GLT_CMD_0] =  | ||||
|       cmdvec( R200_VS_GLOBAL_AMBIENT_ADDR, 1, 4 ); | ||||
|    rmesa->hw.eye.cmd[EYE_CMD_0] =  | ||||
|       cmdvec( R200_VS_EYE_VECTOR_ADDR, 1, 4 ); | ||||
|  | ||||
|    rmesa->hw.mat[R200_MTX_MV].cmd[MAT_CMD_0] =  | ||||
|       cmdvec( R200_VS_MATRIX_0_MV, 1, 16); | ||||
|    rmesa->hw.mat[R200_MTX_IMV].cmd[MAT_CMD_0] =  | ||||
|       cmdvec( R200_VS_MATRIX_1_INV_MV, 1, 16); | ||||
|    rmesa->hw.mat[R200_MTX_MVP].cmd[MAT_CMD_0] =  | ||||
|       cmdvec( R200_VS_MATRIX_2_MVP, 1, 16); | ||||
|    rmesa->hw.mat[R200_MTX_TEX0].cmd[MAT_CMD_0] =  | ||||
|       cmdvec( R200_VS_MATRIX_3_TEX0, 1, 16); | ||||
|    rmesa->hw.mat[R200_MTX_TEX1].cmd[MAT_CMD_0] =  | ||||
|       cmdvec( R200_VS_MATRIX_4_TEX1, 1, 16); | ||||
|  | ||||
|    for (i = 0 ; i < 8; i++) { | ||||
|       rmesa->hw.lit[i].cmd[LIT_CMD_0] =  | ||||
| 	 cmdvec( R200_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 ); | ||||
|       rmesa->hw.lit[i].cmd[LIT_CMD_1] =  | ||||
| 	 cmdscl( R200_SS_LIGHT_DCD_ADDR + i, 8, 7 ); | ||||
|    } | ||||
|  | ||||
|    for (i = 0 ; i < 6; i++) { | ||||
|       rmesa->hw.ucp[i].cmd[UCP_CMD_0] =  | ||||
| 	 cmdvec( R200_VS_UCP_ADDR + i, 1, 4 ); | ||||
|    } | ||||
|  | ||||
|    /* Initial Harware state: | ||||
|     */ | ||||
|    rmesa->hw.ctx.cmd[CTX_PP_MISC] = (R200_ALPHA_TEST_PASS | ||||
| 				     /* | R200_RIGHT_HAND_CUBE_OGL*/); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (R200_FOG_VERTEX | | ||||
| 					  R200_FOG_USE_SPEC_ALPHA); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000; | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP | | ||||
| 					    R200_SRC_BLEND_GL_ONE | | ||||
| 					    R200_DST_BLEND_GL_ZERO ); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = | ||||
|       rmesa->r200Screen->depthOffset; | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] =  | ||||
|       ((rmesa->r200Screen->depthPitch & | ||||
| 	R200_DEPTHPITCH_MASK) | | ||||
|        R200_DEPTH_ENDIAN_NO_SWAP); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt | | ||||
|   					       R200_Z_TEST_LESS |   | ||||
| 					       R200_STENCIL_TEST_ALWAYS | | ||||
| 					       R200_STENCIL_FAIL_KEEP | | ||||
| 					       R200_STENCIL_ZPASS_KEEP | | ||||
| 					       R200_STENCIL_ZFAIL_KEEP | | ||||
| 					       R200_Z_WRITE_ENABLE); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (R200_ANTI_ALIAS_NONE  | ||||
|  				     | R200_TEX_BLEND_0_ENABLE); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = color_fmt; | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_DITHER_ENABLE; | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset & | ||||
| 					      R200_COLOROFFSET_MASK); | ||||
|  | ||||
|    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & | ||||
| 					      R200_COLORPITCH_MASK) | | ||||
| 					     R200_COLOR_ENDIAN_NO_SWAP); | ||||
|  | ||||
|    rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW | | ||||
| 				     R200_BFACE_SOLID | | ||||
| 				     R200_FFACE_SOLID | | ||||
| 				     R200_FLAT_SHADE_VTX_LAST | | ||||
| 				     R200_DIFFUSE_SHADE_GOURAUD | | ||||
| 				     R200_ALPHA_SHADE_GOURAUD | | ||||
| 				     R200_SPECULAR_SHADE_GOURAUD | | ||||
| 				     R200_FOG_SHADE_GOURAUD | | ||||
| 				     R200_VTX_PIX_CENTER_OGL | | ||||
| 				     R200_ROUND_MODE_TRUNC | | ||||
| 				     R200_ROUND_PREC_8TH_PIX); | ||||
|  | ||||
|    rmesa->hw.set.cmd[SET_RE_CNTL] = (R200_PERSPECTIVE_ENABLE | | ||||
| 				     R200_SCISSOR_ENABLE); | ||||
|  | ||||
|    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff); | ||||
|  | ||||
|    rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] =  | ||||
|       ((0 << R200_LINE_CURRENT_PTR_SHIFT) | | ||||
|        (1 << R200_LINE_CURRENT_COUNT_SHIFT)); | ||||
|  | ||||
|    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4); | ||||
|  | ||||
|    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] =  | ||||
|       ((0x00 << R200_STENCIL_REF_SHIFT) | | ||||
|        (0xff << R200_STENCIL_MASK_SHIFT) | | ||||
|        (0xff << R200_STENCIL_WRITEMASK_SHIFT)); | ||||
|  | ||||
|    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = R200_ROP_COPY; | ||||
|    rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff; | ||||
|  | ||||
|    rmesa->hw.tam.cmd[TAM_DEBUG3] = 0; | ||||
|  | ||||
|    rmesa->hw.msc.cmd[MSC_RE_MISC] =  | ||||
|       ((0 << R200_STIPPLE_X_OFFSET_SHIFT) | | ||||
|        (0 << R200_STIPPLE_Y_OFFSET_SHIFT) | | ||||
|        R200_STIPPLE_BIG_BIT_ORDER); | ||||
|  | ||||
|  | ||||
|    rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0; | ||||
|    rmesa->hw.cst.cmd[CST_RB3D_DEPTHXY_OFFSET] = 0; | ||||
|    rmesa->hw.cst.cmd[CST_RE_AUX_SCISSOR_CNTL] = 0x0; | ||||
|    rmesa->hw.cst.cmd[CST_RE_SCISSOR_TL_0] = 0; | ||||
|    rmesa->hw.cst.cmd[CST_RE_SCISSOR_BR_0] = 0; | ||||
|    rmesa->hw.cst.cmd[CST_SE_VAP_CNTL_STATUS] = | ||||
| #ifdef MESA_BIG_ENDIAN | ||||
| 						R200_VC_32BIT_SWAP; | ||||
| #else | ||||
| 						R200_VC_NO_SWAP; | ||||
| #endif | ||||
|    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] = 0x100010; | ||||
|    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_0] = | ||||
|       (0x0 << R200_VERTEX_POSITION_ADDR__SHIFT); | ||||
|    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_1] = | ||||
|       (0x02 << R200_VTX_COLOR_0_ADDR__SHIFT) | | ||||
|       (0x03 << R200_VTX_COLOR_1_ADDR__SHIFT); | ||||
|    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_2] = | ||||
|       (0x06 << R200_VTX_TEX_0_ADDR__SHIFT) | | ||||
|       (0x07 << R200_VTX_TEX_1_ADDR__SHIFT) | | ||||
|       (0x08 << R200_VTX_TEX_2_ADDR__SHIFT) | | ||||
|       (0x09 << R200_VTX_TEX_3_ADDR__SHIFT); | ||||
|    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_3] = | ||||
|       (0x0A << R200_VTX_TEX_4_ADDR__SHIFT) | | ||||
|       (0x0B << R200_VTX_TEX_5_ADDR__SHIFT); | ||||
|    | ||||
|  | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = 0x00000000; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = 0x00000000; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = 0x00000000; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; | ||||
|  | ||||
|    for (i = 0; i < 2; i++) { /* 2 texture units for now */ | ||||
|       rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] = R200_BORDER_MODE_OGL; | ||||
|       rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT] =  | ||||
|          ((i << R200_TXFORMAT_ST_ROUTE_SHIFT) |  /* <-- note i */ | ||||
|           (2 << R200_TXFORMAT_WIDTH_SHIFT) | | ||||
|           (2 << R200_TXFORMAT_HEIGHT_SHIFT)); | ||||
|       rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = 0; | ||||
|       rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; | ||||
|       rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT_X] = | ||||
|          (/* R200_TEXCOORD_PROJ | */ | ||||
|           0x100000);	/* Small default bias */ | ||||
|  | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0; | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F1] = 0; | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F2] = 0; | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F3] = 0; | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F4] = 0; | ||||
|       rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F5] = 0; | ||||
|    } | ||||
|  | ||||
|    rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND] =   | ||||
|       (R200_TXC_ARG_A_ZERO | | ||||
|        R200_TXC_ARG_B_ZERO | | ||||
|        R200_TXC_ARG_C_DIFFUSE_COLOR | | ||||
|        R200_TXC_OP_MADD); | ||||
|  | ||||
|    rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND2] =   | ||||
|       ((0 << R200_TXC_TFACTOR_SEL_SHIFT) |  | ||||
|        R200_TXC_SCALE_1X | | ||||
|        R200_TXC_CLAMP_0_1 | | ||||
|        R200_TXC_OUTPUT_REG_R0); | ||||
|  | ||||
|    rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND] =   | ||||
|       (R200_TXA_ARG_A_ZERO | | ||||
|        R200_TXA_ARG_B_ZERO | | ||||
|        R200_TXA_ARG_C_DIFFUSE_ALPHA | | ||||
|        R200_TXA_OP_MADD); | ||||
|  | ||||
|    rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND2] =   | ||||
|       ((0 << R200_TXA_TFACTOR_SEL_SHIFT) |  | ||||
|        R200_TXA_SCALE_1X | | ||||
|        R200_TXA_CLAMP_0_1 | | ||||
|        R200_TXA_OUTPUT_REG_R0); | ||||
|  | ||||
|    rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND] =   | ||||
|       (R200_TXC_ARG_A_ZERO | | ||||
|        R200_TXC_ARG_B_ZERO | | ||||
|        R200_TXC_ARG_C_DIFFUSE_COLOR | | ||||
|        R200_TXC_OP_MADD); | ||||
|  | ||||
|    rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND2] =   | ||||
|       ((0 << R200_TXC_TFACTOR_SEL_SHIFT) |  | ||||
|        R200_TXC_SCALE_1X | | ||||
|        R200_TXC_CLAMP_0_1 | | ||||
|        R200_TXC_OUTPUT_REG_R0); | ||||
|  | ||||
|    rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND] =   | ||||
|       (R200_TXA_ARG_A_ZERO | | ||||
|        R200_TXA_ARG_B_ZERO | | ||||
|        R200_TXA_ARG_C_DIFFUSE_ALPHA | | ||||
|        R200_TXA_OP_MADD); | ||||
|  | ||||
|    rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND2] =   | ||||
|       ((0 << R200_TXA_TFACTOR_SEL_SHIFT) |  | ||||
|        R200_TXA_SCALE_1X | | ||||
|        R200_TXA_CLAMP_0_1 | | ||||
|        R200_TXA_OUTPUT_REG_R0); | ||||
|  | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_0] = 0; | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_1] = 0; | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_2] = 0; | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_3] = 0; | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_4] = 0; | ||||
|    rmesa->hw.tf.cmd[TF_TFACTOR_5] = 0; | ||||
|  | ||||
|    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] =  | ||||
|       (R200_VAP_TCL_ENABLE |  | ||||
|        (0x9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT)); | ||||
|  | ||||
|    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] =  | ||||
|       (R200_VPORT_X_SCALE_ENA | | ||||
|        R200_VPORT_Y_SCALE_ENA | | ||||
|        R200_VPORT_Z_SCALE_ENA | | ||||
|        R200_VPORT_X_OFFSET_ENA | | ||||
|        R200_VPORT_Y_OFFSET_ENA | | ||||
|        R200_VPORT_Z_OFFSET_ENA | | ||||
| /* FIXME: Turn on for tex rect only */ | ||||
|        R200_VTX_ST_DENORMALIZED |   | ||||
|        R200_VTX_W0_FMT);  | ||||
|  | ||||
|  | ||||
|    rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = 0; | ||||
|    rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = 0; | ||||
|    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] =  | ||||
|       ((R200_VTX_Z0 | R200_VTX_W0 | | ||||
|        (R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)));	 | ||||
|    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] = 0; | ||||
|    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = (R200_OUTPUT_XYZW); | ||||
|    rmesa->hw.vtx.cmd[VTX_STATE_CNTL] = R200_VSC_UPDATE_USER_COLOR_0_ENABLE; | ||||
| 						    | ||||
|  | ||||
|    /* Matrix selection */ | ||||
|    rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_0] =  | ||||
|       (R200_MTX_MV << R200_MODELVIEW_0_SHIFT); | ||||
|     | ||||
|    rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_1] =  | ||||
|        (R200_MTX_IMV << R200_IT_MODELVIEW_0_SHIFT); | ||||
|  | ||||
|    rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_2] =  | ||||
|       (R200_MTX_MVP << R200_MODELPROJECT_0_SHIFT); | ||||
|  | ||||
|    rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_3] =  | ||||
|       ((R200_MTX_TEX0 << R200_TEXMAT_0_SHIFT) | | ||||
|        (R200_MTX_TEX1 << R200_TEXMAT_1_SHIFT) | | ||||
|        (R200_MTX_TEX2 << R200_TEXMAT_2_SHIFT) | | ||||
|        (R200_MTX_TEX3 << R200_TEXMAT_3_SHIFT)); | ||||
|  | ||||
|    rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_4] =  | ||||
|       ((R200_MTX_TEX4 << R200_TEXMAT_4_SHIFT) | | ||||
|        (R200_MTX_TEX5 << R200_TEXMAT_5_SHIFT)); | ||||
|  | ||||
|  | ||||
|    /* General TCL state */ | ||||
|    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] =  | ||||
|       (R200_SPECULAR_LIGHTS | | ||||
|        R200_DIFFUSE_SPECULAR_COMBINE | | ||||
|        R200_LOCAL_LIGHT_VEC_GL); | ||||
|  | ||||
|    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] =  | ||||
|       ((R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_AMBIENT_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_SPECULAR_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_EMISSIVE_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_AMBIENT_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_DIFFUSE_SOURCE_SHIFT) | | ||||
|        (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_SPECULAR_SOURCE_SHIFT));  | ||||
|  | ||||
|    rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_0] = 0; /* filled in via callbacks */ | ||||
|    rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_1] = 0; | ||||
|    rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_2] = 0; | ||||
|    rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_3] = 0; | ||||
|     | ||||
|    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] =  | ||||
|       (R200_UCP_IN_CLIP_SPACE | | ||||
|        R200_CULL_FRONT_IS_CCW); | ||||
|  | ||||
|    /* Texgen/Texmat state */ | ||||
|    rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x0; /* masks??? */ | ||||
|    rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_3] =  | ||||
|       ((0 << R200_TEXGEN_0_INPUT_TEX_SHIFT) | | ||||
|        (1 << R200_TEXGEN_1_INPUT_TEX_SHIFT) | | ||||
|        (2 << R200_TEXGEN_2_INPUT_TEX_SHIFT) | | ||||
|        (3 << R200_TEXGEN_3_INPUT_TEX_SHIFT) | | ||||
|        (4 << R200_TEXGEN_4_INPUT_TEX_SHIFT) | | ||||
|        (5 << R200_TEXGEN_5_INPUT_TEX_SHIFT));  | ||||
|    rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = 0;  | ||||
|    rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] =   | ||||
|       ((0 << R200_TEXGEN_0_INPUT_SHIFT) | | ||||
|        (1 << R200_TEXGEN_1_INPUT_SHIFT) | | ||||
|        (2 << R200_TEXGEN_2_INPUT_SHIFT) | | ||||
|        (3 << R200_TEXGEN_3_INPUT_SHIFT) | | ||||
|        (4 << R200_TEXGEN_4_INPUT_SHIFT) | | ||||
|        (5 << R200_TEXGEN_5_INPUT_SHIFT));  | ||||
|    rmesa->hw.tcg.cmd[TCG_TEX_CYL_WRAP_CTL] = 0; | ||||
|  | ||||
|    rmesa->TexGenInputs = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]; | ||||
|  | ||||
|  | ||||
|    for (i = 0 ; i < 8; i++) { | ||||
|       struct gl_light *l = &ctx->Light.Light[i]; | ||||
|       GLenum p = GL_LIGHT0 + i; | ||||
|       *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; | ||||
|  | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, | ||||
| 			   &l->ConstantAttenuation ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION,  | ||||
| 			   &l->LinearAttenuation ); | ||||
|       ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION,  | ||||
| 		     &l->QuadraticAttenuation ); | ||||
|    } | ||||
|  | ||||
|    ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT,  | ||||
| 			     ctx->Light.Model.Ambient ); | ||||
|  | ||||
|    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); | ||||
|  | ||||
|    for (i = 0 ; i < 6; i++) { | ||||
|       ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL ); | ||||
|    } | ||||
|  | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); | ||||
|    ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); | ||||
|     | ||||
|    rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE; | ||||
|    rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE; | ||||
|    rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE; | ||||
|    rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE; | ||||
|  | ||||
|    rmesa->hw.eye.cmd[EYE_X] = 0; | ||||
|    rmesa->hw.eye.cmd[EYE_Y] = 0; | ||||
|    rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; | ||||
|    rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; | ||||
|  | ||||
|    r200LightingSpaceChange( ctx ); | ||||
|     | ||||
|    rmesa->lost_context = 1; | ||||
| } | ||||
							
								
								
									
										1286
									
								
								src/mesa/drivers/dri/r200/r200_swtcl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1286
									
								
								src/mesa/drivers/dri/r200/r200_swtcl.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										80
									
								
								src/mesa/drivers/dri/r200/r200_swtcl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/mesa/drivers/dri/r200/r200_swtcl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_SWTCL_H__ | ||||
| #define __R200_SWTCL_H__ | ||||
|  | ||||
| #include "mtypes.h" | ||||
| #include "swrast/swrast.h" | ||||
| #include "r200_context.h" | ||||
|  | ||||
| extern void r200InitSwtcl( GLcontext *ctx ); | ||||
| extern void r200DestroySwtcl( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200FlushVertices( GLcontext *ctx, GLuint flags ); | ||||
| extern void r200ChooseRenderState( GLcontext *ctx ); | ||||
| extern void r200ChooseVertexState( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200CheckTexSizes( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count, | ||||
| 				 GLuint newinputs ); | ||||
|  | ||||
| extern void r200PrintSetupFlags(char *msg, GLuint flags ); | ||||
|  | ||||
|  | ||||
| extern void r200_emit_contiguous_verts( GLcontext *ctx, | ||||
| 					  GLuint start, | ||||
| 					  GLuint count ); | ||||
|  | ||||
| extern void r200_emit_indexed_verts( GLcontext *ctx, | ||||
| 				       GLuint start, | ||||
| 				       GLuint count ); | ||||
|  | ||||
| extern void r200_translate_vertex( GLcontext *ctx,  | ||||
| 				     const r200Vertex *src,  | ||||
| 				     SWvertex *dst ); | ||||
|  | ||||
| extern void r200_print_vertex( GLcontext *ctx, const r200Vertex *v ); | ||||
|  | ||||
| extern void r200_import_float_colors( GLcontext *ctx ); | ||||
| extern void r200_import_float_spec_colors( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
| 			      GLsizei width, GLsizei height, | ||||
| 			      const struct gl_pixelstore_attrib *unpack, | ||||
| 			      const GLubyte *bitmap ); | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										555
									
								
								src/mesa/drivers/dri/r200/r200_tcl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										555
									
								
								src/mesa/drivers/dri/r200/r200_tcl.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,555 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h" | ||||
| #include "mtypes.h" | ||||
| #include "enums.h" | ||||
| #include "colormac.h" | ||||
| #include "light.h" | ||||
|  | ||||
| #include "array_cache/acache.h" | ||||
| #include "tnl/tnl.h" | ||||
| #include "tnl/t_pipeline.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_tex.h" | ||||
| #include "r200_tcl.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_maos.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| #define HAVE_POINTS      1 | ||||
| #define HAVE_LINES       1 | ||||
| #define HAVE_LINE_LOOP   0 | ||||
| #define HAVE_LINE_STRIPS 1 | ||||
| #define HAVE_TRIANGLES   1 | ||||
| #define HAVE_TRI_STRIPS  1 | ||||
| #define HAVE_TRI_STRIP_1 0 | ||||
| #define HAVE_TRI_FANS    1 | ||||
| #define HAVE_QUADS       0	/* hw quad verts in wrong order??? */ | ||||
| #define HAVE_QUAD_STRIPS 1 | ||||
| #define HAVE_POLYGONS    1 | ||||
| #define HAVE_ELTS        1 | ||||
|  | ||||
|  | ||||
| #define HW_POINTS           R200_VF_PRIM_POINTS | ||||
| #define HW_LINES            R200_VF_PRIM_LINES | ||||
| #define HW_LINE_LOOP        0 | ||||
| #define HW_LINE_STRIP       R200_VF_PRIM_LINE_STRIP | ||||
| #define HW_TRIANGLES        R200_VF_PRIM_TRIANGLES | ||||
| #define HW_TRIANGLE_STRIP_0 R200_VF_PRIM_TRIANGLE_STRIP | ||||
| #define HW_TRIANGLE_STRIP_1 0 | ||||
| #define HW_TRIANGLE_FAN     R200_VF_PRIM_TRIANGLE_FAN | ||||
| #define HW_QUADS            R200_VF_PRIM_QUADS | ||||
| #define HW_QUAD_STRIP       R200_VF_PRIM_QUAD_STRIP | ||||
| #define HW_POLYGON          R200_VF_PRIM_POLYGON | ||||
|  | ||||
|  | ||||
| static GLboolean discrete_prim[0x10] = { | ||||
|    0,				/* 0 none */ | ||||
|    1,				/* 1 points */ | ||||
|    1,				/* 2 lines */ | ||||
|    0,				/* 3 line_strip */ | ||||
|    1,				/* 4 tri_list */ | ||||
|    0,				/* 5 tri_fan */ | ||||
|    0,				/* 6 tri_strip */ | ||||
|    0,				/* 7 tri_w_flags */ | ||||
|    1,				/* 8 rect list (unused) */ | ||||
|    1,				/* 9 3vert point */ | ||||
|    1,				/* a 3vert line */ | ||||
|    0,				/* b point sprite */ | ||||
|    0,				/* c line loop */ | ||||
|    1,				/* d quads */ | ||||
|    0,				/* e quad strip */ | ||||
|    0,				/* f polygon */ | ||||
| }; | ||||
|     | ||||
|  | ||||
| #define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx) | ||||
| #define ELTS_VARS  GLushort *dest | ||||
|  | ||||
| #define ELT_INIT(prim, hw_prim) \ | ||||
|    r200TclPrimitive( ctx, prim, hw_prim | R200_VF_PRIM_WALK_IND ) | ||||
|  | ||||
| #define GET_ELTS() rmesa->tcl.Elts | ||||
|  | ||||
|  | ||||
| #define NEW_PRIMITIVE()  R200_NEWPRIM( rmesa ) | ||||
| #define NEW_BUFFER()  r200RefillCurrentDmaRegion( rmesa ) | ||||
|  | ||||
| /* Don't really know how many elts will fit in what's left of cmdbuf, | ||||
|  * as there is state to emit, etc: | ||||
|  */ | ||||
|  | ||||
| #if 0 | ||||
| #define GET_CURRENT_VB_MAX_ELTS() \ | ||||
|    ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)  | ||||
| #define GET_SUBSEQUENT_VB_MAX_ELTS() ((R200_CMD_BUF_SZ - 16) / 2)  | ||||
| #else | ||||
| /* Testing on isosurf shows a maximum around here.  Don't know if it's | ||||
|  * the card or driver or kernel module that is causing the behaviour. | ||||
|  */ | ||||
| #define GET_CURRENT_VB_MAX_ELTS() 300 | ||||
| #define GET_SUBSEQUENT_VB_MAX_ELTS() 300 | ||||
| #endif | ||||
|  | ||||
| #define RESET_STIPPLE() do {			\ | ||||
|    R200_STATECHANGE( rmesa, lin );		\ | ||||
|    r200EmitState( rmesa );			\ | ||||
| } while (0) | ||||
|  | ||||
| #define AUTO_STIPPLE( mode )  do {		\ | ||||
|    R200_STATECHANGE( rmesa, lin );		\ | ||||
|    if (mode)					\ | ||||
|       rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |=	\ | ||||
| 	 R200_LINE_PATTERN_AUTO_RESET;	\ | ||||
|    else						\ | ||||
|       rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &=	\ | ||||
| 	 ~R200_LINE_PATTERN_AUTO_RESET;	\ | ||||
|    r200EmitState( rmesa );			\ | ||||
| } while (0) | ||||
|  | ||||
|  | ||||
| /* How do you extend an existing primitive? | ||||
|  */ | ||||
| #define ALLOC_ELTS(nr)							\ | ||||
| do {									\ | ||||
|    if (rmesa->dma.flush == r200FlushElts &&				\ | ||||
|        rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) {		\ | ||||
| 									\ | ||||
|       dest = (GLushort *)(rmesa->store.cmd_buf + 			\ | ||||
| 			  rmesa->store.cmd_used);			\ | ||||
|       rmesa->store.cmd_used += nr*2;					\ | ||||
|    }									\ | ||||
|    else {								\ | ||||
|       if (rmesa->dma.flush)						\ | ||||
| 	 rmesa->dma.flush( rmesa );					\ | ||||
| 									\ | ||||
|       r200EmitAOS( rmesa,						\ | ||||
| 	  	     rmesa->tcl.aos_components,				\ | ||||
| 		     rmesa->tcl.nr_aos_components,			\ | ||||
| 		     0 );						\ | ||||
| 									\ | ||||
|       dest = r200AllocEltsOpenEnded( rmesa,				\ | ||||
| 				       rmesa->tcl.hw_primitive,		\ | ||||
| 				       nr );				\ | ||||
|    }									\ | ||||
| } while (0)  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* TODO: Try to extend existing primitive if both are identical, | ||||
|  * discrete and there are no intervening state changes.  (Somewhat | ||||
|  * duplicates changes to DrawArrays code) | ||||
|  */ | ||||
| static void EMIT_PRIM( GLcontext *ctx,  | ||||
| 		       GLenum prim,  | ||||
| 		       GLuint hwprim,  | ||||
| 		       GLuint start,  | ||||
| 		       GLuint count)	 | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT( ctx ); | ||||
|    r200TclPrimitive( ctx, prim, hwprim ); | ||||
|     | ||||
|    r200EmitAOS( rmesa, | ||||
| 		  rmesa->tcl.aos_components, | ||||
| 		  rmesa->tcl.nr_aos_components, | ||||
| 		  start ); | ||||
|     | ||||
|    /* Why couldn't this packet have taken an offset param? | ||||
|     */ | ||||
|    r200EmitVbufPrim( rmesa, | ||||
| 		     rmesa->tcl.hw_primitive, | ||||
| 		     count - start ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Try & join small primitives | ||||
|  */ | ||||
| #if 0 | ||||
| #define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0 | ||||
| #else | ||||
| #define PREFER_DISCRETE_ELT_PRIM( NR, PRIM )			\ | ||||
|   ((NR) < 20 ||							\ | ||||
|    ((NR) < 40 &&						\ | ||||
|     rmesa->tcl.hw_primitive == (PRIM|				\ | ||||
| 			    R200_VF_TCL_OUTPUT_VTX_ENABLE|	\ | ||||
| 			        R200_VF_PRIM_WALK_IND))) | ||||
| #endif | ||||
|  | ||||
| #ifdef MESA_BIG_ENDIAN | ||||
| /* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */ | ||||
| #define EMIT_ELT(offset, x) do {                                \ | ||||
|         int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 );     \ | ||||
|         GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 );    \ | ||||
|         (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0) | ||||
| #else | ||||
| #define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x) | ||||
| #endif | ||||
| #define EMIT_TWO_ELTS(offset, x, y)  *(GLuint *)(dest+offset) = ((y)<<16)|(x); | ||||
| #define INCR_ELTS( nr ) dest += nr | ||||
| #define RELEASE_ELT_VERTS() \ | ||||
|    r200ReleaseArrays( ctx, ~0 ) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define TAG(x) tcl_##x | ||||
| #include "tnl_dd/t_dd_dmatmp2.h" | ||||
|  | ||||
| /**********************************************************************/ | ||||
| /*                          External entrypoints                     */ | ||||
| /**********************************************************************/ | ||||
|  | ||||
| void r200EmitPrimitive( GLcontext *ctx,  | ||||
| 			  GLuint first, | ||||
| 			  GLuint last, | ||||
| 			  GLuint flags ) | ||||
| { | ||||
|    tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); | ||||
| } | ||||
|  | ||||
| void r200EmitEltPrimitive( GLcontext *ctx,  | ||||
| 			     GLuint first, | ||||
| 			     GLuint last, | ||||
| 			     GLuint flags ) | ||||
| { | ||||
|    tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); | ||||
| } | ||||
|  | ||||
| void r200TclPrimitive( GLcontext *ctx,  | ||||
| 			 GLenum prim, | ||||
| 			 int hw_prim ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE; | ||||
|  | ||||
|    if (newprim != rmesa->tcl.hw_primitive || | ||||
|        !discrete_prim[hw_prim&0xf]) { | ||||
|       R200_NEWPRIM( rmesa ); | ||||
|       rmesa->tcl.hw_primitive = newprim; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /**********************************************************************/ | ||||
| /*                          Render pipeline stage                     */ | ||||
| /**********************************************************************/ | ||||
|  | ||||
|  | ||||
| /* TCL render. | ||||
|  */ | ||||
| static GLboolean r200_run_tcl_render( GLcontext *ctx, | ||||
| 					struct gl_pipeline_stage *stage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    TNLcontext *tnl = TNL_CONTEXT(ctx); | ||||
|    struct vertex_buffer *VB = &tnl->vb; | ||||
|    GLuint i,flags = 0,length; | ||||
|  | ||||
|    /* TODO: separate this from the swtnl pipeline  | ||||
|     */ | ||||
|    if (rmesa->TclFallback) | ||||
|       return GL_TRUE;	/* fallback to software t&l */ | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_PRIMS) | ||||
|       fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    if (VB->Count == 0) | ||||
|       return GL_FALSE; | ||||
|  | ||||
|    r200ReleaseArrays( ctx, stage->changed_inputs ); | ||||
|    r200EmitArrays( ctx, stage->inputs ); | ||||
|  | ||||
|    rmesa->tcl.Elts = VB->Elts; | ||||
|  | ||||
|    for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) | ||||
|    { | ||||
|       flags = VB->Primitive[i]; | ||||
|       length = VB->PrimitiveLength[i]; | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_PRIMS) | ||||
| 	 fprintf(stderr, "%s: prim %s %d..%d\n",  | ||||
| 		 __FUNCTION__, | ||||
| 		 _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK),  | ||||
| 		 i, i+length); | ||||
|  | ||||
|       if (!length) | ||||
| 	 continue; | ||||
|  | ||||
|       if (rmesa->tcl.Elts) | ||||
| 	 r200EmitEltPrimitive( ctx, i, i+length, flags ); | ||||
|       else | ||||
| 	 r200EmitPrimitive( ctx, i, i+length, flags ); | ||||
|    } | ||||
|  | ||||
|    return GL_FALSE;		/* finished the pipe */ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void r200_check_tcl_render( GLcontext *ctx, | ||||
| 				     struct gl_pipeline_stage *stage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint inputs = VERT_BIT_POS; | ||||
|  | ||||
|    /* Validate state: | ||||
|     */ | ||||
|    if (rmesa->NewGLState) | ||||
|       r200ValidateState( ctx ); | ||||
|  | ||||
|    if (0) | ||||
|       fprintf(stderr, "%s: RE %d TGE %d NN %d\n", | ||||
| 	   __FUNCTION__, | ||||
| 	   ctx->Texture.Unit[0]._ReallyEnabled, | ||||
| 	   ctx->Texture.Unit[0].TexGenEnabled, | ||||
| 	   rmesa->TexGenNeedNormals[0]); | ||||
|  | ||||
|    if (ctx->RenderMode == GL_RENDER) { | ||||
|       /* Make all this event-driven: | ||||
|        */ | ||||
|       if (ctx->Light.Enabled) { | ||||
| 	 inputs |= VERT_BIT_NORMAL; | ||||
|  | ||||
| 	 if (ctx->Light.ColorMaterialEnabled) { | ||||
| 	    inputs |= VERT_BIT_COLOR0; | ||||
| 	 } | ||||
|       } | ||||
|       else { | ||||
| 	 inputs |= VERT_BIT_COLOR0; | ||||
| 	  | ||||
| 	 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { | ||||
| 	    inputs |= VERT_BIT_COLOR1; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       if (ctx->Texture.Unit[0]._ReallyEnabled) { | ||||
| 	 if (ctx->Texture.Unit[0].TexGenEnabled) { | ||||
| 	    if (rmesa->TexGenNeedNormals[0]) { | ||||
| 	       inputs |= VERT_BIT_NORMAL; | ||||
| 	    } | ||||
| 	 } else { | ||||
| 	    inputs |= VERT_BIT_TEX0; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       if (ctx->Texture.Unit[1]._ReallyEnabled) { | ||||
| 	 if (ctx->Texture.Unit[1].TexGenEnabled) { | ||||
| 	    if (rmesa->TexGenNeedNormals[1]) { | ||||
| 	       inputs |= VERT_BIT_NORMAL; | ||||
| 	    } | ||||
| 	 } else { | ||||
| 	    inputs |= VERT_BIT_TEX1; | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       stage->inputs = inputs; | ||||
|       stage->active = 1; | ||||
|    } | ||||
|    else | ||||
|       stage->active = 0; | ||||
| } | ||||
|  | ||||
| static void r200_init_tcl_render( GLcontext *ctx, | ||||
| 				    struct gl_pipeline_stage *stage ) | ||||
| { | ||||
|    stage->check = r200_check_tcl_render; | ||||
|    stage->check( ctx, stage ); | ||||
| } | ||||
|  | ||||
| static void dtr( struct gl_pipeline_stage *stage ) | ||||
| { | ||||
|    (void)stage; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Initial state for tcl stage.   | ||||
|  */ | ||||
| const struct gl_pipeline_stage _r200_tcl_stage = | ||||
| { | ||||
|    "r200 render", | ||||
|    (_DD_NEW_SEPARATE_SPECULAR | | ||||
|     _NEW_LIGHT| | ||||
|     _NEW_TEXTURE| | ||||
|     _NEW_FOG| | ||||
|     _NEW_RENDERMODE),		/* re-check (new inputs) */ | ||||
|    0,				/* re-run (always runs) */ | ||||
|    GL_TRUE,			/* active */ | ||||
|    0, 0,			/* inputs (set in check_render), outputs */ | ||||
|    0, 0,			/* changed_inputs, private */ | ||||
|    dtr,				/* destructor */ | ||||
|    r200_init_tcl_render,	/* check - initially set to alloc data */ | ||||
|    r200_run_tcl_render	/* run */ | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /**********************************************************************/ | ||||
| /*                 Validate state at pipeline start                   */ | ||||
| /**********************************************************************/ | ||||
|  | ||||
|  | ||||
| /*----------------------------------------------------------------------- | ||||
|  * Manage TCL fallbacks | ||||
|  */ | ||||
|  | ||||
|  | ||||
| static void transition_to_swtnl( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    TNLcontext *tnl = TNL_CONTEXT(ctx); | ||||
|  | ||||
|    R200_NEWPRIM( rmesa ); | ||||
|    rmesa->swtcl.vertex_format = 0; | ||||
|  | ||||
|    r200ChooseVertexState( ctx ); | ||||
|    r200ChooseRenderState( ctx ); | ||||
|  | ||||
|    _mesa_validate_all_lighting_tables( ctx );  | ||||
|  | ||||
|    tnl->Driver.NotifyMaterialChange =  | ||||
|       _mesa_validate_all_lighting_tables; | ||||
|  | ||||
|    r200ReleaseArrays( ctx, ~0 ); | ||||
|  | ||||
|    /* Still using the D3D based hardware-rasterizer from the radeon; | ||||
|     * need to put the card into D3D mode to make it work: | ||||
|     */ | ||||
|    R200_STATECHANGE( rmesa, vap ); | ||||
|    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE; | ||||
|    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_D3D_TEX_DEFAULT; | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, vte ); | ||||
|    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~R200_VTX_W0_FMT; | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, set ); | ||||
|    rmesa->hw.set.cmd[SET_RE_CNTL] |= (R200_VTX_STQ0_D3D | | ||||
| 				      R200_VTX_STQ1_D3D); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void transition_to_hwtnl( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    TNLcontext *tnl = TNL_CONTEXT(ctx); | ||||
|  | ||||
|    _tnl_need_projected_coords( ctx, GL_FALSE ); | ||||
|  | ||||
|    r200UpdateMaterial( ctx ); | ||||
|  | ||||
|    tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; | ||||
|  | ||||
|    if ( rmesa->dma.flush )			 | ||||
|       rmesa->dma.flush( rmesa );	 | ||||
|  | ||||
|    rmesa->dma.flush = 0; | ||||
|    rmesa->swtcl.vertex_format = 0; | ||||
|     | ||||
|    if (rmesa->swtcl.indexed_verts.buf)  | ||||
|       r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,  | ||||
| 			      __FUNCTION__ ); | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, vap ); | ||||
|    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; | ||||
|    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_FORCE_W_TO_ONE | | ||||
| 					   R200_VAP_D3D_TEX_DEFAULT); | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, vte ); | ||||
|    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); | ||||
|    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; | ||||
|  | ||||
|    R200_STATECHANGE( rmesa, set ); | ||||
|    rmesa->hw.set.cmd[SET_RE_CNTL] &= ~(R200_VTX_STQ0_D3D | | ||||
| 				       R200_VTX_STQ1_D3D); | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_FALLBACKS)  | ||||
|       fprintf(stderr, "R200 end tcl fallback\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| static char *fallbackStrings[] = { | ||||
|    "Rasterization fallback", | ||||
|    "Unfilled triangles", | ||||
|    "Twosided lighting, differing materials", | ||||
|    "Materials in VB (maybe between begin/end)", | ||||
|    "Texgen unit 0", | ||||
|    "Texgen unit 1", | ||||
|    "Texgen unit 2", | ||||
|    "User disable" | ||||
| }; | ||||
|  | ||||
|  | ||||
| static char *getFallbackString(GLuint bit) | ||||
| { | ||||
|    int i = 0; | ||||
|    while (bit > 1) { | ||||
|       i++; | ||||
|       bit >>= 1; | ||||
|    } | ||||
|    return fallbackStrings[i]; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint oldfallback = rmesa->TclFallback; | ||||
|  | ||||
|    if (mode) { | ||||
|       rmesa->TclFallback |= bit; | ||||
|       if (oldfallback == 0) { | ||||
| 	 if (R200_DEBUG & DEBUG_FALLBACKS)  | ||||
| 	    fprintf(stderr, "R200 begin tcl fallback %s\n", | ||||
| 		    getFallbackString( bit )); | ||||
| 	 transition_to_swtnl( ctx ); | ||||
|       } | ||||
|    } | ||||
|    else { | ||||
|       rmesa->TclFallback &= ~bit; | ||||
|       if (oldfallback == bit) { | ||||
| 	 if (R200_DEBUG & DEBUG_FALLBACKS)  | ||||
| 	    fprintf(stderr, "R200 end tcl fallback %s\n", | ||||
| 		    getFallbackString( bit )); | ||||
| 	 transition_to_hwtnl( ctx ); | ||||
|       } | ||||
|    } | ||||
| } | ||||
							
								
								
									
										66
									
								
								src/mesa/drivers/dri/r200/r200_tcl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/mesa/drivers/dri/r200/r200_tcl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_TCL_H__ | ||||
| #define __R200_TCL_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "r200_context.h" | ||||
|  | ||||
| extern void r200TclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim ); | ||||
| extern void r200EmitEltPrimitive( GLcontext *ctx, GLuint first, GLuint last, | ||||
| 				    GLuint flags ); | ||||
| extern void r200EmitPrimitive( GLcontext *ctx, GLuint first, GLuint last, | ||||
| 				 GLuint flags ); | ||||
|  | ||||
| extern void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); | ||||
| 					       | ||||
| #define R200_TCL_FALLBACK_RASTER            0x1 /* rasterization */ | ||||
| #define R200_TCL_FALLBACK_UNFILLED          0x2 /* unfilled tris */ | ||||
| #define R200_TCL_FALLBACK_LIGHT_TWOSIDE     0x4 /* twoside tris */ | ||||
| #define R200_TCL_FALLBACK_MATERIAL          0x8 /* material in vb */ | ||||
| #define R200_TCL_FALLBACK_TEXGEN_0          0x10 /* texgen, unit 0 */ | ||||
| #define R200_TCL_FALLBACK_TEXGEN_1          0x20 /* texgen, unit 1 */ | ||||
| #define R200_TCL_FALLBACK_TEXGEN_2          0x40 /* texgen, unit 2 */ | ||||
| #define R200_TCL_FALLBACK_TCL_DISABLE       0x80 /* user disable */ | ||||
| #define R200_TCL_FALLBACK_BITMAP            0x100 /* draw bitmap with points */ | ||||
|  | ||||
| #define R200_MAX_TCL_VERTSIZE (4*4) /* using maos now... */ | ||||
|  | ||||
| #define TCL_FALLBACK( ctx, bit, mode )	r200TclFallback( ctx, bit, mode ) | ||||
|  | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										988
									
								
								src/mesa/drivers/dri/r200/r200_tex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										988
									
								
								src/mesa/drivers/dri/r200/r200_tex.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,988 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "colormac.h" | ||||
| #include "context.h" | ||||
| #include "enums.h" | ||||
| #include "image.h" | ||||
| #include "mmath.h" | ||||
| #include "simple_list.h" | ||||
| #include "texformat.h" | ||||
| #include "texstore.h" | ||||
| #include "texutil.h" | ||||
|  | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_tex.h" | ||||
|  | ||||
|  | ||||
| /* ============================================================= | ||||
|  * Utility functions: | ||||
|  */ | ||||
|  | ||||
| static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap ) | ||||
| { | ||||
|    t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK); | ||||
|  | ||||
|    switch ( swrap ) { | ||||
|    case GL_REPEAT: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_WRAP; | ||||
|       break; | ||||
|    case GL_CLAMP: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_EDGE: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_BORDER: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRRORED_REPEAT_ARB: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_MIRROR; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_ATI: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_TO_EDGE_ATI: | ||||
|       t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_LAST; | ||||
|       break; | ||||
|    default: | ||||
|       _mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap"); | ||||
|    } | ||||
|  | ||||
|    switch ( twrap ) { | ||||
|    case GL_REPEAT: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_WRAP; | ||||
|       break; | ||||
|    case GL_CLAMP: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_EDGE: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_BORDER: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRRORED_REPEAT_ARB: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_MIRROR; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_ATI: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_TO_EDGE_ATI: | ||||
|       t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_LAST; | ||||
|       break; | ||||
|    default: | ||||
|       _mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap"); | ||||
|    } | ||||
|  | ||||
|    t->pp_txformat_x &= ~R200_CLAMP_Q_MASK; | ||||
|  | ||||
|    switch ( rwrap ) { | ||||
|    case GL_REPEAT: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_WRAP; | ||||
|       break; | ||||
|    case GL_CLAMP: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_EDGE: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST; | ||||
|       break; | ||||
|    case GL_CLAMP_TO_BORDER: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRRORED_REPEAT_ARB: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_MIRROR; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_ATI: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_BORDER; | ||||
|       break; | ||||
|    case GL_MIRROR_CLAMP_TO_EDGE_ATI: | ||||
|       t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST; | ||||
|       break; | ||||
|    default: | ||||
|       _mesa_problem(NULL, "bad R wrap mode in r200SetTexWrap"); | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max ) | ||||
| { | ||||
|    t->pp_txfilter &= ~R200_MAX_ANISO_MASK; | ||||
|  | ||||
|    if ( max == 1.0 ) { | ||||
|       t->pp_txfilter |= R200_MAX_ANISO_1_TO_1; | ||||
|    } else if ( max <= 2.0 ) { | ||||
|       t->pp_txfilter |= R200_MAX_ANISO_2_TO_1; | ||||
|    } else if ( max <= 4.0 ) { | ||||
|       t->pp_txfilter |= R200_MAX_ANISO_4_TO_1; | ||||
|    } else if ( max <= 8.0 ) { | ||||
|       t->pp_txfilter |= R200_MAX_ANISO_8_TO_1; | ||||
|    } else { | ||||
|       t->pp_txfilter |= R200_MAX_ANISO_16_TO_1; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf ) | ||||
| { | ||||
|    GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK); | ||||
|  | ||||
|    t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK); | ||||
|    t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK; | ||||
|  | ||||
|    if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) { | ||||
|       switch ( minf ) { | ||||
|       case GL_NEAREST: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST; | ||||
| 	 break; | ||||
|       case GL_LINEAR: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR; | ||||
| 	 break; | ||||
|       case GL_NEAREST_MIPMAP_NEAREST: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_NEAREST; | ||||
| 	 break; | ||||
|       case GL_NEAREST_MIPMAP_LINEAR: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_NEAREST; | ||||
| 	 break; | ||||
|       case GL_LINEAR_MIPMAP_NEAREST: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_LINEAR; | ||||
| 	 break; | ||||
|       case GL_LINEAR_MIPMAP_LINEAR: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_LINEAR; | ||||
| 	 break; | ||||
|       } | ||||
|    } else { | ||||
|       switch ( minf ) { | ||||
|       case GL_NEAREST: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST; | ||||
| 	 break; | ||||
|       case GL_LINEAR: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_LINEAR; | ||||
| 	 break; | ||||
|       case GL_NEAREST_MIPMAP_NEAREST: | ||||
|       case GL_LINEAR_MIPMAP_NEAREST: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST; | ||||
| 	 break; | ||||
|       case GL_NEAREST_MIPMAP_LINEAR: | ||||
|       case GL_LINEAR_MIPMAP_LINEAR: | ||||
| 	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR; | ||||
| 	 break; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* Note we don't have 3D mipmaps so only use the mag filter setting | ||||
|     * to set the 3D texture filter mode. | ||||
|     */ | ||||
|    switch ( magf ) { | ||||
|    case GL_NEAREST: | ||||
|       t->pp_txfilter |= R200_MAG_FILTER_NEAREST; | ||||
|       t->pp_txformat_x |= R200_VOLUME_FILTER_NEAREST; | ||||
|       break; | ||||
|    case GL_LINEAR: | ||||
|       t->pp_txfilter |= R200_MAG_FILTER_LINEAR; | ||||
|       t->pp_txformat_x |= R200_VOLUME_FILTER_LINEAR; | ||||
|       break; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200SetTexBorderColor( r200TexObjPtr t, GLubyte c[4] ) | ||||
| { | ||||
|    t->pp_border_color = r200PackColor( 4, c[0], c[1], c[2], c[3] ); | ||||
| } | ||||
|  | ||||
|  | ||||
| static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj ) | ||||
| { | ||||
|    r200TexObjPtr t; | ||||
|  | ||||
|    t = CALLOC_STRUCT( r200_tex_obj ); | ||||
|    if (!t) | ||||
|       return NULL; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_TEXTURE ) { | ||||
|       fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); | ||||
|    } | ||||
|  | ||||
|    t->tObj = texObj; | ||||
|    make_empty_list( t ); | ||||
|  | ||||
|    /* Initialize non-image-dependent parts of the state: | ||||
|     */ | ||||
|    r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR ); | ||||
|    r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); | ||||
|    r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); | ||||
|    r200SetTexBorderColor( t, texObj->_BorderChan ); | ||||
|    return t; | ||||
| } | ||||
|  | ||||
|  | ||||
| static const struct gl_texture_format * | ||||
| r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, | ||||
|                            GLenum format, GLenum type ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    const GLboolean do32bpt = ( rmesa->r200Screen->cpp == 4 ); | ||||
|  | ||||
|    switch ( internalFormat ) { | ||||
|    case 4: | ||||
|    case GL_RGBA: | ||||
|       if ( format == GL_BGRA ) { | ||||
| 	 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { | ||||
| 	    return &_mesa_texformat_argb8888; | ||||
| 	 } | ||||
|          else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { | ||||
|             return &_mesa_texformat_argb4444; | ||||
| 	 } | ||||
|          else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { | ||||
| 	    return &_mesa_texformat_argb1555; | ||||
| 	 } | ||||
|       } | ||||
|       return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444; | ||||
|  | ||||
|    case 3: | ||||
|    case GL_RGB: | ||||
|       if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { | ||||
| 	 return &_mesa_texformat_rgb565; | ||||
|       } | ||||
|       return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565; | ||||
|  | ||||
|    case GL_RGBA8: | ||||
|    case GL_RGB10_A2: | ||||
|    case GL_RGBA12: | ||||
|    case GL_RGBA16: | ||||
|       return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444; | ||||
|  | ||||
|    case GL_RGBA4: | ||||
|    case GL_RGBA2: | ||||
|       return &_mesa_texformat_argb4444; | ||||
|  | ||||
|    case GL_RGB5_A1: | ||||
|       return &_mesa_texformat_argb1555; | ||||
|  | ||||
|    case GL_RGB8: | ||||
|    case GL_RGB10: | ||||
|    case GL_RGB12: | ||||
|    case GL_RGB16: | ||||
|       return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565; | ||||
|  | ||||
|    case GL_RGB5: | ||||
|    case GL_RGB4: | ||||
|    case GL_R3_G3_B2: | ||||
|       return &_mesa_texformat_rgb565; | ||||
|  | ||||
|    case GL_ALPHA: | ||||
|    case GL_ALPHA4: | ||||
|    case GL_ALPHA8: | ||||
|    case GL_ALPHA12: | ||||
|    case GL_ALPHA16: | ||||
|       return &_mesa_texformat_al88; | ||||
|  | ||||
|    case 1: | ||||
|    case GL_LUMINANCE: | ||||
|    case GL_LUMINANCE4: | ||||
|    case GL_LUMINANCE8: | ||||
|    case GL_LUMINANCE12: | ||||
|    case GL_LUMINANCE16: | ||||
|       return &_mesa_texformat_al88; | ||||
|  | ||||
|    case 2: | ||||
|    case GL_LUMINANCE_ALPHA: | ||||
|    case GL_LUMINANCE4_ALPHA4: | ||||
|    case GL_LUMINANCE6_ALPHA2: | ||||
|    case GL_LUMINANCE8_ALPHA8: | ||||
|    case GL_LUMINANCE12_ALPHA4: | ||||
|    case GL_LUMINANCE12_ALPHA12: | ||||
|    case GL_LUMINANCE16_ALPHA16: | ||||
|       return &_mesa_texformat_al88; | ||||
|  | ||||
|    case GL_INTENSITY: | ||||
|    case GL_INTENSITY4: | ||||
|    case GL_INTENSITY8: | ||||
|    case GL_INTENSITY12: | ||||
|    case GL_INTENSITY16: | ||||
|       /* At the moment, glean & conform both fail using the i8 internal | ||||
|        * format. | ||||
|        */ | ||||
|       return &_mesa_texformat_al88; | ||||
| /*       return &_mesa_texformat_i8; */ | ||||
|  | ||||
|    case GL_YCBCR_MESA: | ||||
|       if (type == GL_UNSIGNED_SHORT_8_8_APPLE || | ||||
| 	  type == GL_UNSIGNED_BYTE) | ||||
|          return &_mesa_texformat_ycbcr; | ||||
|       else | ||||
|          return &_mesa_texformat_ycbcr_rev; | ||||
|  | ||||
|    default: | ||||
|       _mesa_problem(ctx, "unexpected texture format in r200ChoosTexFormat"); | ||||
|       return NULL; | ||||
|    } | ||||
|  | ||||
|    return NULL; /* never get here */ | ||||
| } | ||||
|  | ||||
|  | ||||
| static GLboolean | ||||
| r200ValidateClientStorage( GLcontext *ctx, GLenum target, | ||||
| 			   GLint internalFormat, | ||||
| 			   GLint srcWidth, GLint srcHeight,  | ||||
|                            GLenum format, GLenum type,  const void *pixels, | ||||
| 			   const struct gl_pixelstore_attrib *packing, | ||||
| 			   struct gl_texture_object *texObj, | ||||
| 			   struct gl_texture_image *texImage) | ||||
|  | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    int texelBytes; | ||||
|  | ||||
|    if (0) | ||||
|       fprintf(stderr, "intformat %s format %s type %s\n", | ||||
| 	      _mesa_lookup_enum_by_nr( internalFormat ), | ||||
| 	      _mesa_lookup_enum_by_nr( format ), | ||||
| 	      _mesa_lookup_enum_by_nr( type )); | ||||
|  | ||||
|    if (!ctx->Unpack.ClientStorage) | ||||
|       return 0; | ||||
|  | ||||
|    if (ctx->_ImageTransferState || | ||||
|        texImage->IsCompressed || | ||||
|        texObj->GenerateMipmap) | ||||
|       return 0; | ||||
|  | ||||
|  | ||||
|    /* This list is incomplete, may be different on ppc??? | ||||
|     */ | ||||
|    switch ( internalFormat ) { | ||||
|    case GL_RGBA: | ||||
|       if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) { | ||||
| 	 texImage->TexFormat = &_mesa_texformat_argb8888; | ||||
| 	 texelBytes = 4; | ||||
|       } | ||||
|       else | ||||
| 	 return 0; | ||||
|       break; | ||||
|  | ||||
|    case GL_YCBCR_MESA: | ||||
|       if ( format == GL_YCBCR_MESA &&  | ||||
| 	   type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) { | ||||
| 	 texImage->TexFormat = &_mesa_texformat_ycbcr_rev; | ||||
| 	 texelBytes = 2; | ||||
|       } | ||||
|       else if ( format == GL_YCBCR_MESA &&  | ||||
| 		(type == GL_UNSIGNED_SHORT_8_8_APPLE ||  | ||||
| 		 type == GL_UNSIGNED_BYTE)) { | ||||
| 	 texImage->TexFormat = &_mesa_texformat_ycbcr; | ||||
| 	 texelBytes = 2; | ||||
|       } | ||||
|       else | ||||
| 	 return 0; | ||||
|       break; | ||||
|        | ||||
| 	  | ||||
|    default: | ||||
|       return 0; | ||||
|    } | ||||
|  | ||||
|    /* Could deal with these packing issues, but currently don't: | ||||
|     */ | ||||
|    if (packing->SkipPixels ||  | ||||
|        packing->SkipRows ||  | ||||
|        packing->SwapBytes || | ||||
|        packing->LsbFirst) { | ||||
|       return 0; | ||||
|    } | ||||
|  | ||||
|    {       | ||||
|       GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, | ||||
| 						  format, type); | ||||
|  | ||||
|        | ||||
|       if (0) | ||||
| 	 fprintf(stderr, "%s: srcRowStride %d/%x\n",  | ||||
| 		 __FUNCTION__, srcRowStride, srcRowStride); | ||||
|  | ||||
|       /* Could check this later in upload, pitch restrictions could be | ||||
|        * relaxed, but would need to store the image pitch somewhere, | ||||
|        * as packing details might change before image is uploaded: | ||||
|        */ | ||||
|       if (!r200IsAgpMemory( rmesa, pixels, srcHeight * srcRowStride ) || | ||||
| 	  (srcRowStride & 63)) | ||||
| 	 return 0; | ||||
|  | ||||
|  | ||||
|       /* Have validated that _mesa_transfer_teximage would be a straight | ||||
|        * memcpy at this point.  NOTE: future calls to TexSubImage will | ||||
|        * overwrite the client data.  This is explicitly mentioned in the | ||||
|        * extension spec. | ||||
|        */ | ||||
|       texImage->Data = (void *)pixels; | ||||
|       texImage->IsClientData = GL_TRUE; | ||||
|       texImage->RowStride = srcRowStride / texelBytes; | ||||
|       return 1; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                               GLint internalFormat, | ||||
|                               GLint width, GLint border, | ||||
|                               GLenum format, GLenum type, const GLvoid *pixels, | ||||
|                               const struct gl_pixelstore_attrib *packing, | ||||
|                               struct gl_texture_object *texObj, | ||||
|                               struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|  | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj( texObj ); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    /* Note, this will call r200ChooseTextureFormat */ | ||||
|    _mesa_store_teximage1d(ctx, target, level, internalFormat, | ||||
|                           width, border, format, type, pixels, | ||||
|                           &ctx->Unpack, texObj, texImage); | ||||
|  | ||||
|    t->dirty_images[0] |= (1 << level); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                                  GLint xoffset, | ||||
|                                  GLsizei width, | ||||
|                                  GLenum format, GLenum type, | ||||
|                                  const GLvoid *pixels, | ||||
|                                  const struct gl_pixelstore_attrib *packing, | ||||
|                                  struct gl_texture_object *texObj, | ||||
|                                  struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; | ||||
|  | ||||
|    assert( t ); /* this _should_ be true */ | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|       t->dirty_images[0] |= (1 << level); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj(texObj); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, | ||||
| 			     format, type, pixels, packing, texObj, | ||||
| 			     texImage); | ||||
|  | ||||
|    t->dirty_images[0] |= (1 << level); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                               GLint internalFormat, | ||||
|                               GLint width, GLint height, GLint border, | ||||
|                               GLenum format, GLenum type, const GLvoid *pixels, | ||||
|                               const struct gl_pixelstore_attrib *packing, | ||||
|                               struct gl_texture_object *texObj, | ||||
|                               struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; | ||||
|    GLuint face; | ||||
|  | ||||
|    /* which cube face or ordinary 2D image */ | ||||
|    switch (target) { | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_X: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: | ||||
|       face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; | ||||
|       ASSERT(face < 6); | ||||
|       break; | ||||
|    default: | ||||
|       face = 0; | ||||
|    } | ||||
|  | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj( texObj ); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    texImage->IsClientData = GL_FALSE; | ||||
|  | ||||
|    if (r200ValidateClientStorage( ctx, target,  | ||||
| 				  internalFormat,  | ||||
| 				  width, height,  | ||||
| 				  format, type, pixels,  | ||||
| 				  packing, texObj, texImage)) { | ||||
|       if (R200_DEBUG & DEBUG_TEXTURE) | ||||
| 	 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);  | ||||
|    } | ||||
|    else { | ||||
|       if (R200_DEBUG & DEBUG_TEXTURE) | ||||
| 	 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);  | ||||
|  | ||||
|       /* Normal path: copy (to cached memory) and eventually upload | ||||
|        * via another copy to agp memory and then a blit...  Could | ||||
|        * eliminate one copy by going straight to (permanent) agp. | ||||
|        * | ||||
|        * Note, this will call r200ChooseTextureFormat. | ||||
|        */ | ||||
|       _mesa_store_teximage2d(ctx, target, level, internalFormat, | ||||
| 			     width, height, border, format, type, pixels, | ||||
| 			     &ctx->Unpack, texObj, texImage); | ||||
|        | ||||
|       t->dirty_images[face] |= (1 << level); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                                  GLint xoffset, GLint yoffset, | ||||
|                                  GLsizei width, GLsizei height, | ||||
|                                  GLenum format, GLenum type, | ||||
|                                  const GLvoid *pixels, | ||||
|                                  const struct gl_pixelstore_attrib *packing, | ||||
|                                  struct gl_texture_object *texObj, | ||||
|                                  struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|    GLuint face; | ||||
|  | ||||
| /*     fprintf(stderr, "%s\n", __FUNCTION__); */ | ||||
|  | ||||
|    /* which cube face or ordinary 2D image */ | ||||
|    switch (target) { | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_X: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: | ||||
|    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: | ||||
|    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: | ||||
|       face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; | ||||
|       ASSERT(face < 6); | ||||
|       break; | ||||
|    default: | ||||
|       face = 0; | ||||
|    } | ||||
|  | ||||
|    assert( t ); /* this _should_ be true */ | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj(texObj); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, | ||||
| 			     height, format, type, pixels, packing, texObj, | ||||
| 			     texImage); | ||||
|  | ||||
|    t->dirty_images[face] |= (1 << level); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                             GLint internalFormat, | ||||
|                             GLint width, GLint height, GLint depth, | ||||
|                             GLint border, | ||||
|                             GLenum format, GLenum type, const GLvoid *pixels, | ||||
|                             const struct gl_pixelstore_attrib *packing, | ||||
|                             struct gl_texture_object *texObj, | ||||
|                             struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; | ||||
|  | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj( texObj ); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    texImage->IsClientData = GL_FALSE; | ||||
|  | ||||
| #if 0 | ||||
|    if (r200ValidateClientStorage( ctx, target,  | ||||
| 				  internalFormat,  | ||||
| 				  width, height,  | ||||
| 				  format, type, pixels,  | ||||
| 				  packing, texObj, texImage)) { | ||||
|       if (R200_DEBUG & DEBUG_TEXTURE) | ||||
| 	 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);  | ||||
|    } | ||||
|    else | ||||
| #endif | ||||
|    { | ||||
|       if (R200_DEBUG & DEBUG_TEXTURE) | ||||
| 	 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);  | ||||
|  | ||||
|       /* Normal path: copy (to cached memory) and eventually upload | ||||
|        * via another copy to agp memory and then a blit...  Could | ||||
|        * eliminate one copy by going straight to (permanent) agp. | ||||
|        * | ||||
|        * Note, this will call r200ChooseTextureFormat. | ||||
|        */ | ||||
|       _mesa_store_teximage3d(ctx, target, level, internalFormat, | ||||
| 			     width, height, depth, border, | ||||
|                              format, type, pixels, | ||||
| 			     &ctx->Unpack, texObj, texImage); | ||||
|        | ||||
|       t->dirty_images[0] |= (1 << level); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level, | ||||
|                    GLint xoffset, GLint yoffset, GLint zoffset, | ||||
|                    GLsizei width, GLsizei height, GLsizei depth, | ||||
|                    GLenum format, GLenum type, | ||||
|                    const GLvoid *pixels, | ||||
|                    const struct gl_pixelstore_attrib *packing, | ||||
|                    struct gl_texture_object *texObj, | ||||
|                    struct gl_texture_image *texImage ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|  | ||||
| /*     fprintf(stderr, "%s\n", __FUNCTION__); */ | ||||
|  | ||||
|    assert( t ); /* this _should_ be true */ | ||||
|    if ( t ) { | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|    else { | ||||
|       t = r200AllocTexObj(texObj); | ||||
|       if (!t) { | ||||
|          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); | ||||
|          return; | ||||
|       } | ||||
|       texObj->DriverData = t; | ||||
|    } | ||||
|  | ||||
|    _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, | ||||
|                              width, height, depth, | ||||
|                              format, type, pixels, packing, texObj, texImage); | ||||
|  | ||||
|    t->dirty_images[0] |= (1 << level); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void r200TexEnv( GLcontext *ctx, GLenum target, | ||||
| 			  GLenum pname, const GLfloat *param ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint unit = ctx->Texture.CurrentUnit; | ||||
|    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_STATE ) { | ||||
|       fprintf( stderr, "%s( %s )\n", | ||||
| 	       __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); | ||||
|    } | ||||
|  | ||||
|    /* This is incorrect: Need to maintain this data for each of | ||||
|     * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch | ||||
|     * between them according to _ReallyEnabled. | ||||
|     */ | ||||
|    switch ( pname ) { | ||||
|    case GL_TEXTURE_ENV_COLOR: { | ||||
|       GLubyte c[4]; | ||||
|       GLuint envColor; | ||||
|       UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); | ||||
|       envColor = r200PackColor( 4, c[0], c[1], c[2], c[3] ); | ||||
|       if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) { | ||||
| 	 R200_STATECHANGE( rmesa, tf ); | ||||
| 	 rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor; | ||||
|       } | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    case GL_TEXTURE_LOD_BIAS_EXT: { | ||||
|       GLfloat bias; | ||||
|       GLuint b; | ||||
|       const int fixed_one = 0x8000000; | ||||
|  | ||||
|       /* The R200's LOD bias is a signed 2's complement value with a | ||||
|        * range of -16.0 <= bias < 16.0.  | ||||
|        * | ||||
|        * NOTE: Add a small bias to the bias for conform mipsel.c test. | ||||
|        */ | ||||
|       bias = *param + .01; | ||||
|       bias = CLAMP( bias, -16.0, 16.0 ); | ||||
|       b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK; | ||||
|        | ||||
|       if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) { | ||||
| 	 R200_STATECHANGE( rmesa, tex[unit] ); | ||||
| 	 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] &= ~R200_LOD_BIAS_MASK; | ||||
| 	 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] |= b; | ||||
|       } | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    default: | ||||
|       return; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200TexParameter( GLcontext *ctx, GLenum target, | ||||
| 				struct gl_texture_object *texObj, | ||||
| 				GLenum pname, const GLfloat *params ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|  | ||||
|    if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { | ||||
|       fprintf( stderr, "%s( %s )\n", __FUNCTION__, | ||||
| 	       _mesa_lookup_enum_by_nr( pname ) ); | ||||
|    } | ||||
|  | ||||
|    if (!t) | ||||
|       return; | ||||
|  | ||||
|    switch ( pname ) { | ||||
|    case GL_TEXTURE_MIN_FILTER: | ||||
|    case GL_TEXTURE_MAG_FILTER: | ||||
|    case GL_TEXTURE_MAX_ANISOTROPY_EXT: | ||||
|       r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); | ||||
|       r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); | ||||
|       break; | ||||
|  | ||||
|    case GL_TEXTURE_WRAP_S: | ||||
|    case GL_TEXTURE_WRAP_T: | ||||
|    case GL_TEXTURE_WRAP_R: | ||||
|       r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR ); | ||||
|       break; | ||||
|  | ||||
|    case GL_TEXTURE_BORDER_COLOR: | ||||
|       r200SetTexBorderColor( t, texObj->_BorderChan ); | ||||
|       break; | ||||
|  | ||||
|    case GL_TEXTURE_BASE_LEVEL: | ||||
|    case GL_TEXTURE_MAX_LEVEL: | ||||
|    case GL_TEXTURE_MIN_LOD: | ||||
|    case GL_TEXTURE_MAX_LOD: | ||||
|       /* This isn't the most efficient solution but there doesn't appear to | ||||
|        * be a nice alternative for R200.  Since there's no LOD clamping, | ||||
|        * we just have to rely on loading the right subset of mipmap levels | ||||
|        * to simulate a clamped LOD. | ||||
|        */ | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|       break; | ||||
|  | ||||
|    default: | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    /* Mark this texobj as dirty (one bit per tex unit) | ||||
|     */ | ||||
|    t->dirty_state = TEX_ALL; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void r200BindTexture( GLcontext *ctx, GLenum target, | ||||
| 			       struct gl_texture_object *texObj ) | ||||
| { | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|    GLuint unit = ctx->Texture.CurrentUnit; | ||||
|  | ||||
|    if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { | ||||
|       fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit ); | ||||
|    } | ||||
|  | ||||
|    if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { | ||||
|       if ( !t ) { | ||||
| 	 t = r200AllocTexObj( texObj ); | ||||
| 	 texObj->DriverData = t; | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
| static void r200DeleteTexture( GLcontext *ctx, | ||||
| 				 struct gl_texture_object *texObj ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|  | ||||
|    if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { | ||||
|       fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); | ||||
|    } | ||||
|  | ||||
|    if ( t ) { | ||||
|       if ( rmesa ) { | ||||
|          R200_FIREVERTICES( rmesa ); | ||||
|       } | ||||
|       r200DestroyTexObj( rmesa, t ); | ||||
|       texObj->DriverData = NULL; | ||||
|    } | ||||
| } | ||||
|  | ||||
| static GLboolean r200IsTextureResident( GLcontext *ctx, | ||||
| 					  struct gl_texture_object *texObj ) | ||||
| { | ||||
|    r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; | ||||
|  | ||||
|    return ( t && t->memBlock ); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200InitTextureObjects( GLcontext *ctx ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    struct gl_texture_object *texObj; | ||||
|    GLuint tmp = ctx->Texture.CurrentUnit; | ||||
|  | ||||
|    ctx->Texture.CurrentUnit = 0; | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[0].Current1D; | ||||
|    r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|    move_to_tail( &rmesa->texture.swapped, | ||||
| 		 (r200TexObjPtr)texObj->DriverData ); | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[0].Current2D; | ||||
|    r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
|    move_to_tail( &rmesa->texture.swapped, | ||||
| 		 (r200TexObjPtr)texObj->DriverData ); | ||||
|  | ||||
|    ctx->Texture.CurrentUnit = 1; | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[1].Current1D; | ||||
|    r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); | ||||
|    move_to_tail( &rmesa->texture.swapped, | ||||
| 		 (r200TexObjPtr)texObj->DriverData ); | ||||
|  | ||||
|    texObj = ctx->Texture.Unit[1].Current2D; | ||||
|    r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); | ||||
|    move_to_tail( &rmesa->texture.swapped, | ||||
| 		 (r200TexObjPtr)texObj->DriverData ); | ||||
|  | ||||
|    ctx->Texture.CurrentUnit = tmp; | ||||
| } | ||||
|  | ||||
| /* Need:   | ||||
|  *  - Same GEN_MODE for all active bits | ||||
|  *  - Same EyePlane/ObjPlane for all active bits when using Eye/Obj | ||||
|  *  - STRQ presumably all supported (matrix means incoming R values | ||||
|  *    can end up in STQ, this has implications for vertex support, | ||||
|  *    presumably ok if maos is used, though?) | ||||
|  *   | ||||
|  * Basically impossible to do this on the fly - just collect some | ||||
|  * basic info & do the checks from ValidateState(). | ||||
|  */ | ||||
| static void r200TexGen( GLcontext *ctx, | ||||
| 			  GLenum coord, | ||||
| 			  GLenum pname, | ||||
| 			  const GLfloat *params ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    GLuint unit = ctx->Texture.CurrentUnit; | ||||
|    rmesa->recheck_texgen[unit] = GL_TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200InitTextureFuncs( GLcontext *ctx ) | ||||
| { | ||||
|    ctx->Driver.ChooseTextureFormat	= r200ChooseTextureFormat; | ||||
|    ctx->Driver.TexImage1D		= r200TexImage1D; | ||||
|    ctx->Driver.TexImage2D		= r200TexImage2D; | ||||
| #if ENABLE_HW_3D_TEXTURE | ||||
|    ctx->Driver.TexImage3D		= r200TexImage3D; | ||||
| #else | ||||
|    ctx->Driver.TexImage3D		= _mesa_store_teximage3d; | ||||
| #endif | ||||
|    ctx->Driver.TexSubImage1D		= r200TexSubImage1D; | ||||
|    ctx->Driver.TexSubImage2D		= r200TexSubImage2D; | ||||
| #if ENABLE_HW_3D_TEXTURE | ||||
|    ctx->Driver.TexSubImage3D		= r200TexSubImage3D; | ||||
| #else | ||||
|    ctx->Driver.TexSubImage3D		= _mesa_store_texsubimage3d; | ||||
| #endif | ||||
|    ctx->Driver.CopyTexImage1D		= _swrast_copy_teximage1d; | ||||
|    ctx->Driver.CopyTexImage2D		= _swrast_copy_teximage2d; | ||||
|    ctx->Driver.CopyTexSubImage1D	= _swrast_copy_texsubimage1d; | ||||
|    ctx->Driver.CopyTexSubImage2D	= _swrast_copy_texsubimage2d; | ||||
|    ctx->Driver.CopyTexSubImage3D 	= _swrast_copy_texsubimage3d; | ||||
|    ctx->Driver.TestProxyTexImage	= _mesa_test_proxy_teximage; | ||||
|  | ||||
|    ctx->Driver.BindTexture		= r200BindTexture; | ||||
|    ctx->Driver.CreateTexture		= NULL; /* FIXME: Is this used??? */ | ||||
|    ctx->Driver.DeleteTexture		= r200DeleteTexture; | ||||
|    ctx->Driver.IsTextureResident	= r200IsTextureResident; | ||||
|    ctx->Driver.PrioritizeTexture	= NULL; | ||||
|    ctx->Driver.ActiveTexture		= NULL; | ||||
|    ctx->Driver.UpdateTexturePalette	= NULL; | ||||
|  | ||||
|    ctx->Driver.TexEnv			= r200TexEnv; | ||||
|    ctx->Driver.TexParameter		= r200TexParameter; | ||||
|    ctx->Driver.TexGen                   = r200TexGen; | ||||
|  | ||||
|    r200InitTextureObjects( ctx ); | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/mesa/drivers/dri/r200/r200_tex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/mesa/drivers/dri/r200/r200_tex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_TEX_H__ | ||||
| #define __R200_TEX_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| extern void r200UpdateTextureState( GLcontext *ctx ); | ||||
|  | ||||
| extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ); | ||||
|  | ||||
| extern void r200AgeTextures( r200ContextPtr rmesa, int heap ); | ||||
| extern void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); | ||||
| extern void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); | ||||
|  | ||||
| extern void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ); | ||||
| extern void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ); | ||||
| extern void r200UpdateTexLRU( r200ContextPtr rmesa, r200TexObjPtr t ); | ||||
|  | ||||
| extern void r200InitTextureFuncs( GLcontext *ctx ); | ||||
|  | ||||
| #endif | ||||
| #endif /* __R200_TEX_H__ */ | ||||
							
								
								
									
										811
									
								
								src/mesa/drivers/dri/r200/r200_texmem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										811
									
								
								src/mesa/drivers/dri/r200/r200_texmem.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,811 @@ | ||||
| /* $XFree86$ */ | ||||
| /************************************************************************** | ||||
|  | ||||
| Copyright (C) Tungsten Graphics 2002.  All Rights Reserved.   | ||||
| The Weather Channel, Inc. funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 | ||||
| license. This notice must be preserved. | ||||
|  | ||||
| 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 on the rights to use, copy, modify, merge, publish, | ||||
| distribute, sub license, and/or sell copies of the Software, and to | ||||
| permit persons to whom the Software is furnished to do so, subject to | ||||
| the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR | ||||
| SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||||
| IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR | ||||
| IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | ||||
| **************************************************************************/ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Kevin E. Martin <martin@valinux.com> | ||||
|  *   Gareth Hughes <gareth@valinux.com> | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "context.h" | ||||
| #include "colormac.h" | ||||
| #include "mmath.h" | ||||
| #include "macros.h" | ||||
| #include "simple_list.h" | ||||
| #include "radeon_reg.h" /* gets definition for usleep */ | ||||
| #include "r200_context.h" | ||||
| #include "r200_state.h" | ||||
| #include "r200_ioctl.h" | ||||
| #include "r200_swtcl.h" | ||||
| #include "r200_tex.h" | ||||
|  | ||||
| #include <unistd.h>  /* for usleep() */ | ||||
| #include <errno.h> | ||||
|  | ||||
| /* Destroy hardware state associated with texture `t'. | ||||
|  */ | ||||
| void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) | ||||
| { | ||||
|    if ( !t ) | ||||
|       return; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_TEXTURE ) { | ||||
|       fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); | ||||
|    } | ||||
|  | ||||
|    if ( t->memBlock ) { | ||||
|       mmFreeMem( t->memBlock ); | ||||
|       t->memBlock = NULL; | ||||
|    } | ||||
|  | ||||
|    if ( t->tObj ) | ||||
|       t->tObj->DriverData = NULL; | ||||
|  | ||||
|    if ( rmesa ) { | ||||
|       if ( t == rmesa->state.texture.unit[0].texobj ) { | ||||
|          rmesa->state.texture.unit[0].texobj = NULL; | ||||
| 	 remove_from_list( &rmesa->hw.tex[0] ); | ||||
| 	 make_empty_list( &rmesa->hw.tex[0] ); | ||||
| 	 remove_from_list( &rmesa->hw.cube[0] ); | ||||
| 	 make_empty_list( &rmesa->hw.cube[0] ); | ||||
|       } | ||||
|  | ||||
|       if ( t == rmesa->state.texture.unit[1].texobj ) { | ||||
|          rmesa->state.texture.unit[1].texobj = NULL; | ||||
| 	 remove_from_list( &rmesa->hw.tex[1] ); | ||||
| 	 make_empty_list( &rmesa->hw.tex[1] ); | ||||
| 	 remove_from_list( &rmesa->hw.cube[1] ); | ||||
| 	 make_empty_list( &rmesa->hw.cube[1] ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    remove_from_list( t ); | ||||
|    FREE( t ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Keep track of swapped out texture objects. | ||||
|  */ | ||||
| void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) | ||||
| { | ||||
|    GLuint face; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_TEXTURE ) { | ||||
|       fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); | ||||
|    } | ||||
|  | ||||
|    if (t->memBlock) { | ||||
|       mmFreeMem( t->memBlock ); | ||||
|       t->memBlock = NULL; | ||||
|    } | ||||
|  | ||||
|    if (!t->tObj) { | ||||
|       remove_from_list( t ); | ||||
|       FREE( t ); | ||||
|    } | ||||
|    else { | ||||
|       for (face = 0; face < 6; face++) | ||||
| 	 t->dirty_images[face] = ~0; | ||||
|       move_to_tail( &rmesa->texture.swapped, t ); | ||||
|    } | ||||
| } | ||||
|  | ||||
| /* Print out debugging information about texture LRU. | ||||
|  */ | ||||
| void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ) | ||||
| { | ||||
|    r200TexObjPtr t; | ||||
|    int sz = 1 << (rmesa->r200Screen->logTexGranularity[heap]); | ||||
|  | ||||
|    fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); | ||||
|  | ||||
|    foreach ( t, &rmesa->texture.objects[heap] ) { | ||||
|       if (!t->memBlock) | ||||
| 	 continue; | ||||
|       if (!t->tObj) { | ||||
| 	 fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", | ||||
| 		  t->memBlock->ofs / sz, | ||||
| 		  t->memBlock->ofs, | ||||
| 		  t->memBlock->size ); | ||||
|       } else { | ||||
| 	 fprintf( stderr, "Texture at 0x%x sz 0x%x\n", | ||||
| 		  t->memBlock->ofs, | ||||
| 		  t->memBlock->size ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    fprintf( stderr, "\n" ); | ||||
| } | ||||
|  | ||||
| void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ) | ||||
| { | ||||
|    radeon_tex_region_t *list = rmesa->sarea->texList[heap]; | ||||
|    int i, j; | ||||
|  | ||||
|    fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); | ||||
|  | ||||
|    for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { | ||||
|       fprintf( stderr, "list[%d] age %d next %d prev %d\n", | ||||
| 	       j, list[j].age, list[j].next, list[j].prev ); | ||||
|       j = list[j].next; | ||||
|       if ( j == RADEON_NR_TEX_REGIONS ) break; | ||||
|    } | ||||
|  | ||||
|    if ( j != RADEON_NR_TEX_REGIONS ) { | ||||
|       fprintf( stderr, "Loop detected in global LRU\n" ); | ||||
|       for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { | ||||
| 	 fprintf( stderr, "list[%d] age %d next %d prev %d\n", | ||||
| 		  i, list[i].age, list[i].next, list[i].prev ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    fprintf( stderr, "\n" ); | ||||
| } | ||||
|  | ||||
| /* Reset the global texture LRU. | ||||
|  */ | ||||
| static void r200ResetGlobalLRU( r200ContextPtr rmesa, int heap ) | ||||
| { | ||||
|    radeon_tex_region_t *list = rmesa->sarea->texList[heap]; | ||||
|    int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; | ||||
|    int i; | ||||
|  | ||||
|    /* | ||||
|     * (Re)initialize the global circular LRU list.  The last element in | ||||
|     * the array (RADEON_NR_TEX_REGIONS) is the sentinal.  Keeping it at | ||||
|     * the end of the array allows it to be addressed rationally when | ||||
|     * looking up objects at a particular location in texture memory. | ||||
|     */ | ||||
|    for ( i = 0 ; (i+1) * sz <= rmesa->r200Screen->texSize[heap] ; i++ ) { | ||||
|       list[i].prev = i-1; | ||||
|       list[i].next = i+1; | ||||
|       list[i].age = 0; | ||||
|    } | ||||
|  | ||||
|    i--; | ||||
|    list[0].prev = RADEON_NR_TEX_REGIONS; | ||||
|    list[i].prev = i-1; | ||||
|    list[i].next = RADEON_NR_TEX_REGIONS; | ||||
|    list[RADEON_NR_TEX_REGIONS].prev = i; | ||||
|    list[RADEON_NR_TEX_REGIONS].next = 0; | ||||
|    rmesa->sarea->texAge[heap] = 0; | ||||
| } | ||||
|  | ||||
| /* Update the local and glock texture LRUs. | ||||
|  */ | ||||
| void r200UpdateTexLRU(r200ContextPtr rmesa, r200TexObjPtr t ) | ||||
| { | ||||
|    int heap = t->heap; | ||||
|    radeon_tex_region_t *list = rmesa->sarea->texList[heap]; | ||||
|    int sz = rmesa->r200Screen->logTexGranularity[heap]; | ||||
|    int i, start, end; | ||||
|  | ||||
|    rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap]; | ||||
|  | ||||
|    if ( !t->memBlock )  | ||||
|       return; | ||||
|  | ||||
|    start = t->memBlock->ofs >> sz; | ||||
|    end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; | ||||
|  | ||||
|    /* Update our local LRU */ | ||||
|    move_to_head( &rmesa->texture.objects[heap], t ); | ||||
|  | ||||
|    /* Update the global LRU */ | ||||
|    for ( i = start ; i <= end ; i++ ) { | ||||
|       list[i].in_use = 1; | ||||
|       list[i].age = rmesa->texture.age[heap]; | ||||
|  | ||||
|       /* remove_from_list(i) */ | ||||
|       list[(GLuint)list[i].next].prev = list[i].prev; | ||||
|       list[(GLuint)list[i].prev].next = list[i].next; | ||||
|  | ||||
|       /* insert_at_head(list, i) */ | ||||
|       list[i].prev = RADEON_NR_TEX_REGIONS; | ||||
|       list[i].next = list[RADEON_NR_TEX_REGIONS].next; | ||||
|       list[(GLuint)list[RADEON_NR_TEX_REGIONS].next].prev = i; | ||||
|       list[RADEON_NR_TEX_REGIONS].next = i; | ||||
|    } | ||||
|  | ||||
|    if ( 0 ) { | ||||
|       r200PrintGlobalLRU( rmesa, t->heap ); | ||||
|       r200PrintLocalLRU( rmesa, t->heap ); | ||||
|    } | ||||
| } | ||||
|  | ||||
| /* Update our notion of what textures have been changed since we last | ||||
|  * held the lock.  This pertains to both our local textures and the | ||||
|  * textures belonging to other clients.  Keep track of other client's | ||||
|  * textures by pushing a placeholder texture onto the LRU list -- these | ||||
|  * are denoted by (tObj == NULL). | ||||
|  */ | ||||
| static void r200TexturesGone( r200ContextPtr rmesa, int heap, | ||||
| 				int offset, int size, int in_use ) | ||||
| { | ||||
|    r200TexObjPtr t, tmp; | ||||
|  | ||||
|    foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) { | ||||
|       if ( !t->memBlock || | ||||
| 	   t->memBlock->ofs >= offset + size || | ||||
| 	   t->memBlock->ofs + t->memBlock->size <= offset ) | ||||
| 	 continue; | ||||
|  | ||||
|       /* It overlaps - kick it out.  Need to hold onto the currently | ||||
|        * bound objects, however. | ||||
|        */ | ||||
|       r200SwapOutTexObj( rmesa, t ); | ||||
|    } | ||||
|  | ||||
|    if ( in_use ) { | ||||
|       t = (r200TexObjPtr) CALLOC( sizeof(*t) ); | ||||
|       if ( !t ) return; | ||||
|  | ||||
|       t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset ); | ||||
|       if ( !t->memBlock ) { | ||||
| 	 fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", | ||||
| 		  (int)size, (int)offset ); | ||||
| 	 mmDumpMemInfo( rmesa->texture.heap[heap] ); | ||||
| 	 return; | ||||
|       } | ||||
|       insert_at_head( &rmesa->texture.objects[heap], t ); | ||||
|    } | ||||
| } | ||||
|  | ||||
| /* Update our client's shared texture state.  If another client has | ||||
|  * modified a region in which we have textures, then we need to figure | ||||
|  * out which of our textures has been removed, and update our global | ||||
|  * LRU. | ||||
|  */ | ||||
| void r200AgeTextures( r200ContextPtr rmesa, int heap ) | ||||
| { | ||||
|    RADEONSAREAPrivPtr sarea = rmesa->sarea; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_TEXTURE ) { | ||||
|       fprintf(stderr, "%s %d\n", __FUNCTION__, heap); | ||||
|    } | ||||
|  | ||||
|    if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) { | ||||
|       int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; | ||||
|       int nr = 0; | ||||
|       int idx; | ||||
|  | ||||
|       for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; | ||||
| 	    idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; | ||||
| 	    idx = sarea->texList[heap][idx].prev, nr++ ) | ||||
|       { | ||||
| 	 /* If switching texturing schemes, then the SAREA might not | ||||
| 	  * have been properly cleared, so we need to reset the | ||||
| 	  * global texture LRU. | ||||
| 	  */ | ||||
| 	 if ( idx * sz > rmesa->r200Screen->texSize[heap] ) { | ||||
| 	    nr = RADEON_NR_TEX_REGIONS; | ||||
| 	    break; | ||||
| 	 } | ||||
|  | ||||
| 	 if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) { | ||||
| 	    r200TexturesGone( rmesa, heap, idx * sz, sz, | ||||
| 				sarea->texList[heap][idx].in_use ); | ||||
| 	 } | ||||
|       } | ||||
|  | ||||
|       if ( nr == RADEON_NR_TEX_REGIONS ) { | ||||
| 	 r200TexturesGone( rmesa, heap, 0, | ||||
| 			     rmesa->r200Screen->texSize[heap], 0 ); | ||||
| 	 r200ResetGlobalLRU( rmesa, heap ); | ||||
|       } | ||||
|  | ||||
|       rmesa->texture.age[heap] = sarea->texAge[heap]; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ------------------------------------------------------------ | ||||
|  * Texture image conversions | ||||
|  */ | ||||
|  | ||||
|  | ||||
| static void r200UploadAGPClientSubImage( r200ContextPtr rmesa, | ||||
| 					 r200TexObjPtr t,  | ||||
| 					 struct gl_texture_image *texImage, | ||||
| 					 GLint hwlevel, | ||||
| 					 GLint x, GLint y,  | ||||
| 					 GLint width, GLint height ) | ||||
| { | ||||
|    const struct gl_texture_format *texFormat = texImage->TexFormat; | ||||
|    GLuint srcPitch, dstPitch; | ||||
|    int blit_format; | ||||
|    int srcOffset; | ||||
|  | ||||
|    /* | ||||
|     * XXX it appears that we always upload the full image, not a subimage. | ||||
|     * I.e. x==0, y==0, width=texWidth, height=texWidth.  If this is ever | ||||
|     * changed, the src pitch will have to change. | ||||
|     */ | ||||
|    switch ( texFormat->TexelBytes ) { | ||||
|    case 1: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_CI8; | ||||
|       srcPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       dstPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       break; | ||||
|    case 2: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_RGB565; | ||||
|       srcPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       dstPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       break; | ||||
|    case 4: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_ARGB8888; | ||||
|       srcPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       dstPitch = t->image[0][0].width * texFormat->TexelBytes; | ||||
|       break; | ||||
|    default: | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    t->image[0][hwlevel].data = texImage->Data; | ||||
|    srcOffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data ); | ||||
|  | ||||
|    assert( srcOffset != ~0 ); | ||||
|  | ||||
|    /* Don't currently need to cope with small pitches? | ||||
|     */ | ||||
|    width = texImage->Width; | ||||
|    height = texImage->Height; | ||||
|  | ||||
|    r200EmitWait( rmesa, RADEON_WAIT_3D ); | ||||
|  | ||||
|    r200EmitBlit( rmesa, blit_format,  | ||||
| 		 srcPitch,   | ||||
| 		 srcOffset,    | ||||
| 		 dstPitch, | ||||
| 		 t->bufAddr, | ||||
| 		 x,  | ||||
| 		 y,  | ||||
| 		 t->image[0][hwlevel].x + x, | ||||
| 		 t->image[0][hwlevel].y + y,  | ||||
| 		 width, | ||||
| 		 height ); | ||||
|  | ||||
|    r200EmitWait( rmesa, RADEON_WAIT_2D ); | ||||
| } | ||||
|  | ||||
| static void r200UploadRectSubImage( r200ContextPtr rmesa, | ||||
| 				    r200TexObjPtr t,  | ||||
| 				    struct gl_texture_image *texImage, | ||||
| 				    GLint x, GLint y,  | ||||
| 				    GLint width, GLint height ) | ||||
| { | ||||
|    const struct gl_texture_format *texFormat = texImage->TexFormat; | ||||
|    int blit_format, dstPitch, done; | ||||
|  | ||||
|    switch ( texFormat->TexelBytes ) { | ||||
|    case 1: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_CI8; | ||||
|       break; | ||||
|    case 2: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_RGB565; | ||||
|       break; | ||||
|    case 4: | ||||
|       blit_format = R200_CP_COLOR_FORMAT_ARGB8888; | ||||
|       break; | ||||
|    default: | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    t->image[0][0].data = texImage->Data; | ||||
|  | ||||
|    /* Currently don't need to cope with small pitches. | ||||
|     */ | ||||
|    width = texImage->Width; | ||||
|    height = texImage->Height; | ||||
|    dstPitch = t->pp_txpitch + 32; | ||||
|  | ||||
|    if (rmesa->prefer_agp_client_texturing && texImage->IsClientData) { | ||||
|       /* In this case, could also use agp texturing.  This is | ||||
|        * currently disabled, but has been tested & works. | ||||
|        */ | ||||
|       t->pp_txoffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data ); | ||||
|       t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32; | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_TEXTURE) | ||||
| 	 fprintf(stderr,  | ||||
| 		 "Using agp texturing for rectangular client texture\n"); | ||||
|  | ||||
|       /* Release FB memory allocated for this image: | ||||
|        */ | ||||
|       if ( t->memBlock ) { | ||||
| 	 mmFreeMem( t->memBlock ); | ||||
| 	 t->memBlock = NULL; | ||||
|       } | ||||
|  | ||||
|    } | ||||
|    else if (texImage->IsClientData) { | ||||
|       /* Data already in agp memory, with usable pitch. | ||||
|        */ | ||||
|       GLuint srcPitch; | ||||
|       srcPitch = texImage->RowStride * texFormat->TexelBytes; | ||||
|       r200EmitBlit( rmesa,  | ||||
| 		    blit_format,  | ||||
| 		    srcPitch, | ||||
| 		    r200AgpOffsetFromVirtual( rmesa, texImage->Data ),    | ||||
| 		    dstPitch, t->bufAddr, | ||||
| 		    0, 0,  | ||||
| 		    0, 0,  | ||||
| 		    width, height ); | ||||
|    } | ||||
|    else { | ||||
|       /* Data not in agp memory, or bad pitch. | ||||
|        */ | ||||
|       for (done = 0; done < height ; ) { | ||||
| 	 struct r200_dma_region region; | ||||
| 	 int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); | ||||
| 	 int src_pitch; | ||||
| 	 char *tex; | ||||
|  | ||||
|          src_pitch = texImage->RowStride * texFormat->TexelBytes; | ||||
|  | ||||
| 	 tex = (char *)texImage->Data + done * src_pitch; | ||||
|  | ||||
| 	 memset(®ion, 0, sizeof(region)); | ||||
| 	 r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 64 ); | ||||
|  | ||||
| 	 /* Copy texdata to dma: | ||||
| 	  */ | ||||
| 	 if (0) | ||||
| 	    fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", | ||||
| 		    __FUNCTION__, src_pitch, dstPitch); | ||||
|  | ||||
| 	 if (src_pitch == dstPitch) { | ||||
| 	    memcpy( region.address, tex, lines * src_pitch ); | ||||
| 	 }  | ||||
| 	 else { | ||||
| 	    char *buf = region.address; | ||||
| 	    int i; | ||||
| 	    for (i = 0 ; i < lines ; i++) { | ||||
| 	       memcpy( buf, tex, src_pitch ); | ||||
| 	       buf += dstPitch; | ||||
| 	       tex += src_pitch; | ||||
| 	    } | ||||
| 	 } | ||||
|  | ||||
| 	 r200EmitWait( rmesa, RADEON_WAIT_3D ); | ||||
|  | ||||
| 	 /* Blit to framebuffer | ||||
| 	  */ | ||||
| 	 r200EmitBlit( rmesa,  | ||||
| 		       blit_format,  | ||||
| 		       dstPitch, GET_START( ®ion ),    | ||||
| 		       dstPitch, t->bufAddr, | ||||
| 		       0, 0,  | ||||
| 		       0, done,  | ||||
| 		       width, lines ); | ||||
| 	  | ||||
| 	 r200EmitWait( rmesa, RADEON_WAIT_2D ); | ||||
|  | ||||
| 	 r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); | ||||
| 	 done += lines; | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Upload the texture image associated with texture `t' at level `level' | ||||
|  * at the address relative to `start'. | ||||
|  */ | ||||
| static void r200UploadSubImage( r200ContextPtr rmesa, | ||||
| 				r200TexObjPtr t,  | ||||
| 				GLint hwlevel, | ||||
| 				GLint x, GLint y, GLint width, GLint height, | ||||
|                                 GLuint face ) | ||||
| { | ||||
|    struct gl_texture_image *texImage = NULL; | ||||
|    const struct gl_texture_format *texFormat; | ||||
|    GLint texelsPerDword = 0; | ||||
|    GLuint format, pitch, offset; | ||||
|    GLint imageWidth, imageHeight; | ||||
|    GLint ret; | ||||
|    drmRadeonTexture tex; | ||||
|    drmRadeonTexImage tmp; | ||||
|    int level = hwlevel + t->firstLevel; | ||||
|  | ||||
|    if ( R200_DEBUG & DEBUG_TEXTURE ) { | ||||
|       fprintf( stderr, "%s level %d %dx%d\n", __FUNCTION__, | ||||
| 	       level, width, height); | ||||
|    } | ||||
|  | ||||
|    ASSERT(face < 6); | ||||
|  | ||||
|    /* Ensure we have a valid texture to upload */ | ||||
|    if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { | ||||
|       _mesa_problem(NULL, "bad texture level in r200UploadSubimage"); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    switch (face) { | ||||
|    case 0: | ||||
|       texImage = t->tObj->Image[level]; | ||||
|       break; | ||||
|    case 1: | ||||
|       texImage = t->tObj->NegX[level]; | ||||
|       break; | ||||
|    case 2: | ||||
|       texImage = t->tObj->PosY[level]; | ||||
|       break; | ||||
|    case 3: | ||||
|       texImage = t->tObj->NegY[level]; | ||||
|       break; | ||||
|    case 4: | ||||
|       texImage = t->tObj->PosZ[level]; | ||||
|       break; | ||||
|    case 5: | ||||
|       texImage = t->tObj->NegZ[level]; | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    if ( !texImage ) { | ||||
|       if ( R200_DEBUG & DEBUG_TEXTURE ) | ||||
| 	 fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); | ||||
|       return; | ||||
|    } | ||||
|    if ( !texImage->Data ) { | ||||
|       if ( R200_DEBUG & DEBUG_TEXTURE ) | ||||
| 	 fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if (t->tObj->Target == GL_TEXTURE_RECTANGLE_NV) { | ||||
|       assert(level == 0); | ||||
|       assert(hwlevel == 0); | ||||
|       if ( R200_DEBUG & DEBUG_TEXTURE ) | ||||
| 	 fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__); | ||||
|       r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height ); | ||||
|       return; | ||||
|    } | ||||
|    else if (texImage->IsClientData) { | ||||
|       if ( R200_DEBUG & DEBUG_TEXTURE ) | ||||
| 	 fprintf( stderr, "%s: image data is in agp client storage\n", | ||||
| 		  __FUNCTION__); | ||||
|       r200UploadAGPClientSubImage( rmesa, t, texImage, hwlevel, | ||||
| 				   x, y, width, height ); | ||||
|       return; | ||||
|    } | ||||
|    else if ( R200_DEBUG & DEBUG_TEXTURE ) | ||||
|       fprintf( stderr, "%s: image data is in normal memory\n", | ||||
| 	       __FUNCTION__); | ||||
|        | ||||
|  | ||||
|    texFormat = texImage->TexFormat; | ||||
|  | ||||
|    switch ( texFormat->TexelBytes ) { | ||||
|    case 1: | ||||
|       texelsPerDword = 4; | ||||
|       break; | ||||
|    case 2: | ||||
|       texelsPerDword = 2; | ||||
|       break; | ||||
|    case 4: | ||||
|       texelsPerDword = 1; | ||||
|       break; | ||||
|    } | ||||
|  | ||||
|    format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK; | ||||
|  | ||||
|    imageWidth = texImage->Width; | ||||
|    imageHeight = texImage->Height; | ||||
|  | ||||
|    offset = t->bufAddr; | ||||
|  | ||||
|    if (texFormat->TexelBytes == 0) | ||||
|       pitch = (t->image[face][0].width * 1) / 64; | ||||
|    else | ||||
|       pitch = (t->image[face][0].width * texFormat->TexelBytes) / 64; | ||||
|  | ||||
|  | ||||
|    if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) | ||||
|    { | ||||
|       GLint imageX = 0; | ||||
|       GLint imageY = 0; | ||||
|       GLint blitX = t->image[face][hwlevel].x; | ||||
|       GLint blitY = t->image[face][hwlevel].y; | ||||
|       GLint blitWidth = t->image[face][hwlevel].width; | ||||
|       GLint blitHeight = t->image[face][hwlevel].height; | ||||
|       fprintf( stderr, "   upload image: %d,%d at %d,%d\n", | ||||
| 	       imageWidth, imageHeight, imageX, imageY ); | ||||
|       fprintf( stderr, "   upload  blit: %d,%d at %d,%d\n", | ||||
| 	       blitWidth, blitHeight, blitX, blitY ); | ||||
|       fprintf( stderr, "       blit ofs: 0x%07x pitch: 0x%x " | ||||
| 	       "level: %d/%d format: %x\n", | ||||
| 	       (GLuint)offset, (GLuint)pitch, hwlevel, level, format ); | ||||
|    } | ||||
|  | ||||
|    t->image[face][hwlevel].data = texImage->Data; | ||||
|  | ||||
|    /* Init the DRM_RADEON_TEXTURE command / drmRadeonTexture struct. | ||||
|     * NOTE: we're always use a 1KB-wide blit and I8 texture format. | ||||
|     * We used to use 1, 2 and 4-byte texels and used to use the texture | ||||
|     * width to dictate the blit width - but that won't work for compressed | ||||
|     * textures. (Brian) | ||||
|     */ | ||||
|    tex.offset = offset; | ||||
|    tex.pitch = BLIT_WIDTH_BYTES / 64; | ||||
|    tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */ | ||||
|    if (texImage->TexFormat->TexelBytes) { | ||||
|       tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */ | ||||
|       tex.height = imageHeight; | ||||
|    } | ||||
|    else { | ||||
|       tex.width = imageWidth; /* compressed */ | ||||
|       tex.height = imageHeight; | ||||
|       if (tex.height < 4) | ||||
|          tex.height = 4; | ||||
|    } | ||||
|    tex.image = &tmp; | ||||
|  | ||||
|    /* copy (x,y,width,height,data) */ | ||||
|    memcpy( &tmp, &t->image[face][hwlevel], sizeof(drmRadeonTexImage) ); | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|    do { | ||||
|       ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, | ||||
|                                  &tex, sizeof(drmRadeonTexture) ); | ||||
|       if (ret) { | ||||
| 	 if (R200_DEBUG & DEBUG_IOCTL) | ||||
| 	    fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n"); | ||||
| 	 usleep(1); | ||||
|       } | ||||
|    } while ( ret && errno == EAGAIN ); | ||||
|  | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    if ( ret ) { | ||||
|       fprintf( stderr, "DRM_R200_TEXTURE: return = %d\n", ret ); | ||||
|       fprintf( stderr, "   offset=0x%08x pitch=0x%x format=%d\n", | ||||
| 	       offset, pitch, format ); | ||||
|       fprintf( stderr, "   image width=%d height=%d\n", | ||||
| 	       imageWidth, imageHeight ); | ||||
|       fprintf( stderr, "    blit width=%d height=%d data=%p\n", | ||||
| 	       t->image[face][hwlevel].width, t->image[face][hwlevel].height, | ||||
| 	       t->image[face][hwlevel].data ); | ||||
|       exit( 1 ); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Upload the texture images associated with texture `t'.  This might | ||||
|  * require removing our own and/or other client's texture objects to | ||||
|  * make room for these images. | ||||
|  */ | ||||
| int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ) | ||||
| { | ||||
|    const int numLevels = t->lastLevel - t->firstLevel + 1; | ||||
|    int heap; | ||||
|    r200TexObjPtr t0 = rmesa->state.texture.unit[0].texobj; | ||||
|    r200TexObjPtr t1 = rmesa->state.texture.unit[1].texobj; | ||||
|  | ||||
|    if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { | ||||
|       fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, | ||||
| 	       rmesa->glCtx, t->tObj, t->totalSize, | ||||
| 	       t->firstLevel, t->lastLevel ); | ||||
|    } | ||||
|  | ||||
|    if ( !t || t->totalSize == 0 ) | ||||
|       return 0; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SYNC) { | ||||
|       fprintf(stderr, "\nSyncing\n\n"); | ||||
|       R200_FIREVERTICES( rmesa ); | ||||
|       r200Finish( rmesa->glCtx ); | ||||
|    } | ||||
|  | ||||
|    LOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    /* Choose the heap appropriately */ | ||||
|    heap = t->heap = RADEON_CARD_HEAP; | ||||
|  | ||||
|    /* Do we need to eject LRU texture objects? */ | ||||
|    if ( !t->memBlock ) { | ||||
|       /* Allocate a memory block on a 1k boundary (1<<10 == 1024) */ | ||||
|       t->memBlock = mmAllocMem( rmesa->texture.heap[heap], | ||||
| 				t->totalSize, 10, 0 ); | ||||
|  | ||||
|  | ||||
|       /* Kick out textures until the requested texture fits */ | ||||
|       while ( !t->memBlock ) { | ||||
| 	 if ( rmesa->texture.objects[heap].prev == t0 || | ||||
| 	      rmesa->texture.objects[heap].prev == t1 ) { | ||||
| 	    fprintf( stderr, | ||||
| 		     "r200UploadTexImages: ran into bound texture\n" ); | ||||
| 	    UNLOCK_HARDWARE( rmesa ); | ||||
| 	    return -1; | ||||
| 	 } | ||||
| 	 if ( rmesa->texture.objects[heap].prev == | ||||
| 	      &rmesa->texture.objects[heap] ) { | ||||
| 	    if ( rmesa->r200Screen->IsPCI ) { | ||||
| 	       fprintf( stderr, "r200UploadTexImages: upload texture " | ||||
| 			"failure on local texture heaps, sz=%d\n", | ||||
| 			t->totalSize ); | ||||
| 	       UNLOCK_HARDWARE( rmesa ); | ||||
| 	       return -1; | ||||
| 	    } else { | ||||
| 	       fprintf( stderr, "r200UploadTexImages: upload texture " | ||||
| 			"failure on both local and AGP texture heaps, " | ||||
| 			"sz=%d\n", | ||||
| 			t->totalSize ); | ||||
| 	       UNLOCK_HARDWARE( rmesa ); | ||||
| 	       return -1; | ||||
| 	    } | ||||
| 	 } | ||||
|  | ||||
| 	 r200SwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev ); | ||||
|  | ||||
| 	 t->memBlock = mmAllocMem( rmesa->texture.heap[heap], | ||||
| 				   t->totalSize, 12, 0 ); | ||||
|       } | ||||
|  | ||||
|       /* Set the base offset of the texture image */ | ||||
|       t->bufAddr = rmesa->r200Screen->texOffset[heap] + t->memBlock->ofs; | ||||
|       t->pp_txoffset = t->bufAddr; | ||||
|  | ||||
|       /* Mark this texobj as dirty on all units: | ||||
|        */ | ||||
|       t->dirty_state = TEX_ALL; | ||||
|    } | ||||
|  | ||||
|    /* Let the world know we've used this memory recently */ | ||||
|    r200UpdateTexLRU( rmesa, t ); | ||||
|    UNLOCK_HARDWARE( rmesa ); | ||||
|  | ||||
|    /* Upload any images that are new */ | ||||
|    if (t->dirty_images[face]) { | ||||
|       int hwlevel; | ||||
|       for ( hwlevel = 0 ; hwlevel < numLevels ; hwlevel++ ) { | ||||
|          if ( t->dirty_images[face] & (1 << (hwlevel+t->firstLevel)) ) { | ||||
|             r200UploadSubImage( rmesa, t, hwlevel,  | ||||
|                                 0, 0, | ||||
|                                 t->image[face][hwlevel].width,  | ||||
|                                 t->image[face][hwlevel].height, face ); | ||||
|          } | ||||
|       } | ||||
|       t->dirty_images[face] = 0; | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_SYNC) { | ||||
|       fprintf(stderr, "\nSyncing\n\n"); | ||||
|       r200Finish( rmesa->glCtx ); | ||||
|    } | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
							
								
								
									
										1799
									
								
								src/mesa/drivers/dri/r200/r200_texstate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1799
									
								
								src/mesa/drivers/dri/r200/r200_texstate.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1152
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1152
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										128
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef __R200_VTXFMT_H__ | ||||
| #define __R200_VTXFMT_H__ | ||||
|  | ||||
| #ifdef GLX_DIRECT_RENDERING | ||||
|  | ||||
| #include "r200_context.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| extern struct r200_vb vb; | ||||
|  | ||||
|  | ||||
| extern void r200VtxfmtUpdate( GLcontext *ctx ); | ||||
| extern void r200VtxfmtInit( GLcontext *ctx ); | ||||
| extern void r200VtxfmtInvalidate( GLcontext *ctx ); | ||||
| extern void r200VtxfmtDestroy( GLcontext *ctx ); | ||||
| extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt ); | ||||
|  | ||||
| extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); | ||||
| extern void r200VtxfmtUnbindContext( GLcontext *ctx ); | ||||
|  | ||||
| extern void r200_copy_to_current( GLcontext *ctx ); | ||||
|  | ||||
| #define DFN( FUNC, CACHE)				\ | ||||
| do {							\ | ||||
|    char *start = (char *)&FUNC;				\ | ||||
|    char *end = (char *)&FUNC##_end;			\ | ||||
|    insert_at_head( &CACHE, dfn );			\ | ||||
|    dfn->key[0] = key[0];					\ | ||||
|    dfn->key[1] = key[1];					\ | ||||
|    dfn->code = ALIGN_MALLOC( end - start, 16 );		\ | ||||
|    memcpy (dfn->code, start, end - start);		\ | ||||
| }							\ | ||||
| while ( 0 ) | ||||
|  | ||||
| #define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL )	\ | ||||
| do {						\ | ||||
|    int *icode = (int *)(CODE+OFFSET);		\ | ||||
|    assert (*icode == CHECKVAL);			\ | ||||
|    *icode = (int)NEWVAL;			\ | ||||
| } while (0) | ||||
|  | ||||
|  | ||||
| /* Useful for figuring out the offsets: | ||||
|  */ | ||||
| #define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL )		\ | ||||
| do {								\ | ||||
|    while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++;		\ | ||||
|    /*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \ | ||||
|    /*	   __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/		\ | ||||
|    *(int *)(CODE+OFFSET) = (int)(NEWVAL);				\ | ||||
|    OFFSET += 4;							\ | ||||
| } while (0) | ||||
|  | ||||
| /*  | ||||
|  */ | ||||
| void r200InitCodegen( struct dfn_generators *gen ); | ||||
| void r200InitX86Codegen( struct dfn_generators *gen ); | ||||
| void r200InitSSECodegen( struct dfn_generators *gen ); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Defined in r200_vtxfmt_x86.c | ||||
|  */ | ||||
| struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color4f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color3f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * ); | ||||
| struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * ); | ||||
|  | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										797
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										797
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,797 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "mtypes.h" | ||||
| #include "colormac.h" | ||||
| #include "simple_list.h" | ||||
| #include "api_noop.h" | ||||
| #include "vtxfmt.h" | ||||
|  | ||||
| #include "r200_vtxfmt.h" | ||||
|  | ||||
| /* Fallback versions of all the entrypoints for situations where | ||||
|  * codegen isn't available.  This is still a lot faster than the | ||||
|  * vb/pipeline implementation in Mesa. | ||||
|  */ | ||||
| static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) | ||||
| { | ||||
|    int i; | ||||
|  | ||||
|    *vb.dmaptr++ = *(int *)&x; | ||||
|    *vb.dmaptr++ = *(int *)&y; | ||||
|    *vb.dmaptr++ = *(int *)&z; | ||||
|  | ||||
|    for (i = 3; i < vb.vertex_size; i++) | ||||
|       *vb.dmaptr++ = vb.vertex[i].i; | ||||
|     | ||||
|    if (--vb.counter == 0) | ||||
|       vb.notify(); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Vertex3fv( const GLfloat *v ) | ||||
| { | ||||
|    int i; | ||||
|  | ||||
|    *vb.dmaptr++ = *(int *)&v[0]; | ||||
|    *vb.dmaptr++ = *(int *)&v[1]; | ||||
|    *vb.dmaptr++ = *(int *)&v[2]; | ||||
|  | ||||
|    for (i = 3; i < vb.vertex_size; i++) | ||||
|       *vb.dmaptr++ = vb.vertex[i].i; | ||||
|     | ||||
|    if (--vb.counter == 0) | ||||
|       vb.notify(); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Vertex2f( GLfloat x, GLfloat y ) | ||||
| { | ||||
|    int i; | ||||
|     | ||||
|    *vb.dmaptr++ = *(int *)&x; | ||||
|    *vb.dmaptr++ = *(int *)&y; | ||||
|    *vb.dmaptr++ = 0; | ||||
|  | ||||
|    for (i = 3; i < vb.vertex_size; i++) | ||||
|       *vb.dmaptr++ = vb.vertex[i].i; | ||||
|  | ||||
|    if (--vb.counter == 0) | ||||
|       vb.notify(); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Vertex2fv( const GLfloat *v ) | ||||
| { | ||||
|    int i; | ||||
|  | ||||
|    *vb.dmaptr++ = *(int *)&v[0]; | ||||
|    *vb.dmaptr++ = *(int *)&v[1]; | ||||
|    *vb.dmaptr++ = 0; | ||||
|  | ||||
|    for (i = 3; i < vb.vertex_size; i++) | ||||
|       *vb.dmaptr++ = vb.vertex[i].i; | ||||
|     | ||||
|    if (--vb.counter == 0) | ||||
|       vb.notify(); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Color for ubyte (packed) color formats: | ||||
|  */ | ||||
| static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    dest->red	= r; | ||||
|    dest->green	= g; | ||||
|    dest->blue	= b; | ||||
|    dest->alpha	= 0xff; | ||||
| } | ||||
|  | ||||
| static void r200_Color3ubv_ub( const GLubyte *v ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    dest->red	= v[0]; | ||||
|    dest->green	= v[1]; | ||||
|    dest->blue	= v[2]; | ||||
|    dest->alpha	= 0xff; | ||||
| } | ||||
|  | ||||
| static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    dest->red	= r; | ||||
|    dest->green	= g; | ||||
|    dest->blue	= b; | ||||
|    dest->alpha	= a; | ||||
| } | ||||
|  | ||||
| static void r200_Color4ubv_ub( const GLubyte *v ) | ||||
| { | ||||
|    *(GLuint *)vb.colorptr = LE32_TO_CPU(*(GLuint *)v); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,   r ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  b ); | ||||
|    dest->alpha = 255; | ||||
| } | ||||
|  | ||||
| static void r200_Color3fv_ub( const GLfloat *v ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,   v[0] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  v[2] ); | ||||
|    dest->alpha = 255; | ||||
| } | ||||
|  | ||||
| static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,   r ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  b ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); | ||||
| } | ||||
|  | ||||
| static void r200_Color4fv_ub( const GLfloat *v ) | ||||
| { | ||||
|    r200_color_t *dest = vb.colorptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,	  v[0] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  v[2] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Color for float color+alpha formats: | ||||
|  */ | ||||
| static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(r); | ||||
|    dest[1] = UBYTE_TO_FLOAT(g); | ||||
|    dest[2] = UBYTE_TO_FLOAT(b); | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_Color3ubv_4f( const GLubyte *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(v[0]); | ||||
|    dest[1] = UBYTE_TO_FLOAT(v[1]); | ||||
|    dest[2] = UBYTE_TO_FLOAT(v[2]); | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(r); | ||||
|    dest[1] = UBYTE_TO_FLOAT(g); | ||||
|    dest[2] = UBYTE_TO_FLOAT(b); | ||||
|    dest[3] = UBYTE_TO_FLOAT(a); | ||||
| } | ||||
|  | ||||
| static void r200_Color4ubv_4f( const GLubyte *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(v[0]); | ||||
|    dest[1] = UBYTE_TO_FLOAT(v[1]); | ||||
|    dest[2] = UBYTE_TO_FLOAT(v[2]); | ||||
|    dest[3] = UBYTE_TO_FLOAT(v[3]); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = r; | ||||
|    dest[1] = g; | ||||
|    dest[2] = b; | ||||
|    dest[3] = 1.0;		 | ||||
| } | ||||
|  | ||||
| static void r200_Color3fv_4f( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = r; | ||||
|    dest[1] = g; | ||||
|    dest[2] = b; | ||||
|    dest[3] = a; | ||||
| } | ||||
|  | ||||
| static void r200_Color4fv_4f( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
|    dest[3] = v[3]; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Color for float color formats: | ||||
|  */ | ||||
| static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(r); | ||||
|    dest[1] = UBYTE_TO_FLOAT(g); | ||||
|    dest[2] = UBYTE_TO_FLOAT(b); | ||||
| } | ||||
|  | ||||
| static void r200_Color3ubv_3f( const GLubyte *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(v[0]); | ||||
|    dest[1] = UBYTE_TO_FLOAT(v[1]); | ||||
|    dest[2] = UBYTE_TO_FLOAT(v[2]); | ||||
| } | ||||
|  | ||||
| static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(r); | ||||
|    dest[1] = UBYTE_TO_FLOAT(g); | ||||
|    dest[2] = UBYTE_TO_FLOAT(b); | ||||
|    vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); | ||||
| } | ||||
|  | ||||
| static void r200_Color4ubv_3f( const GLubyte *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(v[0]); | ||||
|    dest[1] = UBYTE_TO_FLOAT(v[1]); | ||||
|    dest[2] = UBYTE_TO_FLOAT(v[2]); | ||||
|    vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = r; | ||||
|    dest[1] = g; | ||||
|    dest[2] = b; | ||||
| } | ||||
|  | ||||
| static void r200_Color3fv_3f( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
| } | ||||
|  | ||||
| static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = r; | ||||
|    dest[1] = g; | ||||
|    dest[2] = b; | ||||
|    vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; | ||||
| } | ||||
|  | ||||
| static void r200_Color4fv_3f( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatcolorptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
|    vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];  | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Secondary Color: | ||||
|  */ | ||||
| static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) | ||||
| { | ||||
|    r200_color_t *dest = vb.specptr; | ||||
|    dest->red	= r; | ||||
|    dest->green	= g; | ||||
|    dest->blue	= b; | ||||
|    dest->alpha	= 0xff; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v ) | ||||
| { | ||||
|    r200_color_t *dest = vb.specptr; | ||||
|    dest->red	= v[0]; | ||||
|    dest->green	= v[1]; | ||||
|    dest->blue	= v[2]; | ||||
|    dest->alpha	= 0xff; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) | ||||
| { | ||||
|    r200_color_t *dest = vb.specptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,	  r ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  b ); | ||||
|    dest->alpha = 255; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) | ||||
| { | ||||
|    r200_color_t *dest = vb.specptr; | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->red,	  v[0] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); | ||||
|    UNCLAMPED_FLOAT_TO_UBYTE( dest->blue,  v[2] ); | ||||
|    dest->alpha = 255; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatspecptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(r); | ||||
|    dest[1] = UBYTE_TO_FLOAT(g); | ||||
|    dest[2] = UBYTE_TO_FLOAT(b); | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatspecptr; | ||||
|    dest[0] = UBYTE_TO_FLOAT(v[0]); | ||||
|    dest[1] = UBYTE_TO_FLOAT(v[1]); | ||||
|    dest[2] = UBYTE_TO_FLOAT(v[2]); | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatspecptr; | ||||
|    dest[0] = r; | ||||
|    dest[1] = g; | ||||
|    dest[2] = b; | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
| static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.floatspecptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
|    dest[3] = 1.0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Normal | ||||
|  */ | ||||
| static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) | ||||
| { | ||||
|    GLfloat *dest = vb.normalptr; | ||||
|    dest[0] = n0; | ||||
|    dest[1] = n1; | ||||
|    dest[2] = n2; | ||||
| } | ||||
|  | ||||
| static void r200_Normal3fv( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.normalptr; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
|    dest[2] = v[2]; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* TexCoord | ||||
|  */ | ||||
| static void r200_TexCoord1f( GLfloat s ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[0]; | ||||
|    dest[0] = s; | ||||
|    dest[1] = 0; | ||||
| } | ||||
|  | ||||
| static void r200_TexCoord1fv( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[0]; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = 0; | ||||
| } | ||||
|  | ||||
| static void r200_TexCoord2f( GLfloat s, GLfloat t ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[0]; | ||||
|    dest[0] = s; | ||||
|    dest[1] = t; | ||||
| } | ||||
|  | ||||
| static void r200_TexCoord2fv( const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[0]; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* MultiTexcoord | ||||
|  */ | ||||
| static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s  ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; | ||||
|    dest[0] = s; | ||||
|    dest[1] = 0; | ||||
| } | ||||
|  | ||||
| static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = 0; | ||||
| } | ||||
|  | ||||
| static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; | ||||
|    dest[0] = s; | ||||
|    dest[1] = t; | ||||
| } | ||||
|  | ||||
| static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) | ||||
| { | ||||
|    GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; | ||||
|    dest[0] = v[0]; | ||||
|    dest[1] = v[1]; | ||||
| } | ||||
|  | ||||
| static struct dynfn *lookup( struct dynfn *l, const int *key ) | ||||
| { | ||||
|    struct dynfn *f; | ||||
|  | ||||
|    foreach( f, l ) { | ||||
|       if (f->key[0] == key[0] && f->key[1] == key[1])  | ||||
| 	 return f; | ||||
|    } | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
| /* Can't use the loopback template for this: | ||||
|  */ | ||||
|  | ||||
| #define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 )			\ | ||||
| static void choose_##FN ARGS1						\ | ||||
| {									\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(vb.context);			\ | ||||
|    int key[2];								\ | ||||
|    struct dynfn *dfn;							\ | ||||
| 									\ | ||||
|    key[0] = rmesa->vb.vtxfmt_0 & MASK0;				\ | ||||
|    key[1] = rmesa->vb.vtxfmt_1 & MASK1;				\ | ||||
| 									\ | ||||
|    dfn = lookup( &rmesa->vb.dfn_cache.FN, key );			\ | ||||
|    if (dfn == 0)							\ | ||||
|       dfn = rmesa->vb.codegen.FN( vb.context, key );			\ | ||||
|    else if (R200_DEBUG & DEBUG_CODEGEN)					\ | ||||
|       fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ );		\ | ||||
| 									\ | ||||
|    if (dfn)								\ | ||||
|       vb.context->Exec->FN = (FNTYPE)(dfn->code);			\ | ||||
|    else {								\ | ||||
|       if (R200_DEBUG & DEBUG_CODEGEN)					\ | ||||
| 	 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ );	\ | ||||
|       vb.context->Exec->FN = r200_##FN;					\ | ||||
|    }									\ | ||||
| 									\ | ||||
|    vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;		\ | ||||
|    vb.context->Exec->FN ARGS2;						\ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* For the _3f case, only allow one color function to be hooked in at | ||||
|  * a time.  Eventually, use a similar mechanism to allow selecting the | ||||
|  * color component of the vertex format based on client behaviour.   | ||||
|  * | ||||
|  * Note:  Perform these actions even if there is a codegen or cached  | ||||
|  * codegen version of the chosen function. | ||||
|  */ | ||||
| #define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 )	\ | ||||
| static void choose_##FN ARGS1						\ | ||||
| {									\ | ||||
|    GLcontext *ctx = vb.context;						\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(vb.context);			\ | ||||
|    int key[2];								\ | ||||
|    struct dynfn *dfn;							\ | ||||
| 									\ | ||||
|    key[0] = rmesa->vb.vtxfmt_0 & MASK0;					\ | ||||
|    key[1] = rmesa->vb.vtxfmt_1 & MASK1;					\ | ||||
| 									\ | ||||
|    if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) {		\ | ||||
|       ctx->Exec->FN = r200_##FN##_ub;					\ | ||||
|    }									\ | ||||
|    else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) {	\ | ||||
| 									\ | ||||
|       if (rmesa->vb.installed_color_3f_sz != NR) {			\ | ||||
|          rmesa->vb.installed_color_3f_sz = NR;				\ | ||||
|          if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0;	\ | ||||
|          if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) {		\ | ||||
|             r200_copy_to_current( ctx );				\ | ||||
|             _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );	\ | ||||
|             ctx->Exec->FN ARGS2;					\ | ||||
|             return;							\ | ||||
|          }								\ | ||||
|       }									\ | ||||
| 									\ | ||||
|       ctx->Exec->FN = r200_##FN##_3f;					\ | ||||
|    }									\ | ||||
|    else {								\ | ||||
|       ctx->Exec->FN = r200_##FN##_4f;					\ | ||||
|    }									\ | ||||
| 									\ | ||||
| 									\ | ||||
|    dfn = lookup( &rmesa->vb.dfn_cache.FN, key );			\ | ||||
|    if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key );			\ | ||||
| 									\ | ||||
|    if (dfn) {								\ | ||||
|       if (R200_DEBUG & DEBUG_CODEGEN)					\ | ||||
|          fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ );	\ | ||||
|       ctx->Exec->FN = (FNTYPE)dfn->code;				\ | ||||
|    }									\ | ||||
|    else if (R200_DEBUG & DEBUG_CODEGEN)					\ | ||||
|          fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ );		\ | ||||
| 									\ | ||||
|    ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;			\ | ||||
|    ctx->Exec->FN ARGS2;							\ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Right now there are both _ub and _3f versions of the secondary color | ||||
|  * functions.  Currently, we only set-up the hardware to use the _ub versions. | ||||
|  * The _3f versions are needed for the cases where secondary color isn't used | ||||
|  * in the vertex format, but it still needs to be stored in the context | ||||
|  * state vector. | ||||
|  */ | ||||
| #define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 )	\ | ||||
| static void choose_##FN ARGS1						\ | ||||
| {									\ | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(vb.context);			\ | ||||
|    int key[2];								\ | ||||
|    struct dynfn *dfn;							\ | ||||
| 									\ | ||||
|    key[0] = rmesa->vb.vtxfmt_0 & MASK0;					\ | ||||
|    key[1] = rmesa->vb.vtxfmt_1 & MASK1;					\ | ||||
| 									\ | ||||
|    dfn = lookup( &rmesa->vb.dfn_cache.FN, key );			\ | ||||
|    if (dfn == 0)							\ | ||||
|       dfn = rmesa->vb.codegen.FN( vb.context, key );			\ | ||||
|    else  if (R200_DEBUG & DEBUG_CODEGEN)				\ | ||||
|       fprintf(stderr, "%s -- cached version\n", __FUNCTION__ );		\ | ||||
| 									\ | ||||
|    if (dfn)								\ | ||||
|       vb.context->Exec->FN = (FNTYPE)(dfn->code);			\ | ||||
|    else {								\ | ||||
|       if (R200_DEBUG & DEBUG_CODEGEN)					\ | ||||
|          fprintf(stderr, "%s -- generic version\n", __FUNCTION__ );	\ | ||||
|       vb.context->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \ | ||||
| 	  ? r200_##FN##_ub : r200_##FN##_3f;				\ | ||||
|    }									\ | ||||
| 									\ | ||||
|    vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;		\ | ||||
|    vb.context->Exec->FN ARGS2;						\ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* VTXFMT_0 | ||||
|  */ | ||||
| #define MASK_XYZW  (R200_VTX_W0|R200_VTX_Z0) | ||||
| #define MASK_NORM  (MASK_XYZW|R200_VTX_N0) | ||||
| #define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT)) | ||||
| #define MASK_SPEC  (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT)) | ||||
|  | ||||
| /* VTXFMT_1 | ||||
|  */ | ||||
| #define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT) | ||||
|  | ||||
|  | ||||
|  | ||||
| typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); | ||||
| typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); | ||||
| typedef void (*p2f)( GLfloat, GLfloat ); | ||||
| typedef void (*p1f)( GLfloat ); | ||||
| typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); | ||||
| typedef void (*pe1f)( GLenum, GLfloat ); | ||||
| typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); | ||||
| typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); | ||||
| typedef void (*pfv)( const GLfloat * ); | ||||
| typedef void (*pefv)( GLenum, const GLfloat * ); | ||||
| typedef void (*pubv)( const GLubyte * ); | ||||
|  | ||||
|  | ||||
| CHOOSE(Normal3f, p3f, MASK_NORM, 0,  | ||||
|        (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) | ||||
| CHOOSE(Normal3fv, pfv, MASK_NORM, 0,  | ||||
|        (const GLfloat *v), (v)) | ||||
|  | ||||
| CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0, | ||||
| 	(GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) | ||||
| CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0,  | ||||
| 	(const GLubyte *v), (v)) | ||||
| CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0,  | ||||
| 	(GLubyte a,GLubyte b, GLubyte c), (a,b,c)) | ||||
| CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0,  | ||||
| 	(const GLubyte *v), (v)) | ||||
|  | ||||
| CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0,  | ||||
| 	(GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) | ||||
| CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0,  | ||||
| 	(const GLfloat *v), (v)) | ||||
| CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0, | ||||
| 	(GLfloat a,GLfloat b, GLfloat c), (a,b,c)) | ||||
| CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0, | ||||
| 	(const GLfloat *v), (v)) | ||||
|  | ||||
|  | ||||
| CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0,  | ||||
| 	(GLubyte a,GLubyte b, GLubyte c), (a,b,c)) | ||||
| CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0,  | ||||
| 	(const GLubyte *v), (v)) | ||||
| CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0, | ||||
| 	(GLfloat a,GLfloat b, GLfloat c), (a,b,c)) | ||||
| CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0, | ||||
| 	(const GLfloat *v), (v)) | ||||
|  | ||||
| CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0,  | ||||
|        (GLfloat a,GLfloat b), (a,b)) | ||||
| CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0,  | ||||
|        (const GLfloat *v), (v)) | ||||
| CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0,  | ||||
|        (GLfloat a), (a)) | ||||
| CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0,  | ||||
|        (const GLfloat *v), (v)) | ||||
|  | ||||
| CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0, | ||||
| 	 (GLenum u,GLfloat a,GLfloat b), (u,a,b)) | ||||
| CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0, | ||||
| 	(GLenum u,const GLfloat *v), (u,v)) | ||||
| CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0, | ||||
| 	 (GLenum u,GLfloat a), (u,a)) | ||||
| CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0, | ||||
| 	(GLenum u,const GLfloat *v), (u,v)) | ||||
|  | ||||
| CHOOSE(Vertex3f, p3f, ~0, ~0,  | ||||
|        (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) | ||||
| CHOOSE(Vertex3fv, pfv, ~0, ~0,  | ||||
|        (const GLfloat *v), (v)) | ||||
| CHOOSE(Vertex2f, p2f, ~0, ~0,  | ||||
|        (GLfloat a,GLfloat b), (a,b)) | ||||
| CHOOSE(Vertex2fv, pfv, ~0, ~0,  | ||||
|        (const GLfloat *v), (v)) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void r200VtxfmtInitChoosers( GLvertexformat *vfmt ) | ||||
| { | ||||
|    vfmt->Color3f = choose_Color3f; | ||||
|    vfmt->Color3fv = choose_Color3fv; | ||||
|    vfmt->Color3ub = choose_Color3ub; | ||||
|    vfmt->Color3ubv = choose_Color3ubv; | ||||
|    vfmt->Color4f = choose_Color4f; | ||||
|    vfmt->Color4fv = choose_Color4fv; | ||||
|    vfmt->Color4ub = choose_Color4ub; | ||||
|    vfmt->Color4ubv = choose_Color4ubv; | ||||
|    vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; | ||||
|    vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; | ||||
|    vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; | ||||
|    vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; | ||||
|    vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; | ||||
|    vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; | ||||
|    vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; | ||||
|    vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; | ||||
|    vfmt->Normal3f = choose_Normal3f; | ||||
|    vfmt->Normal3fv = choose_Normal3fv; | ||||
|    vfmt->TexCoord1f = choose_TexCoord1f; | ||||
|    vfmt->TexCoord1fv = choose_TexCoord1fv; | ||||
|    vfmt->TexCoord2f = choose_TexCoord2f; | ||||
|    vfmt->TexCoord2fv = choose_TexCoord2fv; | ||||
|    vfmt->Vertex2f = choose_Vertex2f; | ||||
|    vfmt->Vertex2fv = choose_Vertex2fv; | ||||
|    vfmt->Vertex3f = choose_Vertex3f; | ||||
|    vfmt->Vertex3fv = choose_Vertex3fv; | ||||
| } | ||||
|  | ||||
|  | ||||
| static struct dynfn *codegen_noop( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    (void) ctx; (void) key; | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
| void r200InitCodegen( struct dfn_generators *gen ) | ||||
| { | ||||
|    gen->Vertex3f = codegen_noop; | ||||
|    gen->Vertex3fv = codegen_noop; | ||||
|    gen->Color4ub = codegen_noop; | ||||
|    gen->Color4ubv = codegen_noop; | ||||
|    gen->Normal3f = codegen_noop; | ||||
|    gen->Normal3fv = codegen_noop; | ||||
|    gen->TexCoord2f = codegen_noop; | ||||
|    gen->TexCoord2fv = codegen_noop; | ||||
|    gen->MultiTexCoord2fARB = codegen_noop; | ||||
|    gen->MultiTexCoord2fvARB = codegen_noop; | ||||
|    gen->Vertex2f = codegen_noop; | ||||
|    gen->Vertex2fv = codegen_noop; | ||||
|    gen->Color3ub = codegen_noop; | ||||
|    gen->Color3ubv = codegen_noop; | ||||
|    gen->Color4f = codegen_noop; | ||||
|    gen->Color4fv = codegen_noop; | ||||
|    gen->Color3f = codegen_noop; | ||||
|    gen->Color3fv = codegen_noop; | ||||
|    gen->SecondaryColor3fEXT = codegen_noop; | ||||
|    gen->SecondaryColor3fvEXT = codegen_noop; | ||||
|    gen->SecondaryColor3ubEXT = codegen_noop; | ||||
|    gen->SecondaryColor3ubvEXT = codegen_noop; | ||||
|    gen->TexCoord1f = codegen_noop; | ||||
|    gen->TexCoord1fv = codegen_noop; | ||||
|    gen->MultiTexCoord1fARB = codegen_noop; | ||||
|    gen->MultiTexCoord1fvARB = codegen_noop; | ||||
|  | ||||
|    if (!getenv("R200_NO_CODEGEN")) { | ||||
| #if defined(USE_X86_ASM) | ||||
|       r200InitX86Codegen( gen ); | ||||
| #endif | ||||
|  | ||||
| #if defined(USE_SSE_ASM) | ||||
|       r200InitSSECodegen( gen ); | ||||
| #endif | ||||
|    } | ||||
| } | ||||
							
								
								
									
										95
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "simple_list.h"  | ||||
| #include "r200_vtxfmt.h" | ||||
|  | ||||
| #if defined(USE_SSE_ASM) | ||||
|  | ||||
| /* Build specialized versions of the immediate calls on the fly for | ||||
|  * the current state.  ???P4 SSE2 versions??? | ||||
|  */ | ||||
|  | ||||
|  | ||||
| static struct dynfn *makeSSENormal3fv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    /* Requires P4 (sse2?) | ||||
|     */ | ||||
|    static unsigned char temp[] = { | ||||
|       0x8b, 0x44, 0x24, 0x04,          	/*  mov    0x4(%esp,1),%eax */ | ||||
|       0xba, 0x78, 0x56, 0x34, 0x12,   	/*  mov    $0x12345678,%edx */ | ||||
|       0xf3, 0x0f, 0x7e, 0x00,          	/*  movq   (%eax),%xmm0 */ | ||||
|       0x66, 0x0f, 0x6e, 0x48, 0x08,    	/*  movd   0x8(%eax),%xmm1 */ | ||||
|       0x66, 0x0f, 0xd6, 0x42, 0x0c,    	/*  movq   %xmm0,0xc(%edx) */ | ||||
|       0x66, 0x0f, 0x7e, 0x4a, 0x14,    	/*  movd   %xmm1,0x14(%edx) */ | ||||
|       0xc3,                   	        /*  ret     */ | ||||
|    }; | ||||
|  | ||||
|  | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); | ||||
|    dfn->key[0] = key[0]; | ||||
|    dfn->key[1] = key[1]; | ||||
|  | ||||
|    dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); | ||||
|    memcpy (dfn->code, temp, sizeof(temp)); | ||||
|    FIXUP(dfn->code, 5, 0x0, (int)vb.normalptr);  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| void r200InitSSECodegen( struct dfn_generators *gen ) | ||||
| { | ||||
|    /* Need to:  | ||||
|     *    - check kernel sse support | ||||
|     *    - check p4/sse2 | ||||
|     */ | ||||
|    (void) makeSSENormal3fv; | ||||
| } | ||||
|  | ||||
|  | ||||
| #else  | ||||
|  | ||||
| void r200InitSSECodegen( struct dfn_generators *gen ) | ||||
| { | ||||
|    (void) gen; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										462
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										462
									
								
								src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,462 @@ | ||||
| /* $XFree86$ */ | ||||
| /* | ||||
| Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved. | ||||
|  | ||||
| The Weather Channel (TM) funded Tungsten Graphics to develop the | ||||
| initial release of the Radeon 8500 driver under the XFree86 license. | ||||
| This notice must be preserved. | ||||
|  | ||||
| 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 (including the | ||||
| next paragraph) shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||||
| IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Authors: | ||||
|  *   Keith Whitwell <keith@tungstengraphics.com> | ||||
|  */ | ||||
|  | ||||
| #include "glheader.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h"  | ||||
| #include "simple_list.h"  | ||||
| #include "r200_vtxfmt.h" | ||||
|  | ||||
| #if defined(USE_X86_ASM) | ||||
|  | ||||
| #define EXTERN( FUNC )		\ | ||||
| extern const char *FUNC;	\ | ||||
| extern const char *FUNC##_end | ||||
|  | ||||
| EXTERN ( _x86_Normal3fv ); | ||||
| EXTERN ( _x86_Normal3f ); | ||||
| EXTERN ( _x86_Vertex3fv_6 ); | ||||
| EXTERN ( _x86_Vertex3fv_8 ); | ||||
| EXTERN ( _x86_Vertex3fv ); | ||||
| EXTERN ( _x86_Vertex3f_4 ); | ||||
| EXTERN ( _x86_Vertex3f_6 ); | ||||
| EXTERN ( _x86_Vertex3f ); | ||||
| EXTERN ( _x86_Color4ubv_ub ); | ||||
| EXTERN ( _x86_Color4ubv_4f ); | ||||
| EXTERN ( _x86_Color4ub_ub ); | ||||
| EXTERN ( _x86_Color3fv_3f ); | ||||
| EXTERN ( _x86_Color3f_3f ); | ||||
| EXTERN ( _x86_TexCoord2fv ); | ||||
| EXTERN ( _x86_TexCoord2f ); | ||||
| EXTERN ( _x86_MultiTexCoord2fvARB ); | ||||
| EXTERN ( _x86_MultiTexCoord2fvARB_2 ); | ||||
| EXTERN ( _x86_MultiTexCoord2fARB ); | ||||
| EXTERN ( _x86_MultiTexCoord2fARB_2 ); | ||||
|  | ||||
|  | ||||
| /* Build specialized versions of the immediate calls on the fly for | ||||
|  * the current state.  Generic x86 versions. | ||||
|  */ | ||||
|  | ||||
| struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,  | ||||
| 	      key[0], key[1], vb.vertex_size ); | ||||
|  | ||||
|    switch (vb.vertex_size) { | ||||
|    case 4: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); | ||||
|       FIXUP(dfn->code, 2, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 25, 0x0, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 36, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 46, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 51, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 60, 0x0, (int)&vb.notify); | ||||
|       break; | ||||
|    } | ||||
|    case 6: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); | ||||
|       FIXUP(dfn->code, 3, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 28, 0x0, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 34, 0x0, (int)&vb.vertex[4]); | ||||
|       FIXUP(dfn->code, 40, 0x0, (int)&vb.vertex[5]); | ||||
|       FIXUP(dfn->code, 57, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 63, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 70, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 79, 0x0, (int)&vb.notify); | ||||
|       break; | ||||
|    } | ||||
|    default: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); | ||||
|       FIXUP(dfn->code, 3, 0x0, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 9, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 37, 0x0, vb.vertex_size-3); | ||||
|       FIXUP(dfn->code, 44, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 50, 0x0, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 56, 0x0, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); | ||||
|    break; | ||||
|    } | ||||
|    } | ||||
|  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,  | ||||
| 	      key[0], key[1], vb.vertex_size ); | ||||
|  | ||||
|    switch (vb.vertex_size) { | ||||
|    case 6: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); | ||||
|       FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); | ||||
|       FIXUP(dfn->code, 45, 0x00000024, (int)&vb.vertex[5]); | ||||
|       FIXUP(dfn->code, 56, 0x00000000, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 61, 0x00000004, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 67, 0x00000004, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 76, 0x00000008, (int)&vb.notify); | ||||
|       break; | ||||
|    } | ||||
|     | ||||
|  | ||||
|    case 8: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); | ||||
|       FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); | ||||
|       FIXUP(dfn->code, 45, 0x0000001c, (int)&vb.vertex[5]); | ||||
|       FIXUP(dfn->code, 51, 0x00000020, (int)&vb.vertex[6]); | ||||
|       FIXUP(dfn->code, 63, 0x00000024, (int)&vb.vertex[7]); | ||||
|       FIXUP(dfn->code, 74, 0x00000000, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 79, 0x00000004, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 85, 0x00000004, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 94, 0x00000008, (int)&vb.notify); | ||||
|       break; | ||||
|    } | ||||
|     | ||||
|  | ||||
|  | ||||
|    default: { | ||||
|  | ||||
|       DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); | ||||
|       FIXUP(dfn->code, 8, 0x01010101, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 32, 0x00000006, vb.vertex_size-3); | ||||
|       FIXUP(dfn->code, 37, 0x00000058, (int)&vb.vertex[3]); | ||||
|       FIXUP(dfn->code, 45, 0x01010101, (int)&vb.dmaptr); | ||||
|       FIXUP(dfn->code, 50, 0x02020202, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 58, 0x02020202, (int)&vb.counter); | ||||
|       FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); | ||||
|    break; | ||||
|    } | ||||
|    } | ||||
|  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|    int i = 0; | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|    DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); | ||||
|  | ||||
|    FIXUP2(dfn->code, i, 0x0, (int)vb.normalptr);  | ||||
|    FIXUP2(dfn->code, i, 0x4, 4+(int)vb.normalptr);  | ||||
|    FIXUP2(dfn->code, i, 0x8, 8+(int)vb.normalptr);  | ||||
|    /*fprintf(stderr, "%s done\n", __FUNCTION__);*/ | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|    DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f ); | ||||
|    FIXUP(dfn->code, 1, 0x12345678, (int)vb.normalptr);  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|    if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { | ||||
|       DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); | ||||
|       FIXUP(dfn->code, 5, 0x12345678, (int)vb.colorptr);  | ||||
|       return dfn; | ||||
|    }  | ||||
|    else { | ||||
|  | ||||
|       DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); | ||||
|       FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);  | ||||
|       FIXUP(dfn->code, 27, 0xdeadbeaf, (int)vb.floatcolorptr);  | ||||
|       FIXUP(dfn->code, 33, 0xdeadbeaf, (int)vb.floatcolorptr+4);  | ||||
|       FIXUP(dfn->code, 55, 0xdeadbeaf, (int)vb.floatcolorptr+8);  | ||||
|       FIXUP(dfn->code, 61, 0xdeadbeaf, (int)vb.floatcolorptr+12);  | ||||
|       return dfn; | ||||
|    } | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|    if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { | ||||
|       struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|       r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|       DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); | ||||
|       FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr);  | ||||
|       FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1);  | ||||
|       FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2);  | ||||
|       FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3);  | ||||
|       return dfn; | ||||
|    } | ||||
|    else | ||||
|       return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)  | ||||
|       return 0; | ||||
|    else | ||||
|    { | ||||
|       struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|       r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_CODEGEN) | ||||
| 	 fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|       DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv ); | ||||
|       FIXUP(dfn->code, 5, 0x0, (int)vb.floatcolorptr);  | ||||
|       return dfn; | ||||
|    } | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|    if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)  | ||||
|       return 0; | ||||
|    else | ||||
|    { | ||||
|       struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|       r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|       if (R200_DEBUG & DEBUG_CODEGEN) | ||||
| 	 fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); | ||||
|  | ||||
|       DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); | ||||
|       FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr);  | ||||
|       return dfn; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|  | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); | ||||
|  | ||||
|    DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv ); | ||||
|    FIXUP(dfn->code, 5, 0x12345678, (int)vb.texcoordptr[0]);  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) | ||||
| { | ||||
|  | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); | ||||
|  | ||||
|    DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f ); | ||||
|    FIXUP(dfn->code, 1, 0x12345678, (int)vb.texcoordptr[0]);  | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) | ||||
| { | ||||
| #if 0 | ||||
|    static  char temp[] = { | ||||
|       0x8b, 0x44, 0x24, 0x04,          	/* mov    0x4(%esp,1),%eax */ | ||||
|       0x8b, 0x4c, 0x24, 0x08,          	/* mov    0x8(%esp,1),%ecx */ | ||||
|       0x2d, 0xc0, 0x84, 0x00, 0x00,    	/* sub    $0x84c0,%eax */ | ||||
|       0x83, 0xe0, 0x01,             	/* and    $0x1,%eax */ | ||||
|       0x8b, 0x11,                	/* mov    (%ecx),%edx */ | ||||
|       0xc1, 0xe0, 0x03,             	/* shl    $0x3,%eax */ | ||||
|       0x8b, 0x49, 0x04,             	/* mov    0x4(%ecx),%ecx */ | ||||
|       0x89, 0x90, 0, 0, 0, 0,/* mov    %edx,DEST(%eax) */ | ||||
|       0x89, 0x88, 0, 0, 0, 0,/* mov    %ecx,DEST+8(%eax) */ | ||||
|       0xc3,                     	/* ret     */ | ||||
|    }; | ||||
|    static char temp2[] = { | ||||
|       0x8b, 0x44, 0x24, 0x04,          	/* mov    0x4(%esp,1),%eax */ | ||||
|       0x8b, 0x4c, 0x24, 0x08,          	/* mov    0x8(%esp,1),%ecx */ | ||||
|       0x2d, 0xc0, 0x84, 0x00, 0x00,    	/* sub    $0x84c0,%eax */ | ||||
|       0x83, 0xe0, 0x01,             	/* and    $0x1,%eax */ | ||||
|       0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov    DEST(,%eax,4),%edx */ | ||||
|       0x8b, 0x01,                	/* mov    (%ecx),%eax */ | ||||
|       0x89, 0x02,                	/* mov    %eax,(%edx) */ | ||||
|       0x8b, 0x41, 0x04,             	/* mov    0x4(%ecx),%eax */ | ||||
|       0x89, 0x42, 0x04,             	/* mov    %eax,0x4(%edx) */ | ||||
|       0xc3,                     	/* ret     */ | ||||
|    }; | ||||
| #endif | ||||
|  | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); | ||||
|  | ||||
|    if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { | ||||
|       DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); | ||||
|       FIXUP(dfn->code, 26, 0xdeadbeef, (int)vb.texcoordptr[0]);	 | ||||
|       FIXUP(dfn->code, 32, 0xdeadbeef, (int)vb.texcoordptr[0]+4); | ||||
|    } else { | ||||
|       DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); | ||||
|       FIXUP(dfn->code, 19, 0x0, (int)vb.texcoordptr); | ||||
|    } | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
| struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx,  | ||||
| 					      const int *key ) | ||||
| { | ||||
| #if 0 | ||||
|    static  char temp[] = { | ||||
|       0x8b, 0x44, 0x24, 0x04,          	/* mov    0x4(%esp,1),%eax */ | ||||
|       0x8b, 0x54, 0x24, 0x08,          	/* mov    0x8(%esp,1),%edx */ | ||||
|       0x2d, 0xc0, 0x84, 0x00, 0x00,    	/* sub    $0x84c0,%eax */ | ||||
|       0x8b, 0x4c, 0x24, 0x0c,          	/* mov    0xc(%esp,1),%ecx */ | ||||
|       0x83, 0xe0, 0x01,             	/* and    $0x1,%eax */ | ||||
|       0xc1, 0xe0, 0x03,             	/* shl    $0x3,%eax */ | ||||
|       0x89, 0x90, 0, 0, 0, 0,	/* mov    %edx,DEST(%eax) */ | ||||
|       0x89, 0x88, 0, 0, 0, 0,	/* mov    %ecx,DEST+8(%eax) */ | ||||
|       0xc3,                     	/* ret     */ | ||||
|    }; | ||||
|  | ||||
|    static char temp2[] = { | ||||
|       0x8b, 0x44, 0x24, 0x04,          	/* mov    0x4(%esp,1),%eax */ | ||||
|       0x8b, 0x54, 0x24, 0x08,          	/* mov    0x8(%esp,1),%edx */ | ||||
|       0x2d, 0xc0, 0x84, 0x00, 0x00,    	/* sub    $0x84c0,%eax */ | ||||
|       0x8b, 0x4c, 0x24, 0x0c,          	/* mov    0xc(%esp,1),%ecx */ | ||||
|       0x83, 0xe0, 0x01,             	/* and    $0x1,%eax */ | ||||
|       0x8b, 0x04, 0x85, 0, 0, 0, 0,     /* mov    DEST(,%eax,4),%eax */ | ||||
|       0x89, 0x10,                	/* mov    %edx,(%eax) */ | ||||
|       0x89, 0x48, 0x04,             	/* mov    %ecx,0x4(%eax) */ | ||||
|       0xc3,                   	        /* ret     */ | ||||
|    }; | ||||
| #endif | ||||
|    struct dynfn *dfn = MALLOC_STRUCT( dynfn ); | ||||
|    r200ContextPtr rmesa = R200_CONTEXT(ctx); | ||||
|  | ||||
|    if (R200_DEBUG & DEBUG_CODEGEN) | ||||
|       fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); | ||||
|  | ||||
|    if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { | ||||
|       DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); | ||||
|       FIXUP(dfn->code, 25, 0xdeadbeef, (int)vb.texcoordptr[0]);  | ||||
|       FIXUP(dfn->code, 31, 0xdeadbeef, (int)vb.texcoordptr[0]+4);  | ||||
|    } | ||||
|    else { | ||||
|       /* Note: this might get generated multiple times, even though the | ||||
|        * actual emitted code is the same. | ||||
|        */ | ||||
|       DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); | ||||
|       FIXUP(dfn->code, 23, 0x0, (int)vb.texcoordptr);  | ||||
|    }       | ||||
|    return dfn; | ||||
| } | ||||
|  | ||||
|  | ||||
| void r200InitX86Codegen( struct dfn_generators *gen ) | ||||
| { | ||||
|    gen->Vertex3f = r200_makeX86Vertex3f; | ||||
|    gen->Vertex3fv = r200_makeX86Vertex3fv; | ||||
|    gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */ | ||||
|    gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */ | ||||
|    gen->Normal3f = r200_makeX86Normal3f; | ||||
|    gen->Normal3fv = r200_makeX86Normal3fv; | ||||
|    gen->TexCoord2f = r200_makeX86TexCoord2f; | ||||
|    gen->TexCoord2fv = r200_makeX86TexCoord2fv; | ||||
|    gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB; | ||||
|    gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB; | ||||
|    gen->Color3f = r200_makeX86Color3f; | ||||
|    gen->Color3fv = r200_makeX86Color3fv; | ||||
|  | ||||
|    /* Not done: | ||||
|     */ | ||||
| /*     gen->Vertex2f = r200_makeX86Vertex2f; */ | ||||
| /*     gen->Vertex2fv = r200_makeX86Vertex2fv; */ | ||||
| /*     gen->Color3ub = r200_makeX86Color3ub; */ | ||||
| /*     gen->Color3ubv = r200_makeX86Color3ubv; */ | ||||
| /*     gen->Color4f = r200_makeX86Color4f; */ | ||||
| /*     gen->Color4fv = r200_makeX86Color4fv; */ | ||||
| /*     gen->TexCoord1f = r200_makeX86TexCoord1f; */ | ||||
| /*     gen->TexCoord1fv = r200_makeX86TexCoord1fv; */ | ||||
| /*     gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */ | ||||
| /*     gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */ | ||||
| } | ||||
|  | ||||
|  | ||||
| #else  | ||||
|  | ||||
| void r200InitX86Codegen( struct dfn_generators *gen ) | ||||
| { | ||||
|    (void) gen; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										410
									
								
								src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,410 @@ | ||||
| /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ | ||||
| /************************************************************************** | ||||
|  | ||||
| Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. | ||||
|  | ||||
| All Rights Reserved. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a | ||||
| copy of this software and associated documentation files (the "Software"), | ||||
| to deal in the Software without restriction, including without limitation | ||||
| on the rights to use, copy, modify, merge, publish, distribute, sub | ||||
| license, and/or sell copies of the Software, and to permit persons to whom | ||||
| the Software is furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice (including the next | ||||
| paragraph) shall be included in all copies or substantial portions of the | ||||
| Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||||
| ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||||
| DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||||
| OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||||
| USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
| **************************************************************************/ | ||||
|  | ||||
| #define GLOBL( x )	\ | ||||
| .globl x;		\ | ||||
| x: | ||||
|  | ||||
| .data | ||||
| .align 4 | ||||
| GLOBL( _x86_Normal3fv) | ||||
| 	movl 4(%esp), %eax      /* load 'v' off stack */ | ||||
| 	movl (%eax), %ecx       /* load v[0] */ | ||||
| 	movl 4(%eax), %edx      /* load v[1] */ | ||||
| 	movl 8(%eax), %eax      /* load v[2] */ | ||||
| 	movl %ecx, 0      	/* store v[0] to current vertex */ | ||||
| 	movl %edx, 4      	/* store v[1] to current vertex */ | ||||
| 	movl %eax, 8      	/* store v[2] to current vertex */ | ||||
| 	ret | ||||
| GLOBL ( _x86_Normal3fv_end ) | ||||
|  | ||||
| /* | ||||
| 	vertex 3f vertex size 4 | ||||
| */ | ||||
| 	 | ||||
| GLOBL ( _x86_Vertex3f_4 ) | ||||
| 	movl	(0), %ecx | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	8(%esp), %edx | ||||
| 	movl	%eax, (%ecx) | ||||
| 	movl	%edx, 4(%ecx) | ||||
| 	movl	12(%esp), %eax | ||||
| 	movl	(0), %edx | ||||
| 	movl	%eax, 8(%ecx) | ||||
| 	movl	%edx, 12(%ecx) | ||||
| 	movl	(0), %eax | ||||
| 	addl	$16, %ecx | ||||
| 	dec 	%eax | ||||
| 	movl	%ecx, (0) | ||||
| 	movl	%eax, (0) | ||||
| 	je	.1  | ||||
| 	ret | ||||
| .1:	jmp	*0 | ||||
| 	 | ||||
| GLOBL ( _x86_Vertex3f_4_end ) | ||||
|  | ||||
| /* | ||||
| 	vertex 3f vertex size 6 | ||||
| */ | ||||
| GLOBL ( _x86_Vertex3f_6 ) | ||||
| 	push	%edi | ||||
| 	movl	(0), %edi | ||||
| 	movl	8(%esp), %eax | ||||
| 	movl	12(%esp), %edx | ||||
| 	movl	16(%esp), %ecx | ||||
| 	movl	%eax, (%edi) | ||||
| 	movl	%edx, 4(%edi) | ||||
| 	movl	%ecx, 8(%edi) | ||||
| 	movl	(0), %eax | ||||
| 	movl	(0), %edx | ||||
| 	movl	(0), %ecx | ||||
| 	movl	%eax, 12(%edi) | ||||
| 	movl	%edx, 16(%edi) | ||||
| 	movl	%ecx, 20(%edi) | ||||
| 	addl	$24, %edi | ||||
| 	movl	(0), %eax | ||||
| 	movl	%edi, (0) | ||||
| 	dec 	%eax | ||||
| 	pop 	%edi | ||||
| 	movl	%eax, (0) | ||||
| 	je	.2 | ||||
| 	ret | ||||
| .2:	jmp	*0 | ||||
| GLOBL ( _x86_Vertex3f_6_end ) | ||||
| /* | ||||
| 	vertex 3f generic size | ||||
| */ | ||||
| GLOBL ( _x86_Vertex3f ) | ||||
| 	push	%edi | ||||
| 	push	%esi | ||||
| 	movl	$0, %esi | ||||
| 	movl	(0), %edi | ||||
| 	movl	12(%esp), %eax | ||||
| 	movl	16(%esp), %edx | ||||
| 	movl	20(%esp), %ecx | ||||
| 	movl	%eax, (%edi) | ||||
| 	movl	%edx, 4(%edi) | ||||
| 	movl	%ecx, 8(%edi) | ||||
| 	addl	$12, %edi | ||||
| 	movl	$0, %ecx | ||||
| 	repz | ||||
| 	movsl %ds:(%esi), %es:(%edi) | ||||
| 	movl	(0), %eax | ||||
| 	movl	%edi, (0) | ||||
| 	dec 	%eax | ||||
| 	movl	%eax, (0) | ||||
| 	pop 	%esi | ||||
| 	pop 	%edi | ||||
| 	je  	.3 | ||||
| 	ret | ||||
| .3:	jmp	*0 | ||||
|  | ||||
| GLOBL ( _x86_Vertex3f_end ) | ||||
|  | ||||
| /* | ||||
| 	Vertex 3fv vertex size 6 | ||||
| */ | ||||
| GLOBL ( _x86_Vertex3fv_6 ) | ||||
| 	movl	(0), %eax | ||||
| 	movl	4(%esp), %ecx | ||||
| 	movl	(%ecx), %edx | ||||
| 	movl	%edx, (%eax) | ||||
| 	movl	4(%ecx), %edx | ||||
| 	movl	8(%ecx), %ecx | ||||
| 	movl	%edx, 4(%eax) | ||||
| 	movl	%ecx, 8(%eax) | ||||
| 	movl	(28), %edx | ||||
| 	movl	(32), %ecx | ||||
| 	movl	%edx, 12(%eax) | ||||
| 	movl	%ecx, 16(%eax) | ||||
| 	movl	(36), %edx | ||||
| 	movl	%edx, 20(%eax) | ||||
| 	addl	$24, %eax | ||||
| 	movl	%eax, 0 | ||||
| 	movl	4, %eax | ||||
| 	dec 	%eax | ||||
| 	movl	%eax, 4 | ||||
| 	je	.4 | ||||
| 	ret | ||||
| .4:	jmp    *8 | ||||
| 	 | ||||
| GLOBL ( _x86_Vertex3fv_6_end ) | ||||
|  | ||||
| /* | ||||
| 	Vertex 3fv vertex size 8 | ||||
| */ | ||||
| GLOBL ( _x86_Vertex3fv_8 ) | ||||
| 	movl	(0), %eax | ||||
| 	movl	4(%esp), %ecx | ||||
| 	movl	(%ecx), %edx | ||||
| 	movl	%edx ,(%eax) | ||||
| 	movl	4(%ecx) ,%edx | ||||
| 	movl	8(%ecx) ,%ecx | ||||
| 	movl	%edx, 4(%eax) | ||||
| 	movl	%ecx, 8(%eax) | ||||
| 	movl	(28), %edx | ||||
| 	movl	(32), %ecx | ||||
| 	movl	%edx, 12(%eax) | ||||
| 	movl	%ecx, 16(%eax) | ||||
| 	movl	(28), %edx | ||||
| 	movl	(32), %ecx | ||||
| 	movl	%edx, 20(%eax) | ||||
| 	movl	%ecx, 24(%eax) | ||||
| 	movl	(36), %edx | ||||
| 	movl	%edx, 28(%eax) | ||||
| 	addl	$32, %eax | ||||
| 	movl	%eax, (0) | ||||
| 	movl	4, %eax | ||||
| 	dec	%eax | ||||
| 	movl    %eax, (4) | ||||
| 	je	.5 | ||||
| 	ret | ||||
| .5:	jmp    *8 | ||||
| 	 | ||||
| GLOBL ( _x86_Vertex3fv_8_end ) | ||||
|  | ||||
| /* | ||||
| 	Vertex 3fv generic vertex size | ||||
| */ | ||||
| GLOBL ( _x86_Vertex3fv ) | ||||
| 	movl	4(%esp), %edx | ||||
| 	push	%edi | ||||
| 	push	%esi | ||||
| 	movl	(0x1010101), %edi | ||||
| 	movl	(%edx), %eax | ||||
| 	movl	4(%edx), %ecx | ||||
| 	movl	8(%edx), %esi | ||||
| 	movl	%eax, (%edi) | ||||
| 	movl	%ecx, 4(%edi) | ||||
| 	movl	%esi, 8(%edi) | ||||
| 	addl	$12, %edi | ||||
| 	movl	$6, %ecx | ||||
| 	movl	$0x58, %esi | ||||
| 	repz | ||||
| 	movsl %ds:(%esi), %es:(%edi) | ||||
| 	movl	%edi, (0x1010101) | ||||
| 	movl	(0x2020202), %eax | ||||
| 	pop	%esi | ||||
| 	pop	%edi | ||||
| 	dec	%eax | ||||
| 	movl	%eax, (0x2020202) | ||||
| 	je	.6 | ||||
| 	ret | ||||
| .6:	jmp    *0 | ||||
| GLOBL ( _x86_Vertex3fv_end ) | ||||
|  | ||||
| /* | ||||
| 	Normal 3f | ||||
| */ | ||||
| GLOBL ( _x86_Normal3f ) | ||||
| 	movl	$0x12345678, %edx | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	%eax, (%edx) | ||||
| 	movl	8(%esp), %eax | ||||
| 	movl	%eax, 4(%edx) | ||||
| 	movl	12(%esp), %eax | ||||
| 	movl	%eax, 8(%edx) | ||||
| 	ret | ||||
| GLOBL ( _x86_Normal3f_end ) | ||||
|  | ||||
| /* | ||||
| 	Color 4ubv_ub | ||||
| */ | ||||
| GLOBL ( _x86_Color4ubv_ub ) | ||||
| 	movl 4(%esp), %eax | ||||
| 	movl $0x12345678, %edx | ||||
| 	movl (%eax), %eax | ||||
| 	movl %eax, (%edx) | ||||
| 	ret | ||||
| GLOBL ( _x86_Color4ubv_ub_end ) | ||||
|  | ||||
| /* | ||||
| 	Color 4ubv 4f | ||||
| */ | ||||
| GLOBL ( _x86_Color4ubv_4f ) | ||||
| 	push	%ebx | ||||
| 	movl	$0, %edx | ||||
| 	xor	%eax, %eax | ||||
| 	xor	%ecx, %ecx | ||||
| 	movl	8(%esp), %ebx | ||||
| 	movl	(%ebx), %ebx | ||||
| 	mov	%bl, %al | ||||
| 	mov	%bh, %cl | ||||
| 	movl	(%edx,%eax,4),%eax | ||||
| 	movl	(%edx,%ecx,4),%ecx | ||||
| 	movl	%eax, (0xdeadbeaf) | ||||
| 	movl	%ecx, (0xdeadbeaf) | ||||
| 	xor	%eax, %eax | ||||
| 	xor	%ecx, %ecx | ||||
| 	shr	$16, %ebx | ||||
| 	mov	%bl, %al | ||||
| 	mov	%bh, %cl | ||||
| 	movl	(%edx,%eax,4), %eax | ||||
| 	movl	(%edx,%ecx,4), %ecx | ||||
| 	movl	%eax, (0xdeadbeaf) | ||||
| 	movl	%ecx, (0xdeadbeaf) | ||||
| 	pop	%ebx | ||||
| 	ret | ||||
| GLOBL ( _x86_Color4ubv_4f_end ) | ||||
|  | ||||
| /* | ||||
|  | ||||
| 	Color4ub_ub | ||||
| */ | ||||
| GLOBL( _x86_Color4ub_ub ) | ||||
| 	push	%ebx | ||||
| 	movl	8(%esp), %eax | ||||
| 	movl	12(%esp), %edx | ||||
| 	movl	16(%esp), %ecx | ||||
| 	movl	20(%esp), %ebx | ||||
| 	mov	%al, (0) | ||||
| 	mov	%dl, (0) | ||||
| 	mov	%cl, (0) | ||||
| 	mov	%bl, (0) | ||||
| 	pop	%ebx | ||||
| 	ret | ||||
| GLOBL( _x86_Color4ub_ub_end ) | ||||
|  | ||||
| /* | ||||
| 	Color3fv_3f | ||||
| */ | ||||
| GLOBL( _x86_Color3fv_3f ) | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	$0, %edx | ||||
| 	movl	(%eax), %ecx | ||||
| 	movl	%ecx, (%edx) | ||||
| 	movl	4(%eax), %ecx | ||||
| 	movl	%ecx, 4(%edx) | ||||
| 	movl	8(%eax), %ecx | ||||
| 	movl	%ecx, 8(%edx) | ||||
| 	ret | ||||
| GLOBL( _x86_Color3fv_3f_end ) | ||||
|  | ||||
| /* | ||||
| 	Color3f_3f | ||||
| */ | ||||
| GLOBL( _x86_Color3f_3f ) | ||||
| 	movl	$0x12345678, %edx | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	%eax, (%edx) | ||||
| 	movl	8(%esp,1), %eax | ||||
| 	movl	%eax, 4(%edx) | ||||
| 	movl	12(%esp), %eax | ||||
| 	movl	%eax, 8(%edx) | ||||
| 	ret | ||||
| GLOBL( _x86_Color3f_3f_end ) | ||||
|  | ||||
| /* | ||||
| 	TexCoord2fv | ||||
| */ | ||||
|  | ||||
| GLOBL( _x86_TexCoord2fv ) | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	$0x12345678, %edx | ||||
| 	movl	(%eax), %ecx | ||||
| 	movl	4(%eax), %eax | ||||
| 	movl	%ecx, (%edx) | ||||
| 	movl	%eax, 4(%edx) | ||||
| 	ret | ||||
|  | ||||
| GLOBL( _x86_TexCoord2fv_end ) | ||||
| /* | ||||
| 	TexCoord2f | ||||
| */ | ||||
| GLOBL( _x86_TexCoord2f ) | ||||
| 	movl	$0x12345678, %edx | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	8(%esp), %ecx | ||||
| 	movl	%eax, (%edx) | ||||
| 	movl	%ecx, 4(%edx) | ||||
| 	ret | ||||
| GLOBL( _x86_TexCoord2f_end ) | ||||
|  | ||||
| /* | ||||
| 	MultiTexCoord2fvARB st0/st1 | ||||
| */ | ||||
| GLOBL( _x86_MultiTexCoord2fvARB ) | ||||
|  | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	8(%esp), %ecx | ||||
| 	sub	$0x84c0, %eax | ||||
| 	and	$1, %eax | ||||
| 	movl	(%ecx), %edx | ||||
| 	shl	$3, %eax | ||||
| 	movl	4(%ecx), %ecx | ||||
| 	movl	%edx, 0xdeadbeef(%eax) | ||||
| 	movl	%ecx, 0xdeadbeef(%eax) | ||||
| 	ret | ||||
| GLOBL( _x86_MultiTexCoord2fvARB_end ) | ||||
| /* | ||||
| 	MultiTexCoord2fvARB | ||||
| */ | ||||
|  | ||||
| GLOBL( _x86_MultiTexCoord2fvARB_2 ) | ||||
| 	movl	4(%esp,1), %eax | ||||
| 	movl	8(%esp,1), %ecx | ||||
| 	sub	$0x84c0, %eax | ||||
| 	and	$0x1, %eax | ||||
| 	movl	0(,%eax,4), %edx | ||||
| 	movl	(%ecx), %eax | ||||
| 	movl	%eax, (%edx) | ||||
| 	movl	4(%ecx), %eax | ||||
| 	movl	%eax, 4(%edx) | ||||
| 	ret | ||||
|  | ||||
| GLOBL( _x86_MultiTexCoord2fvARB_2_end ) | ||||
|  | ||||
| /* | ||||
| 	MultiTexCoord2fARB st0/st1 | ||||
| */ | ||||
| GLOBL( _x86_MultiTexCoord2fARB ) | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	8(%esp), %edx | ||||
| 	sub	$0x84c0, %eax | ||||
| 	movl	12(%esp), %ecx | ||||
| 	and	$1, %eax | ||||
| 	shl	$3, %eax | ||||
| 	movl	%edx, 0xdeadbeef(%eax) | ||||
| 	movl	%ecx, 0xdeadbeef(%eax) | ||||
| 	ret | ||||
| GLOBL( _x86_MultiTexCoord2fARB_end ) | ||||
|  | ||||
| /* | ||||
| 	MultiTexCoord2fARB | ||||
| */ | ||||
| GLOBL( _x86_MultiTexCoord2fARB_2 ) | ||||
| 	movl	4(%esp), %eax | ||||
| 	movl	8(%esp), %edx | ||||
| 	sub	$0x84c0, %eax | ||||
| 	movl	12(%esp,1), %ecx | ||||
| 	and	$1,%eax | ||||
| 	movl	0(,%eax,4), %eax | ||||
| 	movl	%edx, (%eax) | ||||
| 	movl	%ecx, 4(%eax) | ||||
| 	ret | ||||
| GLOBL( _x86_MultiTexCoord2fARB_2_end ) | ||||
| @@ -1,4 +1,4 @@ | ||||
| # $Id: Makefile,v 1.1.2.26 2003/03/04 17:29:56 keithw Exp $ | ||||
| # $Id: Makefile,v 1.1.2.29 2003/03/20 09:21:23 keithw Exp $ | ||||
|  | ||||
| # Mesa 3-D graphics library | ||||
| # Version:  5.0 | ||||
| @@ -102,7 +102,7 @@ else | ||||
| C_SOURCES = $(DRIVER_SOURCES) \ | ||||
| 	    $(SUBSET_DRIVER_SOURCES) \ | ||||
| 	    $(MINIGLX_SOURCES)  | ||||
| MESA_MODULES = $(FULL_MESA) | ||||
| MESA_MODULES = $(SUBSET_MESA) | ||||
| endif | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -205,8 +205,8 @@ static void radeonInitDriverFuncs( GLcontext *ctx ) | ||||
|     ctx->Driver.Error			= NULL; | ||||
|     ctx->Driver.DrawPixels		= NULL; | ||||
| #if !_HAVE_SWRAST | ||||
|     ctx->Driver.Bitmap			= radeonPointsBitmap; | ||||
|     ctx->Driver.ReadPixels		= radeonReadPixels; | ||||
|     ctx->Exec->Bitmap			= radeonPointsBitmap; | ||||
|     ctx->Exec->ReadPixels		= radeonReadPixels; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @@ -275,6 +275,8 @@ radeonCreateContext( const __GLcontextModes *glVisual, | ||||
|    rmesa->dri.hwLock = &sPriv->pSAREA->lock; | ||||
|    rmesa->dri.fd = sPriv->fd; | ||||
|  | ||||
|    rmesa->glCtx->_RotateMode = radeonScreen->driScreen->display->rotateMode; | ||||
|  | ||||
|    /* If we don't have 1.3, fallback to the 1.1 interfaces. | ||||
|     */ | ||||
|    if (getenv("RADEON_COMPAT") || sPriv->drmMinor < 3 )  | ||||
|   | ||||
| @@ -879,7 +879,10 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) | ||||
|       b[0] = box[0]; | ||||
|       rmesa->sarea->nbox = 1; | ||||
|    } | ||||
|  | ||||
|    else { | ||||
|       UNLOCK_HARDWARE( rmesa ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    /* Throttle the frame rate -- only allow one pending swap buffers | ||||
|     * request at a time. | ||||
|   | ||||
| @@ -109,6 +109,7 @@ radeonUpdatePageFlipping( radeonContextPtr rmesa ) | ||||
|       return; | ||||
|  | ||||
|    rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; | ||||
|    rmesa->doPageFlip = 0; | ||||
|  | ||||
|    use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT); | ||||
|    use_back ^= (rmesa->sarea->pfCurrentPage == 1); | ||||
| @@ -127,23 +128,11 @@ radeonUpdatePageFlipping( radeonContextPtr rmesa ) | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Update the hardware state.  This is called if another context has | ||||
|  * grabbed the hardware lock, which includes the X server.  This | ||||
|  * function also updates the driver's window state after the X server | ||||
|  * moves, resizes or restacks a window -- the change will be reflected | ||||
|  * in the drawable position and clip rects.  Since the X server grabs | ||||
|  * the hardware lock when it changes the window state, this routine will | ||||
|  * automatically be called after such a change. | ||||
|  */ | ||||
| void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) | ||||
| static void validate_drawable( radeonContextPtr rmesa ) | ||||
| { | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    __DRIscreenPrivate *sPriv = rmesa->dri.screen; | ||||
|    RADEONSAREAPrivPtr sarea = rmesa->sarea; | ||||
|    int i; | ||||
|  | ||||
|    drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); | ||||
|    fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    /* The window might have moved, so we might need to get new clip | ||||
|     * rects. | ||||
| @@ -165,14 +154,69 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) | ||||
|       radeonUpdateViewportOffset( rmesa->glCtx ); | ||||
|       rmesa->lastStamp = dPriv->lastStamp; | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Update the hardware state.  This is called if another context has | ||||
|  * grabbed the hardware lock, which includes the X server.  This | ||||
|  * function also updates the driver's window state after the X server | ||||
|  * moves, resizes or restacks a window -- the change will be reflected | ||||
|  * in the drawable position and clip rects.  Since the X server grabs | ||||
|  * the hardware lock when it changes the window state, this routine will | ||||
|  * automatically be called after such a change. | ||||
|  */ | ||||
| void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) | ||||
| { | ||||
|    RADEONSAREAPrivPtr sarea = rmesa->sarea; | ||||
|    int i; | ||||
|  | ||||
|  | ||||
|    while (1) { | ||||
|       drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); | ||||
|  | ||||
|       validate_drawable( rmesa ); | ||||
|  | ||||
|       fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->numClipRects); | ||||
|  | ||||
|       if (rmesa->numClipRects) | ||||
| 	 break; | ||||
|  | ||||
|       drmUnlock( rmesa->dri.fd, rmesa->dri.hwContext ); | ||||
|        | ||||
|       sleep(10); | ||||
|    } | ||||
|  | ||||
|  | ||||
|    if ( sarea->ctxOwner != rmesa->dri.hwContext ) { | ||||
|       sarea->ctxOwner = rmesa->dri.hwContext; | ||||
|  | ||||
|       for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { | ||||
| 	 if ( rmesa->texture.heap[i] && sarea->texAge[i] != rmesa->texture.age[i] ) { | ||||
| 	 if ( rmesa->texture.heap[i] &&  | ||||
| 	      sarea->texAge[i] != rmesa->texture.age[i] ) { | ||||
| 	    radeonAgeTextures( rmesa, i ); | ||||
| 	 } | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| extern void __miniglx_release_vt( void ); | ||||
|  | ||||
| /* In the current miniglx, cliprects can change while the lock is | ||||
|  * held...  Probably need to fix this. | ||||
|  */ | ||||
| void radeonUnlock( radeonContextPtr rmesa ) | ||||
| { | ||||
|    fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|  | ||||
|    drmUnlock( rmesa->dri.fd, rmesa->dri.hwContext ); | ||||
|  | ||||
|    validate_drawable( rmesa ); | ||||
|  | ||||
|    /* This only happens if the VT switch was requested inside the | ||||
|     * locked region. | ||||
|     */ | ||||
|    if (!rmesa->numClipRects) | ||||
|       __miniglx_release_vt(); | ||||
|        | ||||
| } | ||||
|   | ||||
| @@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| #define __RADEON_LOCK_H__ | ||||
|  | ||||
| extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags ); | ||||
| extern void radeonUnlock( radeonContextPtr rmesa ); | ||||
|  | ||||
| /* Turn DEBUG_LOCKING on to find locking conflicts. | ||||
|  */ | ||||
| @@ -99,12 +100,13 @@ extern int prevLockLine; | ||||
|  | ||||
| /* Unlock the hardware. | ||||
|  */ | ||||
| #define UNLOCK_HARDWARE( rmesa )					\ | ||||
|    do {									\ | ||||
|       DRM_UNLOCK( rmesa->dri.fd,					\ | ||||
| 		  rmesa->dri.hwLock,					\ | ||||
| 		  rmesa->dri.hwContext );				\ | ||||
|       DEBUG_RESET();							\ | ||||
| #define UNLOCK_HARDWARE( rmesa )			\ | ||||
|    do {							\ | ||||
|       DRM_CAS_RESULT(__ret);				\ | ||||
|       DRM_CAS( rmesa->dri.hwLock,DRM_LOCK_HELD|rmesa->dri.hwContext,	\ | ||||
| 	      rmesa->dri.hwContext,__ret);		\ | ||||
|       if (__ret) radeonUnlock( rmesa );		\ | ||||
|       DEBUG_RESET();					\ | ||||
|    } while (0) | ||||
|  | ||||
| #endif /* __RADEON_LOCK_H__ */ | ||||
|   | ||||
| @@ -38,6 +38,7 @@ | ||||
| #include "api_arrayelt.h" | ||||
| #include "mmath.h" | ||||
| #include "enums.h" | ||||
| #include "context.h" | ||||
| #include "colormac.h" | ||||
|  | ||||
| #if _HAVE_SWTNL | ||||
| @@ -475,16 +476,25 @@ void radeonUpdateScissor( GLcontext *ctx ) | ||||
|  | ||||
|    if ( rmesa->dri.drawable ) { | ||||
|       __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|       int x1,x2,y1,y2; | ||||
|  | ||||
|       int x = ctx->Scissor.X; | ||||
|       int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; | ||||
|       int w = ctx->Scissor.X + ctx->Scissor.Width - 1; | ||||
|       int h = dPriv->h - ctx->Scissor.Y - 1; | ||||
|       if (ctx->_RotateMode) { | ||||
| 	  x1 = dPriv->w - ctx->Scissor.Y - ctx->Scissor.Height; | ||||
| 	  x2 = dPriv->w - ctx->Scissor.Y; | ||||
| 	  y1 = dPriv->h - ctx->Scissor.X - ctx->Scissor.Width; | ||||
| 	  y2 = dPriv->h - ctx->Scissor.X; | ||||
|       } | ||||
|       else { | ||||
| 	  x1 = ctx->Scissor.X; | ||||
| 	  x2 = ctx->Scissor.X + ctx->Scissor.Width; | ||||
| 	  y1 = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; | ||||
| 	  y2 = dPriv->h - ctx->Scissor.Y; | ||||
|       } | ||||
|  | ||||
|       rmesa->state.scissor.rect.x1 = x + dPriv->x; | ||||
|       rmesa->state.scissor.rect.y1 = y + dPriv->y; | ||||
|       rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; | ||||
|       rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; | ||||
|       rmesa->state.scissor.rect.x1 = x1 + dPriv->x; | ||||
|       rmesa->state.scissor.rect.x2 = x2 + dPriv->x; | ||||
|       rmesa->state.scissor.rect.y1 = y1 + dPriv->y; | ||||
|       rmesa->state.scissor.rect.y2 = y2 + dPriv->y; | ||||
|  | ||||
|       radeonRecalcScissorRects( rmesa ); | ||||
|    } | ||||
| @@ -986,32 +996,54 @@ void radeonUpdateWindow( GLcontext *ctx ) | ||||
| { | ||||
|    radeonContextPtr rmesa = RADEON_CONTEXT(ctx); | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    GLfloat xoffset = (GLfloat)dPriv->x; | ||||
|    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; | ||||
|    const GLfloat *v = ctx->Viewport._WindowMap.m; | ||||
|    const GLfloat n = ctx->Viewport.Near; | ||||
|    const GLfloat f = ctx->Viewport.Far; | ||||
|    const GLfloat x = (GLfloat) ctx->Viewport.X; | ||||
|    const GLfloat y = (GLfloat) ctx->Viewport.Y; | ||||
|    const GLfloat width = (GLfloat) ctx->Viewport.Width; | ||||
|    const GLfloat height = (GLfloat) ctx->Viewport.Height; | ||||
|    GLfloat wx = (GLfloat)dPriv->x; | ||||
|    GLfloat ww = (GLfloat)dPriv->w; | ||||
|    GLfloat wy = (GLfloat)dPriv->y; | ||||
|    GLfloat wh = (GLfloat)dPriv->h; | ||||
|    GLfloat sx,sy,sz, tx,ty,tz; | ||||
|  | ||||
|    if (ctx->_RotateMode) { | ||||
|       sx = height / 2.0F; | ||||
|       tx = wx - sx + ww - y + SUBPIXEL_X; | ||||
|       sy = - width / 2.0F; | ||||
|       ty = wy + sy + wh - x + SUBPIXEL_Y; | ||||
|       sz = ctx->DepthMaxF * ((f - n) / 2.0F) * rmesa->state.depth.scale; | ||||
|       tz = ctx->DepthMaxF * ((f - n) / 2.0F + n) * rmesa->state.depth.scale; | ||||
|    } | ||||
|    else { | ||||
|  | ||||
|       sx = width / 2.0F; | ||||
|       tx = wx + sx + x + SUBPIXEL_X; | ||||
|       sy = -height / 2.0F; | ||||
|       ty = wy + sy + wh - y + SUBPIXEL_Y; | ||||
|       sz = ctx->DepthMaxF * ((f - n) / 2.0F) * rmesa->state.depth.scale; | ||||
|       tz = ctx->DepthMaxF * ((f - n) / 2.0F + n) * rmesa->state.depth.scale; | ||||
|    } | ||||
|  | ||||
|    GLfloat sx = v[MAT_SX]; | ||||
|    GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; | ||||
|    GLfloat sy = - v[MAT_SY]; | ||||
|    GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; | ||||
|    GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; | ||||
|    GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; | ||||
|    RADEON_FIREVERTICES( rmesa ); | ||||
|    RADEON_STATECHANGE( rmesa, vpt ); | ||||
|  | ||||
|    if (0) fprintf(stderr, "%s: %f %f %f %f\n", __FUNCTION__, sx, tx, sy, ty); | ||||
|  | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = *(GLuint *)&sx; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = *(GLuint *)&sy; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = *(GLuint *)&sz; | ||||
|    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * \brief Set the viewport. | ||||
|  * | ||||
|  * \param ctx GL context. | ||||
|  * \param x \e x position of the lower left corner of the viewport rectangle. | ||||
|  * Not used. | ||||
|  * \param y \e y position of the lower left corner of the viewport rectangle. | ||||
| @@ -1023,8 +1055,8 @@ void radeonUpdateWindow( GLcontext *ctx ) | ||||
|  *  | ||||
|  * Fires the vertices and updates the window. | ||||
|  */ | ||||
| static void radeonViewport( GLcontext *ctx, GLint x, GLint y, | ||||
| 			    GLsizei width, GLsizei height ) | ||||
| static void radeonViewport( GLcontext *ctx, | ||||
| 			    GLint x, GLint y, GLsizei width, GLsizei height ) | ||||
| { | ||||
|    /* Don't pipeline viewport changes, conflict with window offset | ||||
|     * setting below.  Could apply deltas to rescue pipelined viewport | ||||
| @@ -1126,7 +1158,9 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) | ||||
| void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ) | ||||
| { | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|  | ||||
|     | ||||
|    fprintf(stderr, "%s\n", __FUNCTION__); | ||||
|     | ||||
|    switch ( mode ) { | ||||
|    case GL_FRONT_LEFT: | ||||
|       rmesa->numClipRects = dPriv->numClipRects; | ||||
| @@ -1153,6 +1187,8 @@ void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ) | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    fprintf(stderr, "%s: %d cliprects\n", __FUNCTION__, rmesa->numClipRects); | ||||
|  | ||||
|    if (rmesa->state.scissor.enabled) | ||||
|       radeonRecalcScissorRects( rmesa ); | ||||
| } | ||||
| @@ -1609,6 +1645,31 @@ void radeonUploadMatrixTranspose( radeonContextPtr rmesa, GLfloat *src, | ||||
| } | ||||
|  | ||||
|  | ||||
| #define A(row,col)  a[(col<<2)+row] | ||||
| #define B(row,col)  b[(col<<2)+row] | ||||
| #define P(row,col)  product[(col<<2)+row] | ||||
|  | ||||
|  | ||||
| static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b ) | ||||
| { | ||||
|    GLint i; | ||||
|    for (i = 0; i < 4; i++) { | ||||
|       const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3); | ||||
|       P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); | ||||
|       P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); | ||||
|       P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); | ||||
|       P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); | ||||
|    } | ||||
| } | ||||
|  | ||||
| static const GLfloat rot[16] = { | ||||
|    0, 1, 0, 0, | ||||
|    -1, 0, 0, 0, | ||||
|    0, 0, 1, 0, | ||||
|    0, 0, 0, 1  | ||||
| }; | ||||
|  | ||||
|  | ||||
| void radeonValidateState( GLcontext *ctx ) | ||||
| { | ||||
|    radeonContextPtr rmesa = RADEON_CONTEXT(ctx); | ||||
| @@ -1621,8 +1682,16 @@ void radeonValidateState( GLcontext *ctx ) | ||||
|  | ||||
|    /* Need an event driven matrix update? | ||||
|     */ | ||||
|    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))  | ||||
|       radeonUploadMatrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ ); | ||||
|    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) { | ||||
|       if (ctx->_RotateMode) { | ||||
| 	 GLfloat tmp[16]; | ||||
| 	 matmul4( tmp, rot, ctx->_ModelProjectMatrix.m ); | ||||
| 	 radeonUploadMatrix( rmesa, tmp, MODEL_PROJ ); | ||||
|       } | ||||
|       else { | ||||
| 	 radeonUploadMatrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ ); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* Need these for lighting (shouldn't upload otherwise) | ||||
|     */ | ||||
| @@ -1726,8 +1795,7 @@ void radeonInitStateFuncs( GLcontext *ctx ) | ||||
|    ctx->Driver.StencilFunc		= radeonStencilFunc; | ||||
|    ctx->Driver.StencilMask		= radeonStencilMask; | ||||
|    ctx->Driver.StencilOp		= radeonStencilOp; | ||||
|    ctx->Driver.Viewport			= radeonViewport; | ||||
|  | ||||
|    ctx->Driver.Viewport			= radeonViewport;  | ||||
| } | ||||
|  | ||||
| /*@}*/ | ||||
|   | ||||
| @@ -36,16 +36,14 @@ | ||||
| #ifndef __RADEON_SUBSET_H__ | ||||
| #define __RADEON_SUBSET_H__ | ||||
|  | ||||
| extern void radeonPointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
| 				GLsizei width, GLsizei height, | ||||
| 				const struct gl_pixelstore_attrib *unpack, | ||||
| extern void radeonPointsBitmap( GLsizei width, GLsizei height, | ||||
| 				GLfloat xorig, GLfloat yorig, | ||||
| 				GLfloat xmove, GLfloat ymove, | ||||
| 				const GLubyte *bitmap ); | ||||
|  | ||||
| extern void radeonReadPixels( GLcontext *ctx, | ||||
| 			      GLint x, GLint y, | ||||
| extern void radeonReadPixels( GLint x, GLint y, | ||||
| 			      GLsizei width, GLsizei height, | ||||
| 			      GLenum format, GLenum type, | ||||
| 			      const struct gl_pixelstore_attrib *packing, | ||||
| 			      GLvoid *pixels ); | ||||
|  | ||||
| extern void radeon_select_Install( GLcontext *ctx ); | ||||
|   | ||||
| @@ -37,11 +37,13 @@ | ||||
| #include "glheader.h" | ||||
| #include "mtypes.h" | ||||
| #include "colormac.h" | ||||
| #include "context.h" | ||||
| #include "enums.h" | ||||
| #include "imports.h" | ||||
| #include "image.h" | ||||
| #include "mmath.h" | ||||
| #include "macros.h" | ||||
| #include "state.h" | ||||
|  | ||||
| #include "radeon_context.h" | ||||
| #include "radeon_ioctl.h" | ||||
| @@ -65,45 +67,52 @@ | ||||
|  * restores TCL, viewport, texture and color states. | ||||
|  */ | ||||
| void | ||||
| radeonPointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
| 		  GLsizei width, GLsizei height, | ||||
| 		  const struct gl_pixelstore_attrib *unpack, | ||||
| 		  const GLubyte *bitmap ) | ||||
| radeonPointsBitmap(  GLsizei width, GLsizei height, | ||||
| 		     GLfloat xorig, GLfloat yorig,  | ||||
| 		     GLfloat xmove, GLfloat ymove, | ||||
| 		     const GLubyte *bitmap ) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    GLsizei bmwidth = width, bmheight = height;    | ||||
|    GLint px, py; | ||||
|    radeonContextPtr rmesa = RADEON_CONTEXT(ctx); | ||||
|    GLfloat saved_color[4], saved_tex0[2]; | ||||
|    GLint row, col; | ||||
|    GLuint orig_se_cntl; | ||||
|    GLuint h; | ||||
|    GLfloat pfz = ctx->Current.RasterPos[3]; | ||||
|    GLint skipRows = unpack->SkipRows; | ||||
|    GLint skipPixels = unpack->SkipPixels; | ||||
|    GLuint w, h; | ||||
|    const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; | ||||
|  | ||||
|    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); | ||||
|  | ||||
|    if (width < 0 || height < 0) { | ||||
|       _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    if (!ctx->Current.RasterPosValid) | ||||
|       return; | ||||
|  | ||||
|    /* horizontal clipping */ | ||||
|    if (px < 0) { | ||||
|       skipPixels -= px; | ||||
|       width += px; | ||||
|       px = 0; | ||||
|    } | ||||
|    if (px + width > (GLint) ctx->ReadBuffer->Width) | ||||
|       width -= (px + width - (GLint) ctx->ReadBuffer->Width); | ||||
|    if (width <= 0) | ||||
|       return; | ||||
|    if (ctx->NewState)  | ||||
|       _mesa_update_state(ctx); | ||||
|  | ||||
|    /* vertical clipping */ | ||||
|    if (py < 0) { | ||||
|       skipRows -= py; | ||||
|       height += py; | ||||
|       py = 0; | ||||
|  | ||||
|    if (ctx->_RotateMode) { | ||||
|       width = bmheight; height = bmwidth; | ||||
|  | ||||
|       px = IFLOOR(ctx->Current.RasterPos[0] + yorig); | ||||
|       py = IFLOOR(ctx->Current.RasterPos[1] + xorig); | ||||
|  | ||||
|       ctx->Current.RasterPos[0] += ymove; | ||||
|       ctx->Current.RasterPos[1] += xmove; | ||||
|    } | ||||
|    if (py + height > (GLint) ctx->ReadBuffer->Height) | ||||
|       height -= (py + height - (GLint) ctx->ReadBuffer->Height); | ||||
|    if (height <= 0) | ||||
|       return; | ||||
|    else { | ||||
|       px = IFLOOR(ctx->Current.RasterPos[0] - xorig); | ||||
|       py = IFLOOR(ctx->Current.RasterPos[1] - yorig); | ||||
|  | ||||
|       ctx->Current.RasterPos[0] += xmove; | ||||
|       ctx->Current.RasterPos[1] += ymove; | ||||
|    } | ||||
|  | ||||
|  | ||||
|  | ||||
|    /* Turn off tcl and the hw viewport transformation so that we can | ||||
| @@ -119,6 +128,7 @@ radeonPointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
|    /* Adjust for window coordinates, flip y values: | ||||
|     */ | ||||
|    h = rmesa->dri.drawable->h + rmesa->dri.drawable->y - 1; | ||||
|    w = rmesa->dri.drawable->w; | ||||
|    px += rmesa->dri.drawable->x; | ||||
|  | ||||
|    /* Save current color, texcoord to restore later: | ||||
| @@ -132,42 +142,48 @@ radeonPointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
|    glColor4fv( ctx->Current.RasterColor ); | ||||
|    glTexCoord2fv( ctx->Current.RasterTexCoords[0] ); | ||||
|  | ||||
|    for (row=0; row<height; row++) { | ||||
|       GLuint y = h - (py + row); | ||||
|       const GLubyte *src = (const GLubyte *)  | ||||
| 	 _mesa_image_address( unpack, bitmap, width, height,  | ||||
| 			      GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 ); | ||||
|  | ||||
|       if (unpack->LsbFirst) { | ||||
|          /* Lsb first */ | ||||
|          GLubyte mask = 1U << (unpack->SkipPixels & 0x7); | ||||
|          for (col=0; col<width; col++) { | ||||
|             if (*src & mask)  | ||||
| 	       glVertex3f( px+col, y, pfz ); | ||||
| 	    src += (mask >> 7); | ||||
| 	    mask = ((mask << 1) & 0xff) | (mask >> 7); | ||||
|          } | ||||
|  | ||||
|          /* get ready for next row */ | ||||
|          if (mask != 1) | ||||
|             src++; | ||||
|       } | ||||
|       else { | ||||
|          /* Msb first */ | ||||
|          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); | ||||
|          for (col=0; col<width; col++) { | ||||
|             if (*src & mask) { | ||||
| 	       glVertex3f( px+col, y, pfz ); | ||||
|             } | ||||
|    if (ctx->_RotateMode) { | ||||
|       for (col=0; col<width; col++) { | ||||
| 	 const GLubyte *src = (const GLubyte *)  | ||||
| 	    _mesa_image_address( unpack, bitmap, height, width,  | ||||
| 				 GL_COLOR_INDEX, GL_BITMAP, 0, col, 0 ); | ||||
| 	     | ||||
| 	 /* Msb first */ | ||||
| 	 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); | ||||
| 	 for (row=0; row<height; row++) { | ||||
| 	    if (*src & mask) { | ||||
| 	       glVertex2f( px-col, h - (py + row) ); | ||||
| 	    } | ||||
| 	    src += mask & 1; | ||||
| 	    mask = ((mask << 7) & 0xff) | (mask >> 1); | ||||
|          } | ||||
|          /* get ready for next row */ | ||||
|          if (mask != 128) | ||||
|             src++; | ||||
| 	 } | ||||
| 	 /* get ready for next row */ | ||||
| 	 if (mask != 128) | ||||
| 	    src++; | ||||
|       } | ||||
|    } | ||||
|     | ||||
|    else { | ||||
|       for (row=0; row<height; row++) { | ||||
| 	 const GLubyte *src = (const GLubyte *)  | ||||
| 	    _mesa_image_address( unpack, bitmap, width, height,  | ||||
| 				 GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 ); | ||||
| 	     | ||||
| 	 /* Msb first */ | ||||
| 	 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); | ||||
| 	 for (col=0; col<width; col++) { | ||||
| 	    if (*src & mask) { | ||||
| 	       glVertex2f( px+col, h - (py + row) ); | ||||
| 	    } | ||||
| 	    src += mask & 1; | ||||
| 	    mask = ((mask << 7) & 0xff) | (mask >> 1); | ||||
| 	 } | ||||
| 	 /* get ready for next row */ | ||||
| 	 if (mask != 128) | ||||
| 	    src++; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    glEnd(); | ||||
|    glColor4fv( saved_color ); | ||||
|    glTexCoord2fv( saved_tex0 ); | ||||
| @@ -178,3 +194,4 @@ radeonPointsBitmap( GLcontext *ctx, GLint px, GLint py, | ||||
|    rmesa->hw.set.cmd[SET_SE_CNTL] = orig_se_cntl; | ||||
|    radeonSubsetVtxEnableTCL( rmesa, GL_TRUE ); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -37,10 +37,12 @@ | ||||
| #include "glheader.h" | ||||
| #include "mtypes.h" | ||||
| #include "colormac.h" | ||||
| #include "context.h" | ||||
| #include "enums.h" | ||||
| #include "imports.h" | ||||
| #include "mmath.h" | ||||
| #include "macros.h" | ||||
| #include "state.h" | ||||
|  | ||||
| #include "radeon_context.h" | ||||
| #include "radeon_ioctl.h" | ||||
| @@ -96,19 +98,36 @@ static void ReadRGBASpan( const GLcontext *ctx, | ||||
|    radeonContextPtr rmesa = RADEON_CONTEXT(ctx); | ||||
|    radeonScreenPtr radeonScreen = rmesa->radeonScreen; | ||||
|    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; | ||||
|    GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; | ||||
|    char *ptr = (char *)(rmesa->dri.screen->pFB + | ||||
| 			rmesa->state.pixel.readOffset + | ||||
| 			((dPriv->x + x) * radeonScreen->cpp) + | ||||
| 			((dPriv->y + (dPriv->h - y - 1)) * pitch)); | ||||
|    GLint i = 0; | ||||
|    GLuint cpp = radeonScreen->cpp; | ||||
|    GLuint pitch = radeonScreen->frontPitch * cpp; | ||||
|    GLint i; | ||||
|  | ||||
|    if (radeonScreen->cpp == 4) | ||||
|       for (i = 0; i < n; i++, ptr += 4) | ||||
| 	 READ_RGBA_32( rgba[i], ptr ); | ||||
|    else | ||||
|       for (i = 0; i < n; i++, ptr += 2) | ||||
| 	 READ_RGBA_16( rgba[i], ptr ); | ||||
|    if (ctx->_RotateMode) { | ||||
|       char *ptr = (char *)(rmesa->dri.screen->pFB + | ||||
| 			   rmesa->state.pixel.readOffset + | ||||
| 			   ((dPriv->x + (dPriv->w - y - 1)) * cpp) + | ||||
| 			   ((dPriv->y + (dPriv->h - x - 1)) * pitch)); | ||||
|  | ||||
|       if (cpp == 4) | ||||
| 	 for (i = 0; i < n; i++, ptr -= pitch) | ||||
| 	    READ_RGBA_32( rgba[i], ptr ); | ||||
|       else | ||||
| 	 for (i = 0; i < n; i++, ptr -= pitch) | ||||
| 	    READ_RGBA_16( rgba[i], ptr ); | ||||
|    } | ||||
|    else { | ||||
|       char *ptr = (char *)(rmesa->dri.screen->pFB + | ||||
| 			   rmesa->state.pixel.readOffset + | ||||
| 			   ((dPriv->x + x) * cpp) + | ||||
| 			   ((dPriv->y + (dPriv->h - y - 1)) * pitch)); | ||||
|  | ||||
|       if (cpp == 4) | ||||
| 	 for (i = 0; i < n; i++, ptr += cpp) | ||||
| 	    READ_RGBA_32( rgba[i], ptr ); | ||||
|       else | ||||
| 	 for (i = 0; i < n; i++, ptr += cpp) | ||||
| 	    READ_RGBA_16( rgba[i], ptr ); | ||||
|    } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -131,20 +150,42 @@ static void ReadRGBASpan( const GLcontext *ctx, | ||||
|  * After asserting the above conditions, compensates for clipping and calls | ||||
|  * ReadRGBASpan() to read each row. | ||||
|  */ | ||||
| void radeonReadPixels( GLcontext *ctx, | ||||
| 		       GLint x, GLint y, | ||||
| void radeonReadPixels( GLint x, GLint y, | ||||
| 		       GLsizei width, GLsizei height, | ||||
| 		       GLenum format, GLenum type, | ||||
| 		       const struct gl_pixelstore_attrib *packing, | ||||
| 		       GLvoid *pixels ) | ||||
| { | ||||
|    GET_CURRENT_CONTEXT(ctx); | ||||
|    GLint srcX = x; | ||||
|    GLint srcY = y; | ||||
|    GLint readWidth = width;           /* actual width read */ | ||||
|    GLint readHeight = height;         /* actual height read */ | ||||
|    const struct gl_pixelstore_attrib *packing = &ctx->Pack; | ||||
|    GLint skipRows = packing->SkipRows; | ||||
|    GLint skipPixels = packing->SkipPixels; | ||||
|    GLint rowLength; | ||||
|    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); | ||||
|  | ||||
|    { | ||||
|       GLint tmp, tmps; | ||||
|       tmp = x; x = y; y = tmp; | ||||
|       tmps = width; width = height; height = tmps; | ||||
|    } | ||||
|  | ||||
|    if (width < 0 || height < 0) { | ||||
|       _mesa_error( ctx, GL_INVALID_VALUE, | ||||
|                    "glReadPixels(width=%d height=%d)", width, height ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    if (!pixels) { | ||||
|       _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); | ||||
|       return; | ||||
|    } | ||||
|  | ||||
|    if (ctx->NewState) | ||||
|       _mesa_update_state(ctx); | ||||
|  | ||||
|  | ||||
|    /* can't do scale, bias, mapping, etc */ | ||||
|    assert(!ctx->_ImageTransferState); | ||||
|   | ||||
| @@ -27,7 +27,7 @@ | ||||
|  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| /* $Id: radeon_subset_select.c,v 1.1.2.4 2003/02/23 16:50:48 jrfonseca Exp $ */ | ||||
| /* $Id: radeon_subset_select.c,v 1.1.2.5 2003/03/17 21:23:00 keithw Exp $ */ | ||||
|  | ||||
|  | ||||
| #include "glheader.h" | ||||
| @@ -913,6 +913,7 @@ static void radeon_select_End(void) | ||||
|    ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * \brief Flush vertices. | ||||
|  *  | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user