Compare commits

...

49 Commits

Author SHA1 Message Date
Keith Whitwell
4b930d3080 Drop morph3d, add terrain 2003-02-23 21:36:20 +00:00
Keith Whitwell
2b3cd85107 Subset terrain 2003-02-23 21:04:38 +00:00
Keith Whitwell
12acb24b60 Subset isosurf 2003-02-23 21:04:25 +00:00
Keith Whitwell
b4bc6375d1 fix some compiler warnings 2003-02-23 20:24:11 +00:00
Keith Whitwell
c91deeffc4 Fail if detected chipset isn't an r100. 2003-02-23 20:23:34 +00:00
Keith Whitwell
728dade650 Fix radeon_tex_region_t declaration (char became int). 2003-02-23 20:16:25 +00:00
Keith Whitwell
c3ded1b33d clean up header usage 2003-02-23 19:38:23 +00:00
Keith Whitwell
080ae6edb5 Add stricter compiler warnings 2003-02-23 19:37:52 +00:00
Keith Whitwell
b8bc33a6b1 add 'void' to glXGetProcAddress prototype 2003-02-23 19:37:15 +00:00
Keith Whitwell
1d7c610c2b Add manytex demo 2003-02-23 19:27:31 +00:00
Keith Whitwell
70130333c2 Use correct pv for flatshaded quadstrips 2003-02-23 19:27:03 +00:00
Keith Whitwell
c608a0fb2a Exclude lighting, userclip state 2003-02-23 19:26:32 +00:00
Keith Whitwell
7f35ecd070 subset demos 2003-02-23 19:25:07 +00:00
Brian Paul
ef9f2d4296 added radeon_subset to header 2003-02-23 17:25:22 +00:00
Jose Fonseca
27b8f1d3ae Final documentation fixes and additions. 2003-02-23 16:50:46 +00:00
Jose Fonseca
c35fb58c35 A few documention fixes and additions. 2003-02-23 15:21:36 +00:00
Jose Fonseca
eb998b80ea Last bits of documentation. Full review still pending. 2003-02-23 02:19:13 +00:00
Jose Fonseca
b77ca3d2b7 More documentation - now almost complete. 2003-02-22 21:27:17 +00:00
Jose Fonseca
cdc64176f9 More documention additions. 2003-02-22 11:48:50 +00:00
Jose Fonseca
da69c37f98 Bunch of documention additions. 2003-02-22 09:17:11 +00:00
Keith Whitwell
661a236d09 Correctly initialize RE_LINE_PATTERN register 2003-02-21 23:59:15 +00:00
Keith Whitwell
b9f8f7f6a4 Eliminate non-subset operations 2003-02-21 23:07:40 +00:00
Keith Whitwell
66f40571e1 Eliminate use of glRectf, sleep so that we see some frames. 2003-02-21 22:20:08 +00:00
Keith Whitwell
6620693116 Eliminate use of glRectf 2003-02-21 22:18:24 +00:00
Brian Paul
730cacfa01 sample MiniGLX program 2003-02-21 21:55:58 +00:00
Keith Whitwell
2f05ae32c5 new file 2003-02-21 21:55:26 +00:00
Keith Whitwell
d9ed9e1a9a Restrict access to non-subset gl entrypoints. Other small cleanups. 2003-02-21 21:14:08 +00:00
Keith Whitwell
6133ba36ec Fix vertex copying bug, remove polygonmode support (didn't/couldn't work) 2003-02-21 21:12:51 +00:00
Jose Fonseca
4b5f9479eb Renamed and tailored the radeon doxygen file for the OpenGL subset only 2003-02-16 21:42:11 +00:00
Jose Fonseca
75019b24d1 Initial/partial documentation to the functions/structures that make the Radeon subset driver. 2003-02-16 20:48:08 +00:00
Jose Fonseca
c9118dfaba A new doxygen configuration file for the Radeon driver. 2003-02-10 17:59:46 +00:00
Jose Fonseca
a140417be9 Most of the documentation to the "server-side" part of the Radeon driver. 2003-02-10 17:58:52 +00:00
Keith Whitwell
ccf4e3e8f2 Eliminate all remaining fallbacks & usage of FALLBACK macro
Rename subset_feedback.c to subset_select.c...
Add new file subset_tex.c which agressively subsets texture operations.
2003-02-07 20:22:16 +00:00
Keith Whitwell
78e1fee39b Add files to allow the subset driver to be built as a dri driver.
At the moment have to choose to build as *either* a dri or a miniglx
driver, but shouldn't be too hard to build one driver that will work
in both environments.
2003-02-05 04:37:12 +00:00
Keith Whitwell
75ccd62be8 Add unfilled rendering and code for feedback (not yet integrated) 2003-02-03 21:33:02 +00:00
Brian Paul
cd9df92c9d clarified glPolygonMode section 2003-02-03 15:00:38 +00:00
Keith Whitwell
cfe59bd3f9 Eliminate some more code 2003-01-28 22:37:23 +00:00
Keith Whitwell
62bc31dcae Eliminate radeon_subset_tcl.c. 2003-01-28 18:28:54 +00:00
Keith Whitwell
675f151c42 Fix compilation for full driver build.
Subsetted readpixels seems to be working.
2003-01-27 16:55:30 +00:00
Keith Whitwell
151cd27866 New file containing subsetted readpixels implementation. 2003-01-24 17:11:10 +00:00
Keith Whitwell
c8facc28cc Isolated code for lighting, fog, texgen and userclip in new files.
Moved some existing swrast, swtnl specific code into files that don't
get built in the subsetted driver.
2003-01-24 15:52:52 +00:00
Keith Whitwell
086e00e086 Add new defines for lighting, texgen, userclip subsetting.
Remove unused mesa modules from link.
2003-01-24 15:50:52 +00:00
Brian Paul
49116e9fd2 terminology updates, etc 2003-01-23 17:15:38 +00:00
Keith Whitwell
9d0eff73b5 Bitmaps are right-way-up 2003-01-23 10:43:59 +00:00
Keith Whitwell
81c7427ddc Hook in accelerated bitmap function -- bitmaps are upside-down! 2003-01-22 18:21:32 +00:00
Keith Whitwell
9e3c6f3b8e (Partially) subsetted driver runs miniglxtest and texobj.
Other applications segfault at null function pointers, etc -- need to remove
these entrypoints from miniglx libGL.so.
2003-01-22 18:16:33 +00:00
Keith Whitwell
18a5321288 Rename radeon_bitmap.c to radeon_subset_bitmap.c
Add new file radeon_subset_tcl.c
	-- this is temporary and will go away eventually.
Some code removal in radeon_subset_vtx.c
2003-01-22 16:19:42 +00:00
Keith Whitwell
4c864746d6 Add new files for bitmap and subsetted begin/end processing. 2003-01-22 12:23:20 +00:00
Keith Whitwell
19b1476515 Start subsetting -- turn off swrast & swtnl. 2003-01-22 09:53:49 +00:00
95 changed files with 16066 additions and 3652 deletions

View File

@@ -7,35 +7,42 @@
<span style="font-style: italic;"></span><span
style="font-weight: bold;"></span>
<h1>
<center>OpenGL Subset Specification</center>
<center>Mesa Subset Specification</center>
</h1>
<h2>
<center>
<h3>Tungsten Graphics, Inc.</h3>
<h3>January 20, 2003<br>
<h3>February 3, 2003<br>
</h3>
</center>
</h2>
<p> Copyright &copy; 2002-2003 by Tungsten Graphics, Inc., Cedar Park,
Texas. All Rights Reserved. <br>
<p> Copyright &copy; 2002-2003 by <a
href="http://www.tungstengraphics.com/">Tungsten Graphics, Inc.</a>,
Cedar Park, Texas. All Rights Reserved. <br>
<br>
Permission is granted to make and distribute verbatim copies of this
document provided the copyright notice and this permission notice are
preserved on all copies.<br>
</p>
<p> OpenGL is a trademark of <a href="http://www.sgi.com">Silicon
Graphics, Inc.</a>.</p>
<h1>1. Introduction</h1>
This document describes a subset of the OpenGL API implemented by
Tungsten Graphics, Inc. for embedded devices. &nbsp;Prior to reading
this document the reader should be familiar with the OpenGL 1.2.1
This document describes a subset of the Mesa implemented by Tungsten
Graphics, Inc. for embedded devices. &nbsp;Prior to reading this
document the reader should be familiar with the OpenGL 1.2.1
specification dated April 1, 1999 (available from <a
href="http://www.opengl.org/developers/documentation/specs.html">http://www.opengl.org/developers/documentation/specs.html</a>.)
&nbsp;Experience with OpenGL programming is highly advisable.<a
href="http://www.opengl.org/developers/documentation/specs.html"><br>
</a><br>
Tungsten Graphics, Inc. is working with industry standards
organizations +in an attempt to standardize this Mesa subset and any
other possible subsets +as a result of this work. <br>
<br>
Appendix A contains a list of issues of which some may not be resolved.<br>
<br>
To summarize, the following major features of OpenGL are omitted from
the subset:<br>
To summarize, the following major features of Mesa are omitted from the
subset:<br>
<ul>
<li>Vertex arrays</li>
<li>Texture coordinate generation</li>
@@ -57,10 +64,11 @@ the subset:<br>
</ul>
<p>Further reductions are made at a lower level of detail.<br>
</p>
<p>As in the OpenGL specification, OpenGL identifiers are printed in <span
style="font-weight: bold;">bold face</span>.<br>
<p>Mesa function names are printed in <span style="font-weight: bold;">bold
face</span>. &nbsp;Function parameters are printed in <span
style="font-style: italic;">italics</span>.<br>
</p>
<p>The Tungsten Graphics, Inc. OpenGL subset library is hereafter
<p>The Tungsten Graphics, Inc. Mesa subset library is hereafter
referred to as <span style="font-style: italic;">the subset.</span><br>
<br>
</p>
@@ -108,10 +116,10 @@ GL_POLYGON - a closed, convex polygon<br>
<br>
The <span style="font-weight: bold;">glVertex</span> commands take two
or three floating point coordinates, or a pointer to an array of two or
three floating point coordinates. &nbsp;OpenGL vertices are actually
4-element homogeneous coordinates. &nbsp;The fourth component,
unspecified by the subset's <span style="font-weight: bold;">glVertex</span>
commands, is one.<br>
three floating point coordinates. &nbsp;Vertices are actually 4-element
homogeneous coordinates. &nbsp;The fourth component, unspecified by the
subset's <span style="font-weight: bold;">glVertex</span> commands, is
one.<br>
<br>
<span style="font-weight: bold;"></span>
<h2>2.2 Other Per-vertex Commands<br>
@@ -162,8 +170,8 @@ command between <span style="font-weight: bold;">glBegin</span> and <span
GL_INVALID_OPERATION.<br>
<br>
<h2>2.3 Unsupported Commands</h2>
None of the following OpenGL commands related to primitive
specification are supported by the subset:<br>
None of the following commands related to primitive specification are
supported by the subset:<br>
<br>
<div style="margin-left: 40px;">Per-Vertex commands:<br>
</div>
@@ -480,7 +488,7 @@ Lines are rendered with the command sequence <span
style="font-weight: bold;">glEnd</span> where <span
style="font-style: italic;">mode</span> is one of GL_LINES,
GL_LINE_STRIP or GL_LINE_LOOP. &nbsp;Lines are rasterized as described
in the OpenGL specification. &nbsp;Note that OpenGL uses the <span
in the OpenGL specification. &nbsp;Note that OpenGL specifies the <span
style="font-style: italic;">half-open</span> convention for drawing
lines: the last fragment in a line segment is omitted so that endpoint
pixels shared by two line segments will only be drawn once instead of
@@ -507,9 +515,8 @@ Lines may be stippled (i.e. dashed) with the command<br>
style="font-style: italic;">pattern</span>)<br>
</div>
<br>
As described in the OpenGL specification, <span
style="font-style: italic;">pattern</span> describes an on/off pattern
for the fragments produced by rasterization and <span
<span style="font-style: italic;">pattern</span> describes an on/off
pattern for the fragments produced by rasterization and <span
style="font-style: italic;">factor</span> specifies how many subsequent
fragments are kept or culled for each pattern bit. &nbsp;Line stippling
can be enabled or disabled by the commands <span
@@ -582,7 +589,7 @@ front-facing triangles and quadrilaterals, respectively.<br>
The command<br>
<br>
<div style="margin-left: 40px;">void <span style="font-weight: bold;">glFrontFace</span>(GLenum<span
style="font-style: italic;">mode</span>)<br>
style="font-style: italic;"> mode</span>)<br>
</div>
<br>
specifies whether clockwise or counter-clockwise winding indicates a
@@ -628,15 +635,18 @@ The command<br>
controls whether polygons are filled, outlined or drawn with a point at
each vertex.&nbsp; The <span style="font-style: italic;">face</span>
parameter must be GL_FRONT_AND_BACK. &nbsp;The values GL_FRONT and
GL_BACK are not permitted by the subset. &nbsp;If <span
style="font-style: italic;">mode</span> is GL_FILL then the polygon
will be filled (the default). &nbsp;If <span style="font-style: italic;">mode</span>
is GL_LINE then the polygon will be rendered as if it were specified by <span
style="font-weight: bold;">glBegin</span>(GL_LINE_LOOP). &nbsp;If <span
style="font-style: italic;">mode</span> is GL_POINT then the polygon
will be rendered as if it were specified with <span
style="font-weight: bold;">glBegin</span>(GL_POINTS). &nbsp;Any other
values for <span style="font-style: italic;">face</span> or <span
GL_BACK are not permitted by the subset.<br>
<br>
If <span style="font-style: italic;">mode</span> is GL_FILL then
triangles, quadrilaterals and triangles will be filled (the default).
&nbsp;If <span style="font-style: italic;">mode</span> is GL_LINE then
triangles, quadrilaterals and polygons will be outlined with line
segments instead of being filled.<span style="font-weight: bold;"></span>
&nbsp;If <span style="font-style: italic;">mode</span> is GL_POINT then
triangles, quadrilaterals and polygons will be rendered with a point at
each vertex instead of being filled.<span style="font-weight: bold;"></span><br>
<br>
Any other values for <span style="font-style: italic;">face</span> or <span
style="font-style: italic;">mode</span> will raise the error
GL_INVALID_ENUM.<br>
<br>
@@ -676,10 +686,10 @@ the first vertex specifies the color for the entire polygon. &nbsp;If <span
are linearly interpolated to produce the fragment colors.<br>
<br>
<h2>4.5 Bitmap Rasterization</h2>
In OpenGL, a bitmap is a monochromatic, binary image in which each
image element (or pixel) is represented by one bit. &nbsp;Fragments are
only generated for the bits (pixels) which are set. &nbsp;Bitmaps are
commonly used to draw text (glyphs) and markers.<br>
A bitmap is a monochromatic, binary image in which each image element
(or pixel) is represented by one bit. &nbsp;Fragments are only generated
for the bits (pixels) which are set. &nbsp;Bitmaps are commonly used
to draw text (glyphs) and markers.<br>
<br>
A bitmap is drawn with the command<br>
<br>
@@ -3037,13 +3047,11 @@ implementation, such as "Tungsten Graphics, Inc."<br>
<td style="vertical-align: top;">GL_EXTENSIONS<br>
</td>
<td style="vertical-align: top;">A white-space separated list of
the supported OpenGL extensions.<br>
</td>
the supported extensions. </td>
</tr>
</tbody>
</table>
<br>
<br>
<h2>9.3 Error Queries</h2>
The command<br>
<br>
@@ -3466,8 +3474,9 @@ Which image formats and types should be supported for <span
style="font-weight: bold;">glTexImage2D</span> and <span
style="font-weight: bold;">glReadPixels</span>?<br>
<br>
OpenGL supports a <span style="font-weight: bold;">large</span> variety
of image formats and data types. &nbsp;Only a few are commonly used.<br>
OpenGL specifies a <span style="font-weight: bold;">large</span>
variety of image formats and data types. &nbsp;Only a few are commonly
used.<br>
<br>
RECOMMENDATION: &nbsp;we propose a subset:<br>
<br>
@@ -3567,6 +3576,7 @@ be expressed as floating point values and queried with <span
implementation of the other three commands involves many lines of code.<br>
<br>
RESOLUTION: &nbsp;open<br>
<br>
<h2>A.13 glBitmap and Per-Fragment Operations</h2>
Should bitmaps rendered with <span style="font-weight: bold;">glBitmap</span>
be subjected to the per-fragment operations?<br>
@@ -3581,6 +3591,18 @@ easy.<br>
<br>
RESOLUTION: &nbsp;open<br>
<br>
<h2>A.14 Reduced gl.h Header File</h2>
Should we produce a reduced gl.h header file which only defines the
tokens and functions which are implemented by the subset?<br>
<br>
RECOMMENDATION: yes. &nbsp;It would be a useful reference to
programmers to quickly determine which functions and tokens are
supported.<br>
<br>
RESOLUTION: open<br>
<br>
<br>
<br>
<p> </p>
</body>
</html>

View File

@@ -3,6 +3,7 @@ array_cache
core
math
miniglx
radeon_subset
swrast
swrast_setup
tnl

View File

@@ -10,4 +10,5 @@
<a href="../swrast_setup/index.html">swrast_setup</a>&nbsp;
<a href="../tnl/index.html">tnl</a>&nbsp;
<a href="../tnl_dd/index.html">tnl_dd</a>&nbsp;
<a href="../radeon_subset/index.html">radeon_subset</a>&nbsp;
</center>

View File

@@ -15,9 +15,10 @@ default:
doxygen swrast_setup.doxy
doxygen tnl.doxy
doxygen miniglx.doxy
doxygen radeon_subset.doxy
clean:
rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx
rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx radeon_subset
rm -rf *.tag

View File

@@ -54,7 +54,7 @@ WARN_LOGFILE =
INPUT = ../src/miniglx/ ../include/GL/miniglx.h
FILE_PATTERNS = *.h *.c
RECURSIVE = NO
EXCLUDE =
EXCLUDE = ../src/miniglx/glapi.c
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =

208
doxygen/radeon_subset.doxy Normal file
View File

@@ -0,0 +1,208 @@
# Doxyfile 0.1
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "Radeon Subset Driver"
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 = NO
SHOW_INCLUDE_FILES = NO
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 = 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/drv/common/mm.c \
../src/drv/common/mm.h \
../src/drv/radeon/radeon_context.c \
../src/drv/radeon/radeon_context.h \
../src/drv/radeon/radeon_ioctl.c \
../src/drv/radeon/radeon_ioctl.h \
../src/drv/radeon/radeon_lock.c \
../src/drv/radeon/radeon_lock.h \
../src/drv/radeon/radeon_screen.c \
../src/drv/radeon/radeon_screen.h \
../src/drv/radeon/radeon_state.c \
../src/drv/radeon/radeon_state.h \
../src/drv/radeon/radeon_state_init.c \
../src/drv/radeon/radeon_subset.h \
../src/drv/radeon/radeon_subset_bitmap.c \
../src/drv/radeon/radeon_subset_readpix.c \
../src/drv/radeon/radeon_subset_select.c \
../src/drv/radeon/radeon_subset_tex.c \
../src/drv/radeon/radeon_subset_vtx.c \
../src/drv/radeon/radeon_tcl.h \
../src/drv/radeon/radeon_tex.h \
../src/drv/radeon/radeon_vtxfmt.h \
../src/drv/radeon/server
FILE_PATTERNS = *.h *.c
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 = radeon_subset
HTML_HEADER = header.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 = 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
GENERATE_TAGFILE = radeon_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 =

View File

@@ -1,4 +1,4 @@
/* $Id: glx.h,v 1.38 2002/10/14 13:52:27 brianp Exp $ */
/* $Id: glx.h,v 1.38.4.1 2003/02/23 19:37:15 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -295,7 +295,7 @@ extern void glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
/* GLX 1.4 and later */
extern void (*glXGetProcAddress(const GLubyte *procname))();
extern void (*glXGetProcAddress(const GLubyte *procname))( void );
#ifndef GLX_GLXEXT_LEGACY

View File

@@ -1,8 +1,9 @@
PROGS = gears \
glinfo \
morph3d \
texobj
texobj \
bounce \
terrain
##### RULES #####
@@ -13,7 +14,7 @@ PROGS = gears \
# make executable from .c file:
.c: $(LIB_DEP)
gcc -I../include -g $< -L../lib -lglut -lGL -lm -o $@
gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lm -o $@
default: $(PROGS)

View File

@@ -1,4 +1,4 @@
/* $Id: bounce.c,v 1.3 2000/08/16 20:36:34 brianp Exp $ */
/* $Id: bounce.c,v 1.3.8.1 2003/02/23 19:25:07 keithw Exp $ */
/*
* Bouncing ball demo.
@@ -33,8 +33,8 @@ GLfloat Xmin = -4.0, Xmax = 4.0;
GLfloat Ymin = -3.8, Ymax = 4.0;
GLfloat G = -0.1;
static GLuint
make_ball(void)
static void
draw_ball(void)
{
GLuint list;
GLfloat a, b;
@@ -43,9 +43,9 @@ make_ball(void)
GLuint color;
GLfloat x, y, z;
list = glGenLists(1);
/* list = glGenLists(1); */
glNewList(list, GL_COMPILE);
/* glNewList(list, GL_COMPILE); */
color = 0;
for (a = -90.0; a + da <= 90.0; a += da) {
@@ -54,10 +54,10 @@ make_ball(void)
for (b = 0.0; b <= 360.0; b += db) {
if (color) {
glIndexi(RED);
/* glIndexi(RED); */
glColor3f(1, 0, 0);
} else {
glIndexi(WHITE);
/* glIndexi(WHITE); */
glColor3f(1, 1, 1);
}
@@ -77,11 +77,12 @@ make_ball(void)
}
glEndList();
/* glEndList(); */
return list;
/* return list; */
}
static void
reshape(int width, int height)
{
@@ -110,7 +111,7 @@ draw(void)
glClear(GL_COLOR_BUFFER_BIT);
glIndexi(CYAN);
/* glIndexi(CYAN); */
glColor3f(0, 1, 1);
glBegin(GL_LINES);
for (i = -5; i <= 5; i++) {
@@ -138,7 +139,8 @@ draw(void)
glRotatef(90.0, 1.0, 0.0, 0.0);
glRotatef(Zrot, 0.0, 0.0, 1.0);
glCallList(Ball);
/* glCallList(Ball); */
draw_ball();
glPopMatrix();
@@ -198,7 +200,7 @@ int main(int argc, char *argv[])
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Bounce");
Ball = make_ball();
/* Ball = make_ball(); */
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glDisable(GL_DITHER);

View File

@@ -1,4 +1,4 @@
/* $Id: gears.c,v 1.6 2000/04/06 02:22:59 brianp Exp $ */
/* $Id: gears.c,v 1.6.12.1 2003/02/23 19:25:07 keithw Exp $ */
/*
* 3-D gear wheels. This program is in the public domain.
@@ -59,7 +59,7 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
glShadeModel(GL_FLAT);
glNormal3f(0.0, 0.0, 1.0);
/* glNormal3f(0.0, 0.0, 1.0); */
/* draw front face */
glBegin(GL_QUAD_STRIP);
@@ -87,7 +87,7 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
}
glEnd();
glNormal3f(0.0, 0.0, -1.0);
/* glNormal3f(0.0, 0.0, -1.0); */
/* draw back face */
glBegin(GL_QUAD_STRIP);
@@ -127,18 +127,18 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
len = sqrt(u * u + v * v);
u /= len;
v /= len;
glNormal3f(v, -u, 0.0);
/* glNormal3f(v, -u, 0.0); */
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
glNormal3f(cos(angle), sin(angle), 0.0);
/* glNormal3f(cos(angle), sin(angle), 0.0); */
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
glNormal3f(v, -u, 0.0);
/* glNormal3f(v, -u, 0.0); */
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
glNormal3f(cos(angle), sin(angle), 0.0);
/* glNormal3f(cos(angle), sin(angle), 0.0); */
}
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
@@ -149,10 +149,11 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
glShadeModel(GL_SMOOTH);
/* draw inside radius cylinder */
glColor3f( .5, .5, .5 );
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glNormal3f(-cos(angle), -sin(angle), 0.0);
/* glNormal3f(-cos(angle), -sin(angle), 0.0); */
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
}
@@ -167,6 +168,11 @@ static GLfloat angle = 0.0;
static void
draw(void)
{
static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
glClearColor( 1,0,1,1 );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
@@ -177,19 +183,23 @@ draw(void)
glPushMatrix();
glTranslatef(-3.0, -2.0, 0.0);
glRotatef(angle, 0.0, 0.0, 1.0);
glCallList(gear1);
glColor3fv( red);
gear(1.0, 4.0, 1.0, 20, 0.7);
glPopMatrix();
glPushMatrix();
glTranslatef(3.1, -2.0, 0.0);
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
glCallList(gear2);
glColor3fv( green);
gear(0.5, 2.0, 2.0, 10, 0.7);
glPopMatrix();
glPushMatrix();
glTranslatef(-3.1, 4.2, 0.0);
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
glCallList(gear3);
glColor3fv( blue);
gear(1.3, 2.0, 0.5, 10, 0.7);
glPopMatrix();
glPopMatrix();
@@ -284,37 +294,15 @@ static void
init(int argc, char *argv[])
{
static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
GLint i;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
/* glLightfv(GL_LIGHT0, GL_POSITION, pos); */
glEnable(GL_CULL_FACE);
/* glEnable(GL_LIGHTING); */
/* glEnable(GL_LIGHT0); */
/* glEnable(GL_DEPTH_TEST); */
/* make the gears */
gear1 = glGenLists(1);
glNewList(gear1, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
gear(1.0, 4.0, 1.0, 20, 0.7);
glEndList();
gear2 = glGenLists(1);
glNewList(gear2, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
gear(0.5, 2.0, 2.0, 10, 0.7);
glEndList();
gear3 = glGenLists(1);
glNewList(gear3, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
gear(1.3, 2.0, 0.5, 10, 0.7);
glEndList();
glEnable(GL_NORMALIZE);
/* glEnable(GL_NORMALIZE); */
for ( i=1; i<argc; i++ ) {
if (strcmp(argv[i], "-info")==0) {
@@ -345,7 +333,7 @@ int main(int argc, char *argv[])
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(300, 300);
glutInitWindowSize(900, 900);
glutCreateWindow("Gears");
init(argc, argv);

View File

@@ -1,4 +1,4 @@
/* $Id: isosurf.c,v 1.15 2002/10/18 17:47:35 kschultz Exp $ */
/* $Id: isosurf.c,v 1.15.4.1 2003/02/23 21:04:25 keithw Exp $ */
/*
* Display an isosurface of 3-D wind speed volume.
@@ -484,7 +484,7 @@ static void draw_surface( unsigned int with_state )
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
glBegin( GL_TRIANGLES );
for (k = 0 ; k < nr ; k++) {
glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
glColor3fv( &compressed_data[tri_indices[i+k]][3] );
glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
}
glEnd();
@@ -492,7 +492,7 @@ static void draw_surface( unsigned int with_state )
} else {
glBegin( GL_TRIANGLES );
for (i = 0 ; i < num_tri_verts ; i++) {
glNormal3fv( &compressed_data[tri_indices[i]][3] );
glColor3fv( &compressed_data[tri_indices[i]][3] );
glVertex3fv( &compressed_data[tri_indices[i]][0] );
}
glEnd();
@@ -506,7 +506,7 @@ static void draw_surface( unsigned int with_state )
*/
glBegin( GL_POINTS );
for ( i = 0 ; i < numuniq ; i++ ) {
glNormal3fv( &compressed_data[i][3] );
glColor3fv( &compressed_data[i][3] );
glVertex3fv( &compressed_data[i][0] );
}
glEnd();
@@ -515,7 +515,7 @@ static void draw_surface( unsigned int with_state )
case (GLVERTEX|STRIPS):
glBegin( GL_TRIANGLE_STRIP );
for (i=0;i<numverts;i++) {
glNormal3fv( &data[i][3] );
glColor3fv( &data[i][0] );
glVertex3fv( &data[i][0] );
}
glEnd();
@@ -595,24 +595,24 @@ static void InitMaterials(void)
static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
static float lmodel_twoside[] = {GL_FALSE};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glEnable(GL_LIGHT0);
/* glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); */
/* glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); */
/* glLightfv(GL_LIGHT0, GL_POSITION, position0); */
/* glEnable(GL_LIGHT0); */
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, position1);
glEnable(GL_LIGHT1);
/* glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); */
/* glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); */
/* glLightfv(GL_LIGHT1, GL_POSITION, position1); */
/* glEnable(GL_LIGHT1); */
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
/* glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); */
/* glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); */
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
/* glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess); */
/* glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular); */
/* glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse); */
glPolygonStipple (halftone);
/* glPolygonStipple (halftone); */
}
@@ -736,65 +736,6 @@ static void ModeMenu(int m)
print_flags("primitive", state & PRIMITIVE_MASK);
print_flags("render style", state & RENDER_STYLE_MASK);
if ((state & PRIMITIVE_MASK) != STRIPS &&
((state & RENDER_STYLE_MASK) == DRAW_ELTS ||
(state & RENDER_STYLE_MASK) == ARRAY_ELT ||
(state & PRIMITIVE_MASK) == POINTS))
{
fprintf(stderr, "enabling small arrays\n");
/* Rendering any primitive with draw-element/array-element
* --> Can't do strips here as ordering has been lost in
* compaction process...
*/
glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
compressed_data );
glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
&compressed_data[0][3]);
#ifdef GL_EXT_compiled_vertex_array
if (allowed & LOCKED) {
if (state & LOCKED) {
glLockArraysEXT( 0, numuniq );
} else {
glUnlockArraysEXT();
}
}
#endif
}
else if ((state & PRIMITIVE_MASK) == TRIANGLES &&
(state & RENDER_STYLE_MASK) == DRAW_ARRAYS) {
fprintf(stderr, "enabling big arrays\n");
/* Only get here for TRIANGLES and drawarrays
*/
glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), (numverts-2) * 3,
expanded_data );
glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), (numverts-2) * 3,
&expanded_data[0][3]);
#ifdef GL_EXT_compiled_vertex_array
if (allowed & LOCKED) {
if (state & LOCKED) {
glLockArraysEXT( 0, (numverts-2)*3 );
} else {
glUnlockArraysEXT();
}
}
#endif
}
else {
fprintf(stderr, "enabling normal arrays\n");
glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
#ifdef GL_EXT_compiled_vertex_array
if (allowed & LOCKED) {
if (state & LOCKED) {
glLockArraysEXT( 0, numverts );
} else {
glUnlockArraysEXT();
}
}
#endif
}
}
#endif
@@ -827,9 +768,9 @@ static void Init(int argc, char *argv[])
plane[3] = 0.0;
glClearColor(0.0, 0.0, 1.0, 0.0);
glEnable( GL_DEPTH_TEST );
glEnable( GL_VERTEX_ARRAY_EXT );
glEnable( GL_NORMAL_ARRAY_EXT );
/* glEnable( GL_DEPTH_TEST ); */
/* glEnable( GL_VERTEX_ARRAY_EXT ); */
/* glEnable( GL_NORMAL_ARRAY_EXT ); */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -837,24 +778,24 @@ static void Init(int argc, char *argv[])
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClipPlane(GL_CLIP_PLANE0, plane);
/* glClipPlane(GL_CLIP_PLANE0, plane); */
InitMaterials();
set_matrix();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
/* glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); */
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
/* glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); */
/* glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); */
/* Green fog is easy to see */
glFogi(GL_FOG_MODE,GL_EXP2);
glFogfv(GL_FOG_COLOR,fogColor);
glFogf(GL_FOG_DENSITY,0.15);
glHint(GL_FOG_HINT,GL_DONT_CARE);
/* glFogi(GL_FOG_MODE,GL_EXP2); */
/* glFogfv(GL_FOG_COLOR,fogColor); */
/* glFogf(GL_FOG_DENSITY,0.15); */
/* glHint(GL_FOG_HINT,GL_DONT_CARE); */
{
static int firsttime = 1;
@@ -872,7 +813,7 @@ static void Init(int argc, char *argv[])
}
ModeMenu(SHADE_SMOOTH|
LIT|
UNLIT|
POINT_FILTER|
NO_USER_CLIP|
NO_MATERIALS|
@@ -1121,6 +1062,9 @@ int main(int argc, char **argv)
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Display);
/* Benchmark(5,0); */
/* Benchmark(5,0); */
/* Benchmark(5,0); */
glutMainLoop();
return 0;
}

View File

@@ -51,7 +51,7 @@ static GLfloat terraincolor[256 * 256][3];
static int win = 0;
static int fog = 1;
static int fog = 0;
static int bfcull = 1;
static int usetex = 1;
static int poutline = 0;
@@ -105,6 +105,21 @@ calcposobs(void)
obs[1] = 0.0;
}
static void
perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLdouble 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) */
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
static void
reshape(int width, int height)
{
@@ -113,7 +128,7 @@ reshape(int width, int height)
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, ((GLfloat) width / (GLfloat) height),
perspective(50.0, ((GLfloat) width / (GLfloat) height),
lenghtXmnt * stepYmnt * 0.01, lenghtXmnt * stepYmnt * 0.7);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@@ -209,13 +224,25 @@ printstring(void *font, char *string)
glutBitmapCharacter(font, string[i]);
}
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
glBegin( GL_QUADS );
glVertex2f( x1, y1 );
glVertex2f( x2, y1 );
glVertex2f( x2, y2 );
glVertex2f( x1, y2 );
glEnd();
}
static void
printhelp(void)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0, 0.0, 0.0, 0.5);
glRecti(40, 40, 600, 440);
_subset_Rectf(40, 40, 600, 440);
glDisable(GL_BLEND);
glColor3f(1.0, 0.0, 0.0);
@@ -351,6 +378,87 @@ dojoy(void)
#endif
}
static void
lookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
GLfloat centerx, GLfloat centery, GLfloat centerz,
GLfloat upx, GLfloat upy, GLfloat 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);
}
static void
drawscene(void)
{
@@ -359,24 +467,24 @@ drawscene(void)
dojoy();
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
/* glEnable(GL_DEPTH_TEST); */
if (usetex)
glEnable(GL_TEXTURE_2D);
else
glDisable(GL_TEXTURE_2D);
if (fog)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
/* if (fog) */
/* glEnable(GL_FOG); */
/* else */
/* glDisable(GL_FOG); */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
calcposobs();
gluLookAt(obs[0], obs[1], obs[2],
lookAt(obs[0], obs[1], obs[2],
obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
0.0, 1.0, 0.0);
@@ -384,8 +492,8 @@ drawscene(void)
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_FOG);
/* glDisable(GL_DEPTH_TEST); */
/* glDisable(GL_FOG); */
glShadeModel(GL_FLAT);
glMatrixMode(GL_PROJECTION);
@@ -549,7 +657,7 @@ calccolor(GLfloat height, GLfloat c[3])
static void
loadpic(void)
{
GLubyte bufferter[256 * 256], terrainpic[256 * 256];
GLubyte bufferter[256 * 256], terrainpic[256 * 256][4];
FILE *FilePic;
int i, tmp;
GLenum gluerr;
@@ -565,25 +673,28 @@ loadpic(void)
terrain[i] = (bufferter[i] * (heightMnt / 255.0f));
calccolor((GLfloat) bufferter[i], terraincolor[i]);
tmp = (((int) bufferter[i]) + 96);
terrainpic[i] = (tmp > 255) ? 255 : tmp;
terrainpic[i][0] = (tmp > 255) ? 255 : tmp;
terrainpic[i][1] = (tmp > 255) ? 255 : tmp;
terrainpic[i][2] = (tmp > 255) ? 255 : tmp;
terrainpic[i][0] = 255;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, 256, 256, GL_LUMINANCE,
if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA,
GL_UNSIGNED_BYTE,
(GLvoid *) (&terrainpic[0])))) {
(GLvoid *) (&terrainpic[0][0])))) {
fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
exit(-1);
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);
}
@@ -593,21 +704,21 @@ init(void)
float fogcolor[4] = { 0.6, 0.7, 0.7, 1.0 };
glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
/* glClearDepth(1.0); */
/* glDepthFunc(GL_LEQUAL); */
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
/* glEnable(GL_DEPTH_TEST); */
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP2);
glFogfv(GL_FOG_COLOR, fogcolor);
glFogf(GL_FOG_DENSITY, 0.0007);
/* glEnable(GL_FOG); */
/* glFogi(GL_FOG_MODE, GL_EXP2); */
/* glFogfv(GL_FOG_COLOR, fogcolor); */
/* glFogf(GL_FOG_DENSITY, 0.0007); */
#ifdef FX
glHint(GL_FOG_HINT, GL_NICEST);
/* glHint(GL_FOG_HINT, GL_NICEST); */
#endif
reshape(scrwidth, scrheight);

View File

@@ -1,4 +1,4 @@
/* $Id: texobj.c,v 1.6 2002/01/04 21:05:57 brianp Exp $ */
/* $Id: texobj.c,v 1.6.6.1 2003/02/23 19:25:07 keithw Exp $ */
/*
* Example of using the 1.1 texture object functions.
@@ -17,7 +17,7 @@ static GLuint Window = 0;
static GLuint TexObj[2];
static GLfloat Angle = 0.0f;
static GLboolean UseObj = GL_FALSE;
static GLboolean UseObj = GL_TRUE;
#if defined(GL_VERSION_1_1) || defined(GL_VERSION_1_2)
@@ -34,7 +34,7 @@ static GLboolean UseObj = GL_FALSE;
static void draw( void )
{
glDepthFunc(GL_EQUAL);
/* glDepthFunc(GL_EQUAL); */
/* glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );*/
glClear( GL_COLOR_BUFFER_BIT );
@@ -147,7 +147,7 @@ static void init( void )
0, 0, 2, 2, 2, 2, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
GLubyte tex[64][3];
GLubyte tex[64][4];
GLint i, j;
@@ -156,7 +156,7 @@ static void init( void )
/* Setup texturing */
glEnable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
/* glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ); */
/* generate texture object IDs */
@@ -174,7 +174,7 @@ static void init( void )
if (UseObj) {
#ifdef TEXTURE_OBJECT
glBindTexture( GL_TEXTURE_2D, TexObj[0] );
assert(glIsTexture(TexObj[0]));
/* assert(glIsTexture(TexObj[0])); */
#endif
}
else {
@@ -190,11 +190,12 @@ static void init( void )
else {
tex[p][0] = 255; tex[p][1] = 255; tex[p][2] = 255;
}
tex[p][3] = 255;
}
}
glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
@@ -208,9 +209,9 @@ static void init( void )
if (UseObj) {
#ifdef TEXTURE_OBJECT
glBindTexture( GL_TEXTURE_2D, TexObj[1] );
assert(glIsTexture(TexObj[1]));
/* assert(glIsTexture(TexObj[1])); */
#endif
assert(!glIsTexture(TexObj[1] + 999));
/* assert(!glIsTexture(TexObj[1] + 999)); */
}
else {
glNewList( TexObj[1], GL_COMPILE );
@@ -227,8 +228,8 @@ static void init( void )
}
}
}
glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );

View File

@@ -498,7 +498,7 @@ main(int ac, char **av)
glEnable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_FOG);
/* glEnable(GL_FOG); */
glFogi(GL_FOG_MODE, GL_EXP2);
glFogfv(GL_FOG_COLOR, fogcolor);

View File

@@ -104,7 +104,7 @@ static void Init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearIndex(0.0);
/* glClearIndex(0.0); */
}
static void Reshape(int width, int height)
@@ -140,14 +140,14 @@ static void Draw(void)
mapIA[0] = 1.0;
mapIA[1] = 1.0;
glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 2, mapIR);
glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 2, mapI);
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 2, mapI);
glPixelMapfv(GL_PIXEL_MAP_I_TO_A, 2, mapIA);
glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
/* glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 2, mapIR); */
/* glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 2, mapI); */
/* glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 2, mapI); */
/* glPixelMapfv(GL_PIXEL_MAP_I_TO_A, 2, mapIA); */
/* glPixelTransferi(GL_MAP_COLOR, GL_TRUE); */
SetColor(COLOR_WHITE);
glRasterPos3fv(boxA);
glRasterPos2fv(boxA);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 24);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 8);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 2);
@@ -162,28 +162,28 @@ static void Draw(void)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
SetColor(COLOR_WHITE);
glRasterPos3fv(boxB);
glRasterPos2fv(boxB);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits1);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits2);
SetColor(COLOR_YELLOW);
glRasterPos3fv(boxC);
glRasterPos2fv(boxC);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits1);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits2);
SetColor(COLOR_CYAN);
glRasterPos3fv(boxD);
glRasterPos2fv(boxD);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits1);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits2);
SetColor(COLOR_RED);
glRasterPos3fv(boxE);
glRasterPos2fv(boxE);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
OpenGL_bits1);
glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,

View File

@@ -620,19 +620,19 @@ static void Init(void)
GLint i;
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearIndex(0.0);
/* glClearIndex(0.0); */
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (i = 0; i < 7; i++) {
exp_lists[i] = glGenLists(1);
glNewList(exp_lists[i], GL_COMPILE);
glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
glEndList();
/* exp_lists[i] = glGenLists(1); */
/* glNewList(exp_lists[i], GL_COMPILE); */
/* glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]); */
/* glEndList(); */
}
abuse = GL_FALSE;
useLists = GL_TRUE;
useLists = GL_FALSE;
}
static void Reshape(int width, int height)
@@ -696,10 +696,10 @@ static void Draw(void)
SetColor(COLOR_RED);
break;
}
glRasterPos3i((j*3)%5, (j*3)%8, 0);
glRasterPos2i((j*3)%5, (j*3)%8);
if (useLists) {
glCallList(exp_lists[i]);
/* glCallList(exp_lists[i]); */
} else {
glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
}
@@ -714,9 +714,9 @@ static void Draw(void)
for (j = 0; j < 40; j++) {
SetColor(COLOR_BLACK);
glRasterPos3i((j*3)%5, (j*3)%8, 0);
glRasterPos2i((j*3)%5, (j*3)%8);
if (useLists) {
glCallList(exp_lists[i]);
/* glCallList(exp_lists[i]); */
} else {
glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
}

View File

@@ -147,7 +147,7 @@ static void Draw(void)
glVertex3fv(pntB);
glEnd();
glPointSize(1);
/* glPointSize(1); */
SetColor(COLOR_GREEN);
glBegin(GL_POINTS);

View File

@@ -151,7 +151,7 @@ static void Draw(void)
glDisable(GL_POINT_SMOOTH);
}
glPointSize(size);
/* glPointSize(size); */
if (mode) {
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED);
} else {
@@ -164,7 +164,7 @@ static void Draw(void)
glDisable(GL_POINT_SMOOTH);
glDisable(GL_BLEND);
glPointSize(1);
/* glPointSize(1); */
SetColor(COLOR_GREEN);
glBegin(GL_POINTS);
glVertex3fv(point);

View File

@@ -52,27 +52,27 @@ static void Reshape(int width, int height)
windH = (GLint)height;
}
static void RotateColorMask(void)
static void RotateRestoreColorMask( int rotate )
{
static GLint rotation = 0;
rotation = (rotation + 1) & 0x3;
if (rotate) rotation = (rotation + 1) & 0x3;
switch (rotation) {
case 0:
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glIndexMask( 0xff );
/* glIndexMask( 0xff ); */
break;
case 1:
glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
glIndexMask(0xFE);
/* glIndexMask(0xFE); */
break;
case 2:
glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
glIndexMask(0xFD);
/* glIndexMask(0xFD); */
break;
case 3:
glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
glIndexMask(0xFB);
/* glIndexMask(0xFB); */
break;
}
}
@@ -90,7 +90,7 @@ static void Key(unsigned char key, int x, int y)
mode2 = !mode2;
break;
case '3':
RotateColorMask();
RotateRestoreColorMask( 1 );
break;
default:
return;
@@ -344,7 +344,7 @@ static void Rect(void)
{
SetColor(COLOR_GREEN);
glRecti(-boxW/4, -boxH/4, boxW/4, boxH/4);
/* glRecti(-boxW/4, -boxH/4, boxW/4, boxH/4); */
}
static void PolygonFunc(void)
@@ -445,15 +445,16 @@ static void Draw(void)
glViewport(0, 0, windW, windH);
glDisable(GL_SCISSOR_TEST);
glPushAttrib(GL_COLOR_BUFFER_BIT);
/* glPushAttrib(GL_COLOR_BUFFER_BIT); */
glColorMask(1, 1, 1, 1);
glIndexMask(~0);
/* glIndexMask(~0); */
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glPopAttrib();
/* glPopAttrib(); */
RotateRestoreColorMask( 0 );
if (mode1) {
glShadeModel(GL_SMOOTH);
@@ -461,11 +462,11 @@ static void Draw(void)
glShadeModel(GL_FLAT);
}
if (mode2) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
/* if (mode2) { */
/* glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); */
/* } else { */
/* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */
/* } */
Viewport(0, 0); Point();
Viewport(0, 1); Lines();
@@ -478,10 +479,13 @@ static void Draw(void)
Viewport(1, 2); Triangles();
Viewport(1, 3); TriangleStrip();
Viewport(2, 0); Rect();
Viewport(2, 1); PolygonFunc();
Viewport(2, 2); Quads();
Viewport(2, 3); QuadStrip();
if (0) {
}
glFlush();

View File

@@ -279,11 +279,11 @@ static void Draw(void)
if (showVerticies) {
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2);
/* glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2); */
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2);
/* glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2); */
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2);
/* glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2); */
}
glPopMatrix();
@@ -306,7 +306,7 @@ static void Draw(void)
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0,0,1);
glPointSize(10);
/* glPointSize(10); */
glLineWidth(5);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_STIPPLE);
@@ -322,7 +322,7 @@ static void Draw(void)
glVertex3fv(p2);
EndPrim();
glPointSize(1);
/* glPointSize(1); */
glLineWidth(1);
glDisable(GL_POINT_SMOOTH);
glDisable(GL_LINE_STIPPLE);

View File

@@ -6,9 +6,9 @@
CC = gcc
CFLAGS = -g -I../include
LIBS = -L../lib -lGL -lm
LIBS = -L../lib -lGL -lglut -lm
PROGS = miniglxtest miniglxsample
PROGS = miniglxtest miniglxsample manytex
##### RULES #####

125
progs/tests/miniglxsample.c Normal file
View File

@@ -0,0 +1,125 @@
#define USE_MINIGLX 1 /* 1 = use Mini GLX, 0 = use Xlib/GLX */
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#if USE_MINIGLX
#include <GL/miniglx.h>
#else
#include <GL/glx.h>
#include <X11/Xlib.h>
#endif
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
glBegin( GL_QUADS );
glVertex2f( x1, y1 );
glVertex2f( x2, y1 );
glVertex2f( x2, y2 );
glVertex2f( x1, y2 );
glEnd();
}
/*
* Create a simple double-buffered RGBA window.
*/
static Window
MakeWindow(Display * dpy, unsigned int width, unsigned int height)
{
int visAttributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
None
};
XSetWindowAttributes attr;
unsigned long attrMask;
Window root;
Window win;
GLXContext ctx;
XVisualInfo *visinfo;
root = RootWindow(dpy, 0);
/* Choose GLX visual / pixel format */
visinfo = glXChooseVisual(dpy, 0, visAttributes);
if (!visinfo) {
printf("Error: couldn't get an RGB, Double-buffered visual\n");
exit(1);
}
/* Create the window */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
attrMask = CWBackPixel | CWBorderPixel | CWColormap;
win = XCreateWindow(dpy, root, 0, 0, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, attrMask, &attr);
if (!win) {
printf("Error: XCreateWindow failed\n");
exit(1);
}
/* Display the window */
XMapWindow(dpy, win);
/* Create GLX rendering context */
ctx = glXCreateContext(dpy, visinfo, NULL, True);
if (!ctx) {
printf("Error: glXCreateContext failed\n");
exit(1);
}
/* Bind the rendering context and window */
glXMakeCurrent(dpy, win, ctx);
return win;
}
/*
* Draw a few frames of a rotating square.
*/
static void
DrawFrames(Display * dpy, Window win)
{
int angle;
glShadeModel(GL_FLAT);
glClearColor(0.5, 0.5, 0.5, 1.0);
for (angle = 0; angle < 360; angle += 10) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 0.0);
glPushMatrix();
glRotatef(angle, 0, 0, 1);
_subset_Rectf(-0.8, -0.8, 0.8, 0.8);
glPopMatrix();
glXSwapBuffers(dpy, win);
sleep(1);
}
}
int
main(int argc, char *argv[])
{
Display *dpy;
Window win;
dpy = XOpenDisplay(NULL);
if (!dpy) {
printf("Error: XOpenDisplay failed\n");
return 1;
}
win = MakeWindow(dpy, 300, 300);
DrawFrames(dpy, win);
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $Id: miniglxtest.c,v 1.1.4.6 2003/01/20 11:25:50 keithw Exp $ */
/* $Id: miniglxtest.c,v 1.1.4.7 2003/02/21 22:18:24 keithw Exp $ */
/*
* Test the mini GLX interface.
@@ -22,6 +22,19 @@
GLXContext ctx;
static void _subset_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
glBegin( GL_QUADS );
glVertex2f( x1, y1 );
glVertex2f( x2, y1 );
glVertex2f( x2, y2 );
glVertex2f( x1, y2 );
glEnd();
}
static void redraw( Display *dpy, Window w, int rot )
{
printf("Redraw event\n");
@@ -46,7 +59,7 @@ static void redraw( Display *dpy, Window w, int rot )
glPushMatrix();
glRotatef(rot, 0, 0, 1);
glScalef(.5, .5, .5);
glRectf( -1, -1, 1, 1 );
_subset_Rectf( -1, -1, 1, 1 );
glPopMatrix();
#endif

67
src/dri-es/Makefile Normal file
View File

@@ -0,0 +1,67 @@
# $Id: Makefile,v 1.1.2.1 2003/02/05 04:37:12 keithw Exp $
# Mesa 3-D graphics library
# Version: 5.0
# Copyright (C) 1995-2002 Brian Paul
MESA = ../..
MESABUILDDIR = ..
INCLUDES = -I/usr/X11R6/include -I/usr/X11R6/include/X11/extensions -I$(MESA)/include -I. -I..
DEFINES =
CFLAGS = $(INCLUDES) $(DEFINES) -g -MD -Wall -Wpointer-arith \
-Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wnested-externs
# The .a files for each mesa module required by this driver:
#
DRI_SOURCES = dri_glx.c \
dri_util.c \
xf86drm.c \
xf86drmHash.c \
xf86drmRandom.c \
xf86drmSL.c
C_SOURCES = $(DRI_SOURCES)
ASM_SOURCES =
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)
##### RULES #####
.S.o:
$(CC) -c $(CFLAGS) $< -o $@
.c.o:
$(CC) -c $(CFLAGS) $< -o $@
##### TARGETS #####
default: dri.a
dri.a: $(OBJECTS) Makefile
rm -f $@ && ar rcv $@ $(OBJECTS) && ranlib $@
clean:
-rm -f *.o *~ *.d .\#* *.so
tags:
etags `find . -name \*.[ch]` `find ../include`
##### DEPENDENCIES #####
-include $(C_SOURCES:.c=.d)
.SUFFIXES: .c .d
.c.d:
$(CC) -M $(INCLUDES) $(DEFINES) $< > $@

472
src/dri-es/dri_glx.c Normal file
View File

@@ -0,0 +1,472 @@
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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.
**************************************************************************/
/* $XFree86: xc/lib/GL/dri/dri_glx.c,v 1.10 2001/08/27 17:40:57 dawes Exp $ */
/*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
*
*/
#include <unistd.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include "extutil.h"
#include "glxclient.h"
#include "xf86dri.h"
#include "sarea.h"
#include <stdio.h>
#include <dlfcn.h>
#include "dri_glx.h"
#include <sys/types.h>
#include <stdarg.h>
#ifdef BUILT_IN_DRI_DRIVER
extern void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config);
#else /* BUILT_IN_DRI_DRIVER */
#ifndef DEFAULT_DRIVER_DIR
/* this is normally defined in the Imakefile */
#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"
#endif
static __DRIdriver *Drivers = NULL;
/*
* printf wrappers
*/
static void InfoMessageF(const char *f, ...)
{
va_list args;
const char *env;
if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
fprintf(stderr, "libGL: ");
va_start(args, f);
vfprintf(stderr, f, args);
va_end(args);
}
}
static void ErrorMessageF(const char *f, ...)
{
va_list args;
if (getenv("LIBGL_DEBUG")) {
fprintf(stderr, "libGL error: ");
va_start(args, f);
vfprintf(stderr, f, args);
va_end(args);
}
}
/*
* We'll save a pointer to this function when we couldn't find a
* direct rendering driver for a given screen.
*/
static void *DummyCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
(void) dpy;
(void) scrn;
(void) psc;
(void) numConfigs;
(void) config;
return NULL;
}
/*
* Extract the ith directory path out of a colon-separated list of
* paths.
* Input:
* index - index of path to extract (starting at zero)
* paths - the colon-separated list of paths
* dirLen - max length of result to store in <dir>
* Output:
* dir - the extracted directory path, dir[0] will be zero when
* extraction fails.
*/
static void ExtractDir(int index, const char *paths, int dirLen, char *dir)
{
int i, len;
const char *start, *end;
/* find ith colon */
start = paths;
i = 0;
while (i < index) {
if (*start == ':') {
i++;
start++;
}
else if (*start == 0) {
/* end of string and couldn't find ith colon */
dir[0] = 0;
return;
}
else {
start++;
}
}
while (*start == ':')
start++;
/* find next colon, or end of string */
end = start + 1;
while (*end != ':' && *end != 0) {
end++;
}
/* copy string between <start> and <end> into result string */
len = end - start;
if (len > dirLen - 1)
len = dirLen - 1;
strncpy(dir, start, len);
dir[len] = 0;
}
/*
* Try to dlopen() the named driver. This function adds the
* "_dri.so" suffix to the driver name and searches the
* directories specified by the LIBGL_DRIVERS_PATH env var
* in order to find the driver.
* Input:
* driverName - a name like "tdfx", "i810", "mga", etc.
* Return:
* handle from dlopen, or NULL if driver file not found.
*/
static __DRIdriver *OpenDriver(const char *driverName)
{
char *libPaths = NULL;
int i;
__DRIdriver *driver;
/* First, search Drivers list to see if we've already opened this driver */
for (driver = Drivers; driver; driver = driver->next) {
if (strcmp(driver->name, driverName) == 0) {
/* found it */
return driver;
}
}
if (geteuid() == getuid()) {
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
libPaths = getenv("LIBGL_DRIVERS_PATH");
if (!libPaths)
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
}
if (!libPaths)
libPaths = DEFAULT_DRIVER_DIR;
for (i = 0; ; i++) {
char libDir[1000], realDriverName[200];
void *handle;
ExtractDir(i, libPaths, 1000, libDir);
if (!libDir[0])
break; /* ran out of paths to search */
snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName);
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
if (handle) {
/* allocate __DRIdriver struct */
driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver));
if (!driver)
return NULL; /* out of memory! */
/* init the struct */
driver->name = __glXstrdup(driverName);
if (!driver->name) {
Xfree(driver);
return NULL; /* out of memory! */
}
driver->createScreenFunc = (CreateScreenFunc)
dlsym(handle, "__driCreateScreen");
if (!driver->createScreenFunc) {
/* If the driver doesn't have this symbol then something's
* really, really wrong.
*/
ErrorMessageF("__driCreateScreen() not defined in %s_dri.so!\n",
driverName);
Xfree(driver);
dlclose(handle);
continue;
}
driver->registerExtensionsFunc = (RegisterExtensionsFunc)
dlsym(handle, "__driRegisterExtensions");
driver->handle = handle;
/* put at head of linked list */
driver->next = Drivers;
Drivers = driver;
return driver;
}
else {
ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
}
}
ErrorMessageF("unable to find driver: %s_dri.so\n", driverName);
return NULL;
}
/*
* Given a display pointer and screen number, determine the name of
* the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
* Return True for success, False for failure.
*/
static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
{
int directCapable;
Bool b;
int driverMajor, driverMinor, driverPatch;
*driverName = NULL;
if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed");
return False;
}
if (!directCapable) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false");
return False;
}
b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
&driverPatch, driverName);
if (!b) {
ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
return False;
}
InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
driverMajor, driverMinor, driverPatch, *driverName, scrNum);
return True;
}
/*
* Given a display pointer and screen number, return a __DRIdriver handle.
* Return NULL if anything goes wrong.
*/
__DRIdriver *driGetDriver(Display *dpy, int scrNum)
{
char *driverName;
if (GetDriverName(dpy, scrNum, &driverName)) {
return OpenDriver(driverName);
}
return NULL;
}
#endif /* BUILT_IN_DRI_DRIVER */
/* This function isn't currently used.
*/
static void driDestroyDisplay(Display *dpy, void *private)
{
__DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private;
if (pdpyp) {
const int numScreens = ScreenCount(dpy);
int i;
for (i = 0; i < numScreens; i++) {
if (pdpyp->libraryHandles[i])
dlclose(pdpyp->libraryHandles[i]);
}
Xfree(pdpyp->libraryHandles);
Xfree(pdpyp);
}
}
/*
* Allocate, initialize and return a __DRIdisplayPrivate object.
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
{
const int numScreens = ScreenCount(dpy);
__DRIdisplayPrivate *pdpyp;
int eventBase, errorBase;
int major, minor, patch;
int scrn;
/* Initialize these fields to NULL in case we fail.
* If we don't do this we may later get segfaults trying to free random
* addresses when the display is closed.
*/
pdisp->private = NULL;
pdisp->destroyDisplay = NULL;
pdisp->createScreen = NULL;
if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
return NULL;
}
if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
return NULL;
}
pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate));
if (!pdpyp) {
return NULL;
}
pdpyp->driMajor = major;
pdpyp->driMinor = minor;
pdpyp->driPatch = patch;
pdisp->destroyDisplay = driDestroyDisplay;
/* allocate array of pointers to createScreen funcs */
pdisp->createScreen = (CreateScreenFunc *) Xmalloc(numScreens * sizeof(void *));
if (!pdisp->createScreen) {
XFree(pdpyp);
return NULL;
}
/* allocate array of library handles */
pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*));
if (!pdpyp->libraryHandles) {
Xfree(pdisp->createScreen);
XFree(pdpyp);
return NULL;
}
#ifdef BUILT_IN_DRI_DRIVER
/* we'll statically bind to the built-in __driCreateScreen function */
for (scrn = 0; scrn < numScreens; scrn++) {
pdisp->createScreen[scrn] = __driCreateScreen;
pdpyp->libraryHandles[scrn] = NULL;
}
#else
/* dynamically discover DRI drivers for all screens, saving each
* driver's "__driCreateScreen" function pointer. That's the bootstrap
* entrypoint for all DRI drivers.
*/
__glXRegisterExtensions();
for (scrn = 0; scrn < numScreens; scrn++) {
__DRIdriver *driver = driGetDriver(dpy, scrn);
if (driver) {
pdisp->createScreen[scrn] = driver->createScreenFunc;
pdpyp->libraryHandles[scrn] = driver->handle;
}
else {
pdisp->createScreen[scrn] = DummyCreateScreen;
pdpyp->libraryHandles[scrn] = NULL;
}
}
#endif
return (void *)pdpyp;
}
/*
** Here we'll query the DRI driver for each screen and let each
** driver register its GL extension functions. We only have to
** do this once.
**
** In older versions of libGL (prior to October 2002) we _always_
** called this function during libGL start-up. Now, we only call
** it from glXGetProcAddress() as a last resort.
**
** Two key things changed along the way:
** 1. _glapi_get_proc_address() now generates new dispatch stub functions
** anytime it gets an unknown "gl*" function name. I.e. we always return
** a valid function address and later patch it up to use the correct
** dispatch offset.
** 2. The GL API dispatch table is a fixed size (with plenty of extra slots).
** This means we don't have to register all new functions before we create
** the first dispatch table.
*/
void
__glXRegisterExtensions(void)
{
#ifndef BUILT_IN_DRI_DRIVER
static GLboolean alreadyCalled = GL_FALSE;
int displayNum, maxDisplays;
if (alreadyCalled)
return;
alreadyCalled = GL_TRUE;
if (getenv("LIBGL_MULTIHEAD")) {
/* we'd like to always take this path but doing so causes a second
* or more of delay while the XOpenDisplay() function times out.
*/
maxDisplays = 10; /* infinity, really */
}
else {
/* just open the :0 display */
maxDisplays = 1;
}
for (displayNum = 0; displayNum < maxDisplays; displayNum++) {
char displayName[200];
Display *dpy;
snprintf(displayName, 199, ":%d.0", displayNum);
dpy = XOpenDisplay(displayName);
if (dpy) {
const int numScreens = ScreenCount(dpy);
int screenNum;
for (screenNum = 0; screenNum < numScreens; screenNum++) {
__DRIdriver *driver = driGetDriver(dpy, screenNum);
if (driver && driver->registerExtensionsFunc) {
(*driver->registerExtensionsFunc)();
}
}
XCloseDisplay(dpy);
}
else {
break;
}
}
#endif
}

59
src/dri-es/dri_glx.h Normal file
View File

@@ -0,0 +1,59 @@
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
*
*/
#ifndef _DRI_GLX_H_
#define _DRI_GLX_H_
struct __DRIdisplayPrivateRec {
/*
** XFree86-DRI version information
*/
int driMajor;
int driMinor;
int driPatch;
/*
** Array of library handles [indexed by screen number]
*/
void **libraryHandles;
};
typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
typedef struct __DRIvisualPrivateRec __DRIvisualPrivate;
typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
#endif /* _DRI_GLX_H_ */

1109
src/dri-es/dri_util.c Normal file

File diff suppressed because it is too large Load Diff

375
src/dri-es/dri_util.h Normal file
View File

@@ -0,0 +1,375 @@
/* $XFree86$ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
*/
/*
* This module acts as glue between GLX and the actual hardware driver.
* A DRI driver doesn't really _have_ to use any of this - it's optional.
* But, some useful stuff is done here that otherwise would have to be
* duplicated in most drivers.
*
* Basically, these utility functions take care of some of the dirty details
* of screen initialization, context creation, context binding, DRM setup,
* etc.
*
* These functions are compiled into each DRI driver so libGL.so knows
* nothing about them.
*
* Look for more comments in the dri_util.c file.
*/
#ifndef _DRI_UTIL_H_
#define _DRI_UTIL_H_
#define CAPI /* XXX this should be globally defined somewhere */
#include "glxclient.h" /* for GLXDrawable */
#include "xf86dri.h" /* for XF86DRIClipRectPtr */
#include "sarea.h" /* for XF86DRISAREAPtr */
#include "GL/internal/glcore.h" /* for __GLcontextModes */
typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \
do { \
if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \
__driUtilUpdateDrawableInfo(pDrawPriv); \
} \
} while (0)
#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \
do { \
while (*(pdp->pStamp) != pdp->lastStamp) { \
DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \
pdp->driContextPriv->hHWContext); \
\
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
\
DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \
pdp->driContextPriv->hHWContext); \
} \
} while (0)
/* Each DRI driver must have one of these structs with all the pointers
* set to appropriate functions within the driver.
* When glXCreateContext is called, for example, it'll call a helper
* function dri_util.c which in turn will jump through the CreateContext
* pointer in this structure.
*/
struct __DriverAPIRec {
GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv);
GLboolean (*CreateContext)(const __GLcontextModes *glVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
void (*DestroyContext)(__DRIcontextPrivate *driContextPriv);
GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *glVis,
GLboolean pixmapBuffer);
void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv);
void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv);
GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv);
GLboolean (*OpenFullScreen)(__DRIcontextPrivate *driContextPriv);
GLboolean (*CloseFullScreen)(__DRIcontextPrivate *driContextPriv);
};
struct __DRIdrawablePrivateRec {
/*
** Kernel drawable handle (not currently used).
*/
drmDrawable hHWDrawable;
/*
** Driver's private drawable information. This structure is opaque.
*/
void *driverPrivate;
/*
** X's drawable ID associated with this private drawable.
*/
GLXDrawable draw;
/*
** Reference count for number of context's currently bound to this
** drawable. Once the refcount reaches 0, the drawable can be
** destroyed. This behavior will change with GLX 1.3.
*/
int refcount;
/*
** Index of this drawable's information in the SAREA.
*/
unsigned int index;
/*
** Pointer to the "drawable has changed ID" stamp in the SAREA.
*/
unsigned int *pStamp;
/*
** Last value of the stamp. If this differs from the value stored
** at *pStamp, then the drawable information has been modified by
** the X server, and the drawable information (below) should be
** retrieved from the X server.
*/
unsigned int lastStamp;
/*
** Drawable information used in software fallbacks.
*/
int x;
int y;
int w;
int h;
int numClipRects;
XF86DRIClipRectPtr pClipRects;
/*
** Information about the back and depthbuffer where different
** from above.
*/
int backX;
int backY;
int backClipRectType;
int numBackClipRects;
XF86DRIClipRectPtr pBackClipRects;
/*
** Pointer to context to which this drawable is currently bound.
*/
__DRIcontextPrivate *driContextPriv;
/*
** Pointer to screen on which this drawable was created.
*/
__DRIscreenPrivate *driScreenPriv;
/*
** Basically just need these for when the locking code needs to call
** __driUtilUpdateDrawableInfo() which calls XF86DRIGetDrawableInfo().
*/
Display *display;
int screen;
/*
** Called via glXSwapBuffers().
*/
void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
};
struct __DRIcontextPrivateRec {
/*
** Kernel context handle used to access the device lock.
*/
XID contextID;
/*
** Kernel context handle used to access the device lock.
*/
drmContext hHWContext;
/*
** Device driver's private context data. This structure is opaque.
*/
void *driverPrivate;
/*
** This context's display pointer.
*/
Display *display;
/*
** Pointer to drawable currently bound to this context.
*/
__DRIdrawablePrivate *driDrawablePriv;
/*
** Pointer to screen on which this context was created.
*/
__DRIscreenPrivate *driScreenPriv;
};
struct __DRIscreenPrivateRec {
/*
** Display for this screen
*/
Display *display;
/*
** Current screen's number
*/
int myNum;
/*
** Callback functions into the hardware-specific DRI driver code.
*/
struct __DriverAPIRec DriverAPI;
/*
** DDX / 2D driver version information.
*/
int ddxMajor;
int ddxMinor;
int ddxPatch;
/*
** DRI X extension version information.
*/
int driMajor;
int driMinor;
int driPatch;
/*
** DRM (kernel module) version information.
*/
int drmMajor;
int drmMinor;
int drmPatch;
/*
** ID used when the client sets the drawable lock. The X server
** uses this value to detect if the client has died while holding
** the drawable lock.
*/
int drawLockID;
/*
** File descriptor returned when the kernel device driver is opened.
** It is used to:
** - authenticate client to kernel
** - map the frame buffer, SAREA, etc.
** - close the kernel device driver
*/
int fd;
/*
** SAREA pointer used to access:
** - the device lock
** - the device-independent per-drawable and per-context(?) information
*/
XF86DRISAREAPtr pSAREA;
/*
** Direct frame buffer access information used for software
** fallbacks.
*/
unsigned char *pFB;
int fbSize;
int fbOrigin;
int fbStride;
int fbWidth;
int fbHeight;
int fbBPP;
/*
** Device-dependent private information (stored in the SAREA). This
** data is accessed by the client driver only.
*/
void *pDevPriv;
int devPrivSize;
/*
** Dummy context to which drawables are bound when not bound to any
** other context. A dummy hHWContext is created for this context,
** and is used by the GL core when a HW lock is required but the
** drawable is not currently bound (e.g., potentially during a
** SwapBuffers request). The dummy context is created when the
** first "real" context is created on this screen.
*/
__DRIcontextPrivate dummyContextPriv;
/*
** Hash table to hold the drawable information for this screen.
*/
void *drawHash;
/*
** Device-dependent private information (not stored in the SAREA).
** This pointer is never touched by the DRI layer.
*/
void *private;
/* If we're in full screen mode (via DRIOpenFullScreen), this points
to the drawable that was bound. Otherwise, this is NULL. */
__DRIdrawablePrivate *fullscreen;
/*
** Number of visuals (configs) for this screen, and a pointer to them.
*/
int numConfigs;
__GLXvisualConfig *configs;
};
extern void
__driUtilMessage(const char *f, ...);
extern void
__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp);
extern __DRIscreenPrivate *
__driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config,
const struct __DriverAPIRec *driverAPI);
/* This must be implemented in each driver */
extern void *
__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config);
/* This is optionally implemented in each driver */
extern void
__driRegisterExtensions( void );
#endif /* _DRI_UTIL_H_ */

474
src/dri-es/drm.h Normal file
View File

@@ -0,0 +1,474 @@
/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* 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 (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
* VA LINUX SYSTEMS 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:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
* Acknowledgements:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
*
*/
#ifndef _DRM_H_
#define _DRM_H_
#if defined(__linux__)
#include <linux/config.h>
#include <asm/ioctl.h> /* For _IO* macros */
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IOC_VOID _IOC_NONE
#define DRM_IOC_READ _IOC_READ
#define DRM_IOC_WRITE _IOC_WRITE
#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
#if defined(__FreeBSD__) && defined(XFree86Server)
/* Prevent name collision when including sys/ioccom.h */
#undef ioctl
#include <sys/ioccom.h>
#define ioctl(a,b,c) xf86ioctl(a,b,c)
#else
#include <sys/ioccom.h>
#endif /* __FreeBSD__ && xf86ioctl */
#define DRM_IOCTL_NR(n) ((n) & 0xff)
#define DRM_IOC_VOID IOC_VOID
#define DRM_IOC_READ IOC_OUT
#define DRM_IOC_WRITE IOC_IN
#define DRM_IOC_READWRITE IOC_INOUT
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#endif
#define XFREE86_VERSION(major,minor,patch,snap) \
((major << 16) | (minor << 8) | patch)
#ifndef CONFIG_XFREE86_VERSION
#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
#endif
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
#define DRM_PROC_DEVICES "/proc/devices"
#define DRM_PROC_MISC "/proc/misc"
#define DRM_PROC_DRM "/proc/drm"
#define DRM_DEV_DRM "/dev/drm"
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define DRM_DEV_UID 0
#define DRM_DEV_GID 0
#endif
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
#define DRM_MAJOR 226
#define DRM_MAX_MINOR 15
#endif
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
#define DRM_RAM_PERCENT 10 /* How much system ram can we lock? */
#define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
#define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
typedef unsigned long drm_handle_t;
typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */
/* KW: Actually it's illegal to change either for
* backwards-compatibility reasons.
*/
typedef struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
unsigned short x2;
unsigned short y2;
} drm_clip_rect_t;
typedef struct drm_tex_region {
unsigned char next;
unsigned char prev;
unsigned char in_use;
unsigned char padding;
unsigned int age;
} drm_tex_region_t;
typedef struct drm_version {
int version_major; /* Major version */
int version_minor; /* Minor version */
int version_patchlevel;/* Patch level */
size_t name_len; /* Length of name buffer */
char *name; /* Name of driver */
size_t date_len; /* Length of date buffer */
char *date; /* User-space buffer to hold date */
size_t desc_len; /* Length of desc buffer */
char *desc; /* User-space buffer to hold desc */
} drm_version_t;
typedef struct drm_unique {
size_t unique_len; /* Length of unique */
char *unique; /* Unique name for driver instantiation */
} drm_unique_t;
typedef struct drm_list {
int count; /* Length of user-space structures */
drm_version_t *version;
} drm_list_t;
typedef struct drm_block {
int unused;
} drm_block_t;
typedef struct drm_control {
enum {
DRM_ADD_COMMAND,
DRM_RM_COMMAND,
DRM_INST_HANDLER,
DRM_UNINST_HANDLER
} func;
int irq;
} drm_control_t;
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
_DRM_REGISTERS = 1, /* no caching, no core dump */
_DRM_SHM = 2, /* shared, cached */
_DRM_AGP = 3, /* AGP/GART */
_DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
} drm_map_type_t;
typedef enum drm_map_flags {
_DRM_RESTRICTED = 0x01, /* Cannot be mapped to user-virtual */
_DRM_READ_ONLY = 0x02,
_DRM_LOCKED = 0x04, /* shared, cached, locked */
_DRM_KERNEL = 0x08, /* kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
_DRM_REMOVABLE = 0x40 /* Removable mapping */
} drm_map_flags_t;
typedef struct drm_ctx_priv_map {
unsigned int ctx_id; /* Context requesting private mapping */
void *handle; /* Handle of map */
} drm_ctx_priv_map_t;
typedef struct drm_map {
unsigned long offset; /* Requested physical address (0 for SAREA)*/
unsigned long size; /* Requested physical size (bytes) */
drm_map_type_t type; /* Type of memory to map */
drm_map_flags_t flags; /* Flags */
void *handle; /* User-space: "Handle" to pass to mmap */
/* Kernel-space: kernel-virtual address */
int mtrr; /* MTRR slot used */
/* Private data */
} drm_map_t;
typedef struct drm_client {
int idx; /* Which client desired? */
int auth; /* Is client authenticated? */
unsigned long pid; /* Process id */
unsigned long uid; /* User id */
unsigned long magic; /* Magic */
unsigned long iocs; /* Ioctl count */
} drm_client_t;
typedef enum {
_DRM_STAT_LOCK,
_DRM_STAT_OPENS,
_DRM_STAT_CLOSES,
_DRM_STAT_IOCTLS,
_DRM_STAT_LOCKS,
_DRM_STAT_UNLOCKS,
_DRM_STAT_VALUE, /* Generic value */
_DRM_STAT_BYTE, /* Generic byte counter (1024bytes/K) */
_DRM_STAT_COUNT, /* Generic non-byte counter (1000/k) */
_DRM_STAT_IRQ, /* IRQ */
_DRM_STAT_PRIMARY, /* Primary DMA bytes */
_DRM_STAT_SECONDARY, /* Secondary DMA bytes */
_DRM_STAT_DMA, /* DMA */
_DRM_STAT_SPECIAL, /* Special DMA (e.g., priority or polled) */
_DRM_STAT_MISSED /* Missed DMA opportunity */
/* Add to the *END* of the list */
} drm_stat_type_t;
typedef struct drm_stats {
unsigned long count;
struct {
unsigned long value;
drm_stat_type_t type;
} data[15];
} drm_stats_t;
typedef enum drm_lock_flags {
_DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
_DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
_DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
_DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */
/* These *HALT* flags aren't supported yet
-- they will be used to support the
full-screen DGA-like mode. */
_DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
_DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
} drm_lock_flags_t;
typedef struct drm_lock {
int context;
drm_lock_flags_t flags;
} drm_lock_t;
typedef enum drm_dma_flags { /* These values *MUST* match xf86drm.h */
/* Flags for DMA buffer dispatch */
_DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched.
Note, the buffer may not yet have
been processed by the hardware --
getting a hardware lock with the
hardware quiescent will ensure
that the buffer has been
processed. */
_DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */
_DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */
/* Flags for DMA buffer request */
_DRM_DMA_WAIT = 0x10, /* Wait for free buffers */
_DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */
_DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */
} drm_dma_flags_t;
typedef struct drm_buf_desc {
int count; /* Number of buffers of this size */
int size; /* Size in bytes */
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
enum {
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
_DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
_DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
} flags;
unsigned long agp_start; /* Start address of where the agp buffers
* are in the agp aperture */
} drm_buf_desc_t;
typedef struct drm_buf_info {
int count; /* Entries in list */
drm_buf_desc_t *list;
} drm_buf_info_t;
typedef struct drm_buf_free {
int count;
int *list;
} drm_buf_free_t;
typedef struct drm_buf_pub {
int idx; /* Index into master buflist */
int total; /* Buffer size */
int used; /* Amount of buffer in use (for DMA) */
void *address; /* Address of buffer */
} drm_buf_pub_t;
typedef struct drm_buf_map {
int count; /* Length of buflist */
void *virtual; /* Mmaped area in user-virtual */
drm_buf_pub_t *list; /* Buffer information */
} drm_buf_map_t;
typedef struct drm_dma {
/* Indices here refer to the offset into
buflist in drm_buf_get_t. */
int context; /* Context handle */
int send_count; /* Number of buffers to send */
int *send_indices; /* List of handles to buffers */
int *send_sizes; /* Lengths of data to send */
drm_dma_flags_t flags; /* Flags */
int request_count; /* Number of buffers requested */
int request_size; /* Desired size for buffers */
int *request_indices; /* Buffer information */
int *request_sizes;
int granted_count; /* Number of buffers granted */
} drm_dma_t;
typedef enum {
_DRM_CONTEXT_PRESERVED = 0x01,
_DRM_CONTEXT_2DONLY = 0x02
} drm_ctx_flags_t;
typedef struct drm_ctx {
drm_context_t handle;
drm_ctx_flags_t flags;
} drm_ctx_t;
typedef struct drm_ctx_res {
int count;
drm_ctx_t *contexts;
} drm_ctx_res_t;
typedef struct drm_draw {
drm_drawable_t handle;
} drm_draw_t;
typedef struct drm_auth {
drm_magic_t magic;
} drm_auth_t;
typedef struct drm_irq_busid {
int irq;
int busnum;
int devnum;
int funcnum;
} drm_irq_busid_t;
typedef enum {
_DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
_DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drm_vblank_seq_type_t;
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
struct drm_wait_vblank_request {
drm_vblank_seq_type_t type;
unsigned int sequence;
unsigned long signal;
};
struct drm_wait_vblank_reply {
drm_vblank_seq_type_t type;
unsigned int sequence;
long tval_sec;
long tval_usec;
};
typedef union drm_wait_vblank {
struct drm_wait_vblank_request request;
struct drm_wait_vblank_reply reply;
} drm_wait_vblank_t;
typedef struct drm_agp_mode {
unsigned long mode;
} drm_agp_mode_t;
/* For drm_agp_alloc -- allocated a buffer */
typedef struct drm_agp_buffer {
unsigned long size; /* In bytes -- will round to page boundary */
unsigned long handle; /* Used for BIND/UNBIND ioctls */
unsigned long type; /* Type of memory to allocate */
unsigned long physical; /* Physical used by i810 */
} drm_agp_buffer_t;
/* For drm_agp_bind */
typedef struct drm_agp_binding {
unsigned long handle; /* From drm_agp_buffer */
unsigned long offset; /* In bytes -- will round to page boundary */
} drm_agp_binding_t;
typedef struct drm_agp_info {
int agp_version_major;
int agp_version_minor;
unsigned long mode;
unsigned long aperture_base; /* physical address */
unsigned long aperture_size; /* bytes */
unsigned long memory_allowed; /* bytes */
unsigned long memory_used;
/* PCI information */
unsigned short id_vendor;
unsigned short id_device;
} drm_agp_info_t;
typedef struct drm_scatter_gather {
unsigned long size; /* In bytes -- will round to page boundary */
unsigned long handle; /* Used for mapping / unmapping */
} drm_scatter_gather_t;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t)
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t)
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
/* Device specfic ioctls should only be in their respective headers
* The device specific ioctl range is 0x40 to 0x79. */
#define DRM_COMMAND_BASE 0x40
#endif

224
src/dri-es/extutil.h Normal file
View File

@@ -0,0 +1,224 @@
/*
* $Xorg: extutil.h,v 1.4 2001/02/09 02:03:24 xorgcvs Exp $
*
Copyright 1989, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
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 THE
OPEN GROUP 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.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*
* Author: Jim Fulton, MIT The Open Group
*
* Xlib Extension-Writing Utilities
*
* This package contains utilities for writing the client API for various
* protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
* ARE SUBJECT TO CHANGE!
*/
/* $XFree86: xc/include/extensions/extutil.h,v 1.9 2001/12/14 19:53:28 dawes Exp $ */
#ifndef _EXTUTIL_H_
#define _EXTUTIL_H_
#include <X11/extensions/Xext.h>
/*
* We need to keep a list of open displays since the Xlib display list isn't
* public. We also have to per-display info in a separate block since it isn't
* stored directly in the Display structure.
*/
typedef struct _XExtDisplayInfo {
struct _XExtDisplayInfo *next; /* keep a linked list */
Display *display; /* which display this is */
XExtCodes *codes; /* the extension protocol codes */
XPointer data; /* extra data for extension to use */
} XExtDisplayInfo;
typedef struct _XExtensionInfo {
XExtDisplayInfo *head; /* start of list */
XExtDisplayInfo *cur; /* most recently used */
int ndisplays; /* number of displays */
} XExtensionInfo;
typedef struct _XExtensionHooks {
int (*create_gc)(
#if NeedNestedPrototypes
Display* /* display */,
GC /* gc */,
XExtCodes* /* codes */
#endif
);
int (*copy_gc)(
#if NeedNestedPrototypes
Display* /* display */,
GC /* gc */,
XExtCodes* /* codes */
#endif
);
int (*flush_gc)(
#if NeedNestedPrototypes
Display* /* display */,
GC /* gc */,
XExtCodes* /* codes */
#endif
);
int (*free_gc)(
#if NeedNestedPrototypes
Display* /* display */,
GC /* gc */,
XExtCodes* /* codes */
#endif
);
int (*create_font)(
#if NeedNestedPrototypes
Display* /* display */,
XFontStruct* /* fs */,
XExtCodes* /* codes */
#endif
);
int (*free_font)(
#if NeedNestedPrototypes
Display* /* display */,
XFontStruct* /* fs */,
XExtCodes* /* codes */
#endif
);
int (*close_display)(
#if NeedNestedPrototypes
Display* /* display */,
XExtCodes* /* codes */
#endif
);
Bool (*wire_to_event)(
#if NeedNestedPrototypes
Display* /* display */,
XEvent* /* re */,
xEvent* /* event */
#endif
);
Status (*event_to_wire)(
#if NeedNestedPrototypes
Display* /* display */,
XEvent* /* re */,
xEvent* /* event */
#endif
);
int (*error)(
#if NeedNestedPrototypes
Display* /* display */,
xError* /* err */,
XExtCodes* /* codes */,
int* /* ret_code */
#endif
);
char *(*error_string)(
#if NeedNestedPrototypes
Display* /* display */,
int /* code */,
XExtCodes* /* codes */,
char* /* buffer */,
int /* nbytes */
#endif
);
} XExtensionHooks;
extern XExtensionInfo *XextCreateExtension(
#if NeedFunctionPrototypes
void
#endif
);
extern void XextDestroyExtension(
#if NeedFunctionPrototypes
XExtensionInfo* /* info */
#endif
);
extern XExtDisplayInfo *XextAddDisplay(
#if NeedFunctionPrototypes
XExtensionInfo* /* extinfo */,
Display* /* dpy */,
char* /* ext_name */,
XExtensionHooks* /* hooks */,
int /* nevents */,
XPointer /* data */
#endif
);
extern int XextRemoveDisplay(
#if NeedFunctionPrototypes
XExtensionInfo* /* extinfo */,
Display* /* dpy */
#endif
);
extern XExtDisplayInfo *XextFindDisplay(
#if NeedFunctionPrototypes
XExtensionInfo* /* extinfo */,
Display* /* dpy */
#endif
);
#define XextHasExtension(i) ((i) && ((i)->codes))
#define XextCheckExtension(dpy,i,name,val) \
if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; }
#define XextSimpleCheckExtension(dpy,i,name) \
if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; }
/*
* helper macros to generate code that is common to all extensions; caller
* should prefix it with static if extension source is in one file; this
* could be a utility function, but have to stack 6 unused arguments for
* something that is called many, many times would be bad.
*/
#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \
XExtDisplayInfo *proc (Display *dpy) \
{ \
XExtDisplayInfo *dpyinfo; \
if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \
if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \
dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \
return dpyinfo; \
}
#define XEXT_FIND_DISPLAY_PROTO(proc) \
XExtDisplayInfo *proc(Display *dpy)
#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \
int proc (Display *dpy, XExtCodes *codes) \
{ \
return XextRemoveDisplay (extinfo, dpy); \
}
#define XEXT_CLOSE_DISPLAY_PROTO(proc) \
int proc(Display *dpy, XExtCodes *codes)
#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \
char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \
{ \
code -= codes->first_error; \
if (code >= 0 && code < nerr) { \
char tmp[256]; \
sprintf (tmp, "%s.%d", extname, code); \
XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \
return buf; \
} \
return (char *)0; \
}
#define XEXT_ERROR_STRING_PROTO(proc) \
char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n)
#endif

678
src/dri-es/glxclient.h Normal file
View File

@@ -0,0 +1,678 @@
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
*/
/* $XFree86: xc/lib/GL/glx/glxclient.h,v 1.14 2002/02/22 21:32:53 dawes Exp $ */
/*
* Direct rendering support added by Precision Insight, Inc.
*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
*
*/
#ifndef _GLX_client_h_
#define _GLX_client_h_
#define NEED_REPLIES
#define NEED_EVENTS
#include <X11/Xproto.h>
#include <X11/Xlibint.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#include <string.h>
#include <stdlib.h>
#include "GL/glxint.h"
#include "GL/glxproto.h"
#include "glapitable.h"
#ifdef NEED_GL_FUNCS_WRAPPED
#include "indirect.h"
#endif
#ifdef XTHREADS
#include "Xthreads.h"
#endif
#ifdef GLX_BUILT_IN_XMESA
#include "realglx.h" /* just silences prototype warnings */
#endif
#define GLX_MAJOR_VERSION 1 /* current version numbers */
#define GLX_MINOR_VERSION 2
#define __GL_BOOLEAN_ARRAY (GL_BYTE - 1)
#define __GLX_MAX_TEXTURE_UNITS 32
typedef struct __GLXcontextRec __GLXcontext;
typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate;
typedef struct _glapi_table __GLapi;
/************************************************************************/
/*
** The following structures define the interface between the GLX client
** side library and the DRI (direct rendering infrastructure).
*/
typedef struct __DRIdisplayRec __DRIdisplay;
typedef struct __DRIscreenRec __DRIscreen;
typedef struct __DRIcontextRec __DRIcontext;
typedef struct __DRIdrawableRec __DRIdrawable;
typedef struct __DRIdriverRec __DRIdriver;
extern __DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn);
/*
** Display dependent methods. This structure is initialized during the
** driCreateDisplay() call.
*/
struct __DRIdisplayRec {
/*
** Method to destroy the private DRI display data.
*/
void (*destroyDisplay)(Display *dpy, void *displayPrivate);
/*
** Methods to create the private DRI screen data and initialize the
** screen dependent methods.
** This is an array [indexed by screen number] of function pointers.
*/
void *(**createScreen)(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config);
/*
** Opaque pointer to private per display direct rendering data.
** NULL if direct rendering is not supported on this display. Never
** dereferenced in libGL.
*/
void *private;
};
/*
** Screen dependent methods. This structure is initialized during the
** (*createScreen)() call.
*/
struct __DRIscreenRec {
/*
** Method to destroy the private DRI screen data.
*/
void (*destroyScreen)(Display *dpy, int scrn, void *screenPrivate);
/*
** Method to create the private DRI context data and initialize the
** context dependent methods.
*/
void *(*createContext)(Display *dpy, XVisualInfo *vis, void *sharedPrivate,
__DRIcontext *pctx);
/*
** Method to create the private DRI drawable data and initialize the
** drawable dependent methods.
*/
void *(*createDrawable)(Display *dpy, int scrn, GLXDrawable draw,
VisualID vid, __DRIdrawable *pdraw);
/*
** Method to return a pointer to the DRI drawable data.
*/
__DRIdrawable *(*getDrawable)(Display *dpy, GLXDrawable draw,
void *drawablePrivate);
/*
** XXX in the future, implement this:
void *(*createPBuffer)(Display *dpy, int scrn, GLXPbuffer pbuffer,
GLXFBConfig config, __DRIdrawable *pdraw);
**/
/*
** Opaque pointer to private per screen direct rendering data. NULL
** if direct rendering is not supported on this screen. Never
** dereferenced in libGL.
*/
void *private;
};
/*
** Context dependent methods. This structure is initialized during the
** (*createContext)() call.
*/
struct __DRIcontextRec {
/*
** Method to destroy the private DRI context data.
*/
void (*destroyContext)(Display *dpy, int scrn, void *contextPrivate);
/*
** Method to bind a DRI drawable to a DRI graphics context.
** XXX in the future, also pass a 'read' GLXDrawable for
** glXMakeCurrentReadSGI() and GLX 1.3's glXMakeContextCurrent().
*/
Bool (*bindContext)(Display *dpy, int scrn, GLXDrawable draw,
GLXContext gc);
/*
** Method to unbind a DRI drawable to a DRI graphics context.
*/
Bool (*unbindContext)(Display *dpy, int scrn, GLXDrawable draw,
GLXContext gc, int will_rebind);
/*
** Opaque pointer to private per context direct rendering data.
** NULL if direct rendering is not supported on the display or
** screen used to create this context. Never dereferenced in libGL.
*/
void *private;
};
/*
** Drawable dependent methods. This structure is initialized during the
** (*createDrawable)() call. createDrawable() is not called by libGL at
** this time. It's currently used via the dri_util.c utility code instead.
*/
struct __DRIdrawableRec {
/*
** Method to destroy the private DRI drawable data.
*/
void (*destroyDrawable)(Display *dpy, void *drawablePrivate);
/*
** Method to swap the front and back buffers.
*/
void (*swapBuffers)(Display *dpy, void *drawablePrivate);
/*
** Opaque pointer to private per drawable direct rendering data.
** NULL if direct rendering is not supported on the display or
** screen used to create this drawable. Never dereferenced in libGL.
*/
void *private;
};
typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config);
typedef void *(*RegisterExtensionsFunc)(void);
/*
** We keep a linked list of these structures, one per DRI device driver.
*/
struct __DRIdriverRec {
const char *name;
void *handle;
CreateScreenFunc createScreenFunc;
RegisterExtensionsFunc registerExtensionsFunc;
struct __DRIdriverRec *next;
};
/*
** Function to create and DRI display data and initialize the display
** dependent methods.
*/
extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
extern __DRIdriver *driGetDriver(Display *dpy, int scrNum);
extern void DRI_glXUseXFont( Font font, int first, int count, int listbase );
/************************************************************************/
#define __GL_CLIENT_ATTRIB_STACK_DEPTH 16
typedef struct __GLXpixelStoreModeRec {
GLboolean swapEndian;
GLboolean lsbFirst;
GLuint rowLength;
GLuint imageHeight;
GLuint imageDepth;
GLuint skipRows;
GLuint skipPixels;
GLuint skipImages;
GLuint alignment;
} __GLXpixelStoreMode;
typedef struct __GLXvertexArrayPointerStateRec {
GLboolean enable;
void (*proc)(const void *);
const GLubyte *ptr;
GLsizei skip;
GLint size;
GLenum type;
GLsizei stride;
} __GLXvertexArrayPointerState;
typedef struct __GLXvertArrayStateRec {
__GLXvertexArrayPointerState vertex;
__GLXvertexArrayPointerState normal;
__GLXvertexArrayPointerState color;
__GLXvertexArrayPointerState index;
__GLXvertexArrayPointerState texCoord[__GLX_MAX_TEXTURE_UNITS];
__GLXvertexArrayPointerState edgeFlag;
GLint maxElementsVertices;
GLint maxElementsIndices;
GLint activeTexture;
} __GLXvertArrayState;
typedef struct __GLXattributeRec {
GLuint mask;
/*
** Pixel storage state. Most of the pixel store mode state is kept
** here and used by the client code to manage the packing and
** unpacking of data sent to/received from the server.
*/
__GLXpixelStoreMode storePack, storeUnpack;
/*
** Vertex Array storage state. The vertex array component
** state is stored here and is used to manage the packing of
** DrawArrays data sent to the server.
*/
__GLXvertArrayState vertArray;
} __GLXattribute;
typedef struct __GLXattributeMachineRec {
__GLXattribute *stack[__GL_CLIENT_ATTRIB_STACK_DEPTH];
__GLXattribute **stackPointer;
} __GLXattributeMachine;
/*
** GLX state that needs to be kept on the client. One of these records
** exist for each context that has been made current by this client.
*/
struct __GLXcontextRec {
/*
** Drawing command buffer. Drawing commands are packed into this
** buffer before being sent as a single GLX protocol request. The
** buffer is sent when it overflows or is flushed by
** __glXFlushRenderBuffer. "pc" is the next location in the buffer
** to be filled. "limit" is described above in the buffer slop
** discussion.
**
** Commands that require large amounts of data to be transfered will
** also use this buffer to hold a header that describes the large
** command.
**
** These must be the first 6 fields since they are static initialized
** in the dummy context in glxext.c
*/
GLubyte *buf;
GLubyte *pc;
GLubyte *limit;
GLubyte *bufEnd;
GLint bufSize;
/*
** The XID of this rendering context. When the context is created a
** new XID is allocated. This is set to None when the context is
** destroyed but is still current to some thread. In this case the
** context will be freed on next MakeCurrent.
*/
XID xid;
/*
** The XID of the shareList context.
*/
XID share_xid;
/*
** Visual id.
*/
VisualID vid;
/*
** screen number.
*/
GLint screen;
/*
** GL_TRUE if the context was created with ImportContext, which
** means the server-side context was created by another X client.
*/
GLboolean imported;
/*
** The context tag returned by MakeCurrent when this context is made
** current. This tag is used to identify the context that a thread has
** current so that proper server context management can be done. It is
** used for all context specific commands (i.e., Render, RenderLarge,
** WaitX, WaitGL, UseXFont, and MakeCurrent (for the old context)).
*/
GLXContextTag currentContextTag;
/*
** The rendering mode is kept on the client as well as the server.
** When glRenderMode() is called, the buffer associated with the
** previous rendering mode (feedback or select) is filled.
*/
GLenum renderMode;
GLfloat *feedbackBuf;
GLuint *selectBuf;
/*
** This is GL_TRUE if the pixel unpack modes are such that an image
** can be unpacked from the clients memory by just copying. It may
** still be true that the server will have to do some work. This
** just promises that a straight copy will fetch the correct bytes.
*/
GLboolean fastImageUnpack;
/*
** Fill newImage with the unpacked form of oldImage getting it
** ready for transport to the server.
*/
void (*fillImage)(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
GLenum, const GLvoid*, GLubyte*, GLubyte*);
/*
** Client side attribs.
*/
__GLXattribute state;
__GLXattributeMachine attributes;
/*
** Client side error code. This is set when client side gl API
** routines need to set an error because of a bad enumerant or
** running out of memory, etc.
*/
GLenum error;
/*
** Whether this context does direct rendering.
*/
Bool isDirect;
/*
** dpy of current display for this context. Will be NULL if not
** current to any display, or if this is the "dummy context".
*/
Display *currentDpy;
/*
** The current drawable for this context. Will be None if this
** context is not current to any drawable.
*/
GLXDrawable currentDrawable;
/*
** Constant strings that describe the server implementation
** These pertain to GL attributes, not to be confused with
** GLX versioning attributes.
*/
GLubyte *vendor;
GLubyte *renderer;
GLubyte *version;
GLubyte *extensions;
/* Record the dpy this context was created on for later freeing */
Display *createDpy;
/*
** Maximum small render command size. This is the smaller of 64k and
** the size of the above buffer.
*/
GLint maxSmallRenderCommandSize;
/*
** Major opcode for the extension. Copied here so a lookup isn't
** needed.
*/
GLint majorOpcode;
/*
** Per context direct rendering interface functions and data.
*/
__DRIcontext driContext;
};
#define __glXSetError(gc,code) \
if (!(gc)->error) { \
(gc)->error = code; \
}
extern void __glFreeAttributeState(__GLXcontext *);
/************************************************************************/
/*
** The size of the largest drawing command known to the implementation
** that will use the GLXRender glx command. In this case it is
** glPolygonStipple.
*/
#define __GLX_MAX_SMALL_RENDER_CMD_SIZE 156
/*
** To keep the implementation fast, the code uses a "limit" pointer
** to determine when the drawing command buffer is too full to hold
** another fixed size command. This constant defines the amount of
** space that must always be available in the drawing command buffer
** at all times for the implementation to work. It is important that
** the number be just large enough, but not so large as to reduce the
** efficacy of the buffer. The "+32" is just to keep the code working
** in case somebody counts wrong.
*/
#define __GLX_BUFFER_LIMIT_SIZE (__GLX_MAX_SMALL_RENDER_CMD_SIZE + 32)
/*
** This implementation uses a smaller threshold for switching
** to the RenderLarge protocol than the protcol requires so that
** large copies don't occur.
*/
#define __GLX_RENDER_CMD_SIZE_LIMIT 4096
/*
** One of these records exists per screen of the display. It contains
** a pointer to the config data for that screen (if the screen supports GL).
*/
typedef struct __GLXscreenConfigsRec {
__GLXvisualConfig *configs;
int numConfigs;
const char *serverGLXexts;
char *effectiveGLXexts;
/*
** Per screen direct rendering interface functions and data.
*/
__DRIscreen driScreen;
} __GLXscreenConfigs;
/*
** Per display private data. One of these records exists for each display
** that is using the OpenGL (GLX) extension.
*/
struct __GLXdisplayPrivateRec {
/*
** Back pointer to the display
*/
Display *dpy;
/*
** The majorOpcode is common to all connections to the same server.
** It is also copied into the context structure.
*/
int majorOpcode;
/*
** Major and minor version returned by the server during initialization.
*/
int majorVersion, minorVersion;
/* Storage for the servers GLX vendor and versions strings. These
** are the same for all screens on this display. These fields will
** be filled in on demand.
*/
char *serverGLXvendor;
char *serverGLXversion;
/*
** Configurations of visuals for all screens on this display.
** Also, per screen data which now includes the server GLX_EXTENSION
** string.
*/
__GLXscreenConfigs *screenConfigs;
/*
** Per display direct rendering interface functions and data.
*/
__DRIdisplay driDisplay;
};
void __glXFreeContext(__GLXcontext*);
extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint,
const GLvoid *, GLint);
/* Initialize the GLX extension for dpy */
extern __GLXdisplayPrivate *__glXInitialize(Display*);
/* Query drivers for dynamically registered extensions */
extern void __glXRegisterExtensions(void);
/* Functions for extending the GLX API: */
extern void *__glXRegisterGLXFunction(const char *funcName, void *funcAddr);
extern void __glXRegisterGLXExtensionString(const char *extName);
/************************************************************************/
extern int __glXDebug;
/* This is per-thread storage in an MT environment */
#if defined(XTHREADS)
extern __GLXcontext *__glXGetCurrentContext(void);
extern void __glXSetCurrentContext(__GLXcontext *c);
#else
extern __GLXcontext *__glXcurrentContext;
#define __glXGetCurrentContext() __glXcurrentContext
#define __glXSetCurrentContext(gc) __glXcurrentContext = gc
#endif
/*
** Global lock for all threads in this address space using the GLX
** extension
*/
#if defined(XTHREADS)
extern xmutex_rec __glXmutex;
#define __glXLock() xmutex_lock(&__glXmutex)
#define __glXUnlock() xmutex_unlock(&__glXmutex)
#else
#define __glXLock()
#define __glXUnlock()
#endif
/*
** Setup for a command. Initialize the extension for dpy if necessary.
*/
extern CARD8 __glXSetupForCommand(Display *dpy);
/************************************************************************/
/*
** Data conversion and packing support.
*/
/* Return the size, in bytes, of some pixel data */
extern GLint __glImageSize(GLint, GLint, GLint, GLenum, GLenum);
/* Return the k value for a given map target */
extern GLint __glEvalComputeK(GLenum);
/*
** Fill the transport buffer with the data from the users buffer,
** applying some of the pixel store modes (unpack modes) to the data
** first. As a side effect of this call, the "modes" field is
** updated to contain the modes needed by the server to decode the
** sent data.
*/
extern void __glFillImage(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
GLenum, const GLvoid*, GLubyte*, GLubyte*);
/* Copy map data with a stride into a packed buffer */
extern void __glFillMap1f(GLint, GLint, GLint, const GLfloat *, GLubyte *);
extern void __glFillMap1d(GLint, GLint, GLint, const GLdouble *, GLubyte *);
extern void __glFillMap2f(GLint, GLint, GLint, GLint, GLint,
const GLfloat *, GLfloat *);
extern void __glFillMap2d(GLint, GLint, GLint, GLint, GLint,
const GLdouble *, GLdouble *);
/*
** Empty an image out of the reply buffer into the clients memory applying
** the pack modes to pack back into the clients requested format.
*/
extern void __glEmptyImage(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
GLenum, const GLubyte *, GLvoid *);
/*
** Allocate and Initialize Vertex Array client state
*/
extern void __glXInitVertexArrayState(__GLXcontext*);
/*
** Inform the Server of the major and minor numbers and of the client
** libraries extension string.
*/
extern void __glXClientInfo ( Display *dpy, int opcode );
/************************************************************************/
/*
** Declarations that should be in Xlib
*/
#ifdef __GL_USE_OUR_PROTOTYPES
extern void _XFlush(Display*);
extern Status _XReply(Display*, xReply*, int, Bool);
extern void _XRead(Display*, void*, long);
extern void _XSend(Display*, const void*, long);
#endif
/*
** GLX_BUILT_IN_XMESA controls whether libGL has a built-in verions of
** Mesa that can render to non-GLX displays.
*/
#ifdef GLX_BUILT_IN_XMESA
#define GLX_PREFIX(function) _real_##function
#else
#define GLX_PREFIX(function) function
#endif
extern char *__glXstrdup(const char *str);
extern int __glXGetInternalVersion(void);
extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw);
#endif /* !__GLX_client_h__ */

80
src/dri-es/sarea.h Normal file
View File

@@ -0,0 +1,80 @@
/* $XFree86: xc/programs/Xserver/GL/dri/sarea.h,v 1.10 2001/10/04 18:28:20 alanh Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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:
* Kevin E. Martin <kevin@precisioninsight.com>
* Jens Owen <jens@tungstengraphics.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
#ifndef _SAREA_H_
#define _SAREA_H_
#include "xf86drm.h"
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000
#elif defined(__ia64__)
#define SAREA_MAX 0x10000 /* 64kB */
#else
/* Intel 830M driver needs at least 8k SAREA */
#define SAREA_MAX 0x2000
#endif
#define SAREA_MAX_DRAWABLES 256
#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000
typedef struct _XF86DRISAREADrawable {
unsigned int stamp;
unsigned int flags;
} XF86DRISAREADrawableRec, *XF86DRISAREADrawablePtr;
typedef struct _XF86DRISAREAFrame {
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
unsigned int fullscreen;
} XF86DRISAREAFrameRec, *XF86DRISAREAFramePtr;
typedef struct _XF86DRISAREA {
/* first thing is always the drm locking structure */
drmLock lock;
/* NOT_DONE: Use readers/writer lock for drawable_lock */
drmLock drawable_lock;
XF86DRISAREADrawableRec drawableTable[SAREA_MAX_DRAWABLES];
XF86DRISAREAFrameRec frame;
drmContext dummy_context;
} XF86DRISAREARec, *XF86DRISAREAPtr;
#endif

227
src/dri-es/xf86dri.h Normal file
View File

@@ -0,0 +1,227 @@
/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.7 2000/12/07 20:26:02 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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:
* Kevin E. Martin <martin@valinux.com>
* Jens Owen <jens@tungstengraphics.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
#ifndef _XF86DRI_H_
#define _XF86DRI_H_
#include <X11/Xfuncproto.h>
#include <xf86drm.h>
#define X_XF86DRIQueryVersion 0
#define X_XF86DRIQueryDirectRenderingCapable 1
#define X_XF86DRIOpenConnection 2
#define X_XF86DRICloseConnection 3
#define X_XF86DRIGetClientDriverName 4
#define X_XF86DRICreateContext 5
#define X_XF86DRIDestroyContext 6
#define X_XF86DRICreateDrawable 7
#define X_XF86DRIDestroyDrawable 8
#define X_XF86DRIGetDrawableInfo 9
#define X_XF86DRIGetDeviceInfo 10
#define X_XF86DRIAuthConnection 11
#define X_XF86DRIOpenFullScreen 12
#define X_XF86DRICloseFullScreen 13
#define XF86DRINumberEvents 0
#define XF86DRIClientNotLocal 0
#define XF86DRIOperationNotSupported 1
#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
/* Warning : Do not change XF86DRIClipRect without changing the kernel
* structure! */
typedef struct _XF86DRIClipRect {
unsigned short x1; /* Upper left: inclusive */
unsigned short y1;
unsigned short x2; /* Lower right: exclusive */
unsigned short y2;
} XF86DRIClipRectRec, *XF86DRIClipRectPtr;
#ifndef _XF86DRI_SERVER_
_XFUNCPROTOBEGIN
Bool XF86DRIQueryExtension(
#if NeedFunctionPrototypes
Display* /* dpy */,
int* /* event_base */,
int* /* error_base */
#endif
);
Bool XF86DRIQueryVersion(
#if NeedFunctionPrototypes
Display* /* dpy */,
int* /* majorVersion */,
int* /* minorVersion */,
int* /* patchVersion */
#endif
);
Bool XF86DRIQueryDirectRenderingCapable(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Bool* /* isCapable */
#endif
);
Bool XF86DRIOpenConnection(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
drmHandlePtr /* hSAREA */,
char** /* busIDString */
#endif
);
Bool XF86DRIAuthConnection(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
drmMagic /* magic */
#endif
);
Bool XF86DRICloseConnection(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */
#endif
);
Bool XF86DRIGetClientDriverName(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
int* /* ddxDriverMajorVersion */,
int* /* ddxDriverMinorVersion */,
int* /* ddxDriverPatchVersion */,
char** /* clientDriverName */
#endif
);
Bool XF86DRICreateContext(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Visual* /* visual */,
XID* /* ptr to returned context id */,
drmContextPtr /* hHWContext */
#endif
);
Bool XF86DRIDestroyContext(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
XID /* context id */
#endif
);
Bool XF86DRICreateDrawable(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Drawable /* drawable */,
drmDrawablePtr /* hHWDrawable */
#endif
);
Bool XF86DRIDestroyDrawable(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Drawable /* drawable */
#endif
);
Bool XF86DRIGetDrawableInfo(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Drawable /* drawable */,
unsigned int* /* index */,
unsigned int* /* stamp */,
int* /* X */,
int* /* Y */,
int* /* W */,
int* /* H */,
int* /* numClipRects */,
XF86DRIClipRectPtr*,/* pClipRects */
int* /* backX */,
int* /* backY */,
int* /* numBackClipRects */,
XF86DRIClipRectPtr* /* pBackClipRects */
#endif
);
Bool XF86DRIGetDeviceInfo(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
drmHandlePtr /* hFrameBuffer */,
int* /* fbOrigin */,
int* /* fbSize */,
int* /* fbStride */,
int* /* devPrivateSize */,
void** /* pDevPrivate */
#endif
);
Bool XF86DRIOpenFullScreen(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Drawable /* drawable */
#endif
);
Bool XF86DRICloseFullScreen(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Drawable /* drawable */
#endif
);
_XFUNCPROTOEND
#endif /* _XF86DRI_SERVER_ */
#endif /* _XF86DRI_H_ */

343
src/dri-es/xf86dristr.h Normal file
View File

@@ -0,0 +1,343 @@
/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.9 2001/03/21 16:01:08 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT 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:
* Kevin E. Martin <martin@valinux.com>
* Jens Owen <jens@tungstengraphics.com>
* Rickard E. (Rik) Fiath <faith@valinux.com>
*
*/
#ifndef _XF86DRISTR_H_
#define _XF86DRISTR_H_
#include "xf86dri.h"
#define XF86DRINAME "XFree86-DRI"
/* The DRI version number. This was originally set to be the same of the
* XFree86 version number. However, this version is really indepedent of
* the XFree86 version.
*
* Version History:
* 4.0.0: Original
* 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
* 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
*/
#define XF86DRI_MAJOR_VERSION 4
#define XF86DRI_MINOR_VERSION 1
#define XF86DRI_PATCH_VERSION 0
typedef struct _XF86DRIQueryVersion {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIQueryVersion */
CARD16 length B16;
} xXF86DRIQueryVersionReq;
#define sz_xXF86DRIQueryVersionReq 4
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD16 majorVersion B16; /* major version of DRI protocol */
CARD16 minorVersion B16; /* minor version of DRI protocol */
CARD32 patchVersion B32; /* patch version of DRI protocol */
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRIQueryVersionReply;
#define sz_xXF86DRIQueryVersionReply 32
typedef struct _XF86DRIQueryDirectRenderingCapable {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
CARD16 length B16;
CARD32 screen B32;
} xXF86DRIQueryDirectRenderingCapableReq;
#define sz_xXF86DRIQueryDirectRenderingCapableReq 8
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
BOOL isCapable;
BOOL pad2;
BOOL pad3;
BOOL pad4;
CARD32 pad5 B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
CARD32 pad8 B32;
CARD32 pad9 B32;
} xXF86DRIQueryDirectRenderingCapableReply;
#define sz_xXF86DRIQueryDirectRenderingCapableReply 32
typedef struct _XF86DRIOpenConnection {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIOpenConnection */
CARD16 length B16;
CARD32 screen B32;
} xXF86DRIOpenConnectionReq;
#define sz_xXF86DRIOpenConnectionReq 8
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 hSAREALow B32;
CARD32 hSAREAHigh B32;
CARD32 busIdStringLength B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
CARD32 pad8 B32;
} xXF86DRIOpenConnectionReply;
#define sz_xXF86DRIOpenConnectionReply 32
typedef struct _XF86DRIAuthConnection {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICloseConnection */
CARD16 length B16;
CARD32 screen B32;
CARD32 magic B32;
} xXF86DRIAuthConnectionReq;
#define sz_xXF86DRIAuthConnectionReq 12
typedef struct {
BYTE type;
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 authenticated B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRIAuthConnectionReply;
#define zx_xXF86DRIAuthConnectionReply 32
typedef struct _XF86DRICloseConnection {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICloseConnection */
CARD16 length B16;
CARD32 screen B32;
} xXF86DRICloseConnectionReq;
#define sz_xXF86DRICloseConnectionReq 8
typedef struct _XF86DRIGetClientDriverName {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIGetClientDriverName */
CARD16 length B16;
CARD32 screen B32;
} xXF86DRIGetClientDriverNameReq;
#define sz_xXF86DRIGetClientDriverNameReq 8
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 ddxDriverMajorVersion B32;
CARD32 ddxDriverMinorVersion B32;
CARD32 ddxDriverPatchVersion B32;
CARD32 clientDriverNameLength B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRIGetClientDriverNameReply;
#define sz_xXF86DRIGetClientDriverNameReply 32
typedef struct _XF86DRICreateContext {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICreateContext */
CARD16 length B16;
CARD32 screen B32;
CARD32 visual B32;
CARD32 context B32;
} xXF86DRICreateContextReq;
#define sz_xXF86DRICreateContextReq 16
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 hHWContext B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRICreateContextReply;
#define sz_xXF86DRICreateContextReply 32
typedef struct _XF86DRIDestroyContext {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIDestroyContext */
CARD16 length B16;
CARD32 screen B32;
CARD32 context B32;
} xXF86DRIDestroyContextReq;
#define sz_xXF86DRIDestroyContextReq 12
typedef struct _XF86DRICreateDrawable {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICreateDrawable */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xXF86DRICreateDrawableReq;
#define sz_xXF86DRICreateDrawableReq 12
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 hHWDrawable B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRICreateDrawableReply;
#define sz_xXF86DRICreateDrawableReply 32
typedef struct _XF86DRIDestroyDrawable {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIDestroyDrawable */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xXF86DRIDestroyDrawableReq;
#define sz_xXF86DRIDestroyDrawableReq 12
typedef struct _XF86DRIGetDrawableInfo {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIGetDrawableInfo */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xXF86DRIGetDrawableInfoReq;
#define sz_xXF86DRIGetDrawableInfoReq 12
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 drawableTableIndex B32;
CARD32 drawableTableStamp B32;
INT16 drawableX B16;
INT16 drawableY B16;
INT16 drawableWidth B16;
INT16 drawableHeight B16;
CARD32 numClipRects B32;
INT16 backX B16;
INT16 backY B16;
CARD32 numBackClipRects B32;
} xXF86DRIGetDrawableInfoReply;
#define sz_xXF86DRIGetDrawableInfoReply 36
typedef struct _XF86DRIGetDeviceInfo {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIGetDeviceInfo */
CARD16 length B16;
CARD32 screen B32;
} xXF86DRIGetDeviceInfoReq;
#define sz_xXF86DRIGetDeviceInfoReq 8
typedef struct {
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 hFrameBufferLow B32;
CARD32 hFrameBufferHigh B32;
CARD32 framebufferOrigin B32;
CARD32 framebufferSize B32;
CARD32 framebufferStride B32;
CARD32 devPrivateSize B32;
} xXF86DRIGetDeviceInfoReply;
#define sz_xXF86DRIGetDeviceInfoReply 32
typedef struct _XF86DRIOpenFullScreen {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIOpenFullScreen */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xXF86DRIOpenFullScreenReq;
#define sz_xXF86DRIOpenFullScreenReq 12
typedef struct {
BYTE type;
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 isFullScreen B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xXF86DRIOpenFullScreenReply;
#define sz_xXF86DRIOpenFullScreenReply 32
typedef struct _XF86DRICloseFullScreen {
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICloseFullScreen */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xXF86DRICloseFullScreenReq;
#define sz_xXF86DRICloseFullScreenReq 12
typedef struct {
BYTE type;
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
} xXF86DRICloseFullScreenReply;
#define sz_xXF86DRICloseFullScreenReply 32
#endif /* _XF86DRISTR_H_ */

1500
src/dri-es/xf86drm.c Normal file

File diff suppressed because it is too large Load Diff

607
src/dri-es/xf86drm.h Normal file
View File

@@ -0,0 +1,607 @@
/* xf86drm.h -- OS-independent header for DRM user-level library interface
* Created: Tue Jan 5 08:17:23 1999 by faith@precisioninsight.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* 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 (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
* PRECISION INSIGHT 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.
*
* Author: Rickard E. (Rik) Faith <faith@valinux.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.17 2002/10/16 01:26:48 dawes Exp $
*
*/
#ifndef _XF86DRM_H_
#define _XF86DRM_H_
/* Defaults, if nothing set in xf86config */
#define DRM_DEV_UID 0
#define DRM_DEV_GID 0
/* Default /dev/dri directory permissions 0755 */
#define DRM_DEV_DIRMODE \
(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define DRM_DIR_NAME "/dev/dri"
#define DRM_DEV_NAME "%s/card%d"
#define DRM_PROC_NAME "/proc/dri/" /* For backware Linux compatibility */
#define DRM_ERR_NO_DEVICE (-1001)
#define DRM_ERR_NO_ACCESS (-1002)
#define DRM_ERR_NOT_ROOT (-1003)
#define DRM_ERR_INVALID (-1004)
#define DRM_ERR_NO_FD (-1005)
typedef unsigned long drmHandle, *drmHandlePtr; /* To mapped regions */
typedef unsigned int drmSize, *drmSizePtr; /* For mapped regions */
typedef void *drmAddress, **drmAddressPtr; /* For mapped regions */
typedef unsigned int drmContext, *drmContextPtr; /* GLXContext handle */
typedef unsigned int drmDrawable, *drmDrawablePtr; /* Unused */
typedef unsigned int drmMagic, *drmMagicPtr; /* Magic for auth */
typedef struct _drmVersion {
int version_major; /* Major version */
int version_minor; /* Minor version */
int version_patchlevel; /* Patch level */
int name_len; /* Length of name buffer */
char *name; /* Name of driver */
int date_len; /* Length of date buffer */
char *date; /* User-space buffer to hold date */
int desc_len; /* Length of desc buffer */
char *desc; /* User-space buffer to hold desc */
} drmVersion, *drmVersionPtr;
typedef struct _drmStats {
unsigned long count; /* Number of data */
struct {
unsigned long value; /* Value from kernel */
const char *long_format; /* Suggested format for long_name */
const char *long_name; /* Long name for value */
const char *rate_format; /* Suggested format for rate_name */
const char *rate_name; /* Short name for value per second */
int isvalue; /* True if value (vs. counter) */
const char *mult_names; /* Multiplier names (e.g., "KGM") */
int mult; /* Multiplier value (e.g., 1024) */
int verbose; /* Suggest only in verbose output */
} data[15];
} drmStatsT;
/* All of these enums *MUST* match with the
kernel implementation -- so do *NOT*
change them! (The drmlib implementation
will just copy the flags instead of
translating them.) */
typedef enum {
DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */
DRM_REGISTERS = 1, /* no caching, no core dump */
DRM_SHM = 2, /* shared, cached */
DRM_AGP = 3, /* AGP/GART */
DRM_SCATTER_GATHER = 4 /* PCI scatter/gather */
} drmMapType;
typedef enum {
DRM_RESTRICTED = 0x0001, /* Cannot be mapped to client-virtual */
DRM_READ_ONLY = 0x0002, /* Read-only in client-virtual */
DRM_LOCKED = 0x0004, /* Physical pages locked */
DRM_KERNEL = 0x0008, /* Kernel requires access */
DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */
DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */
DRM_REMOVABLE = 0x0040 /* Removable mapping */
} drmMapFlags;
typedef enum { /* These values *MUST* match drm.h */
/* Flags for DMA buffer dispatch */
DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched. Note,
the buffer may not yet have been
processed by the hardware -- getting a
hardware lock with the hardware
quiescent will ensure that the buffer
has been processed. */
DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */
DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */
/* Flags for DMA buffer request */
DRM_DMA_WAIT = 0x10, /* Wait for free buffers */
DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */
DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */
} drmDMAFlags;
typedef enum {
DRM_PAGE_ALIGN = 0x01,
DRM_AGP_BUFFER = 0x02,
DRM_SG_BUFFER = 0x04
} drmBufDescFlags;
typedef enum {
DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */
/* These *HALT* flags aren't supported yet
-- they will be used to support the
full-screen DGA-like mode. */
DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
} drmLockFlags;
typedef enum {
DRM_CONTEXT_PRESERVED = 0x01, /* This context is preserved and
never swapped. */
DRM_CONTEXT_2DONLY = 0x02 /* This context is for 2D rendering only. */
} drmContextFlags, *drmContextFlagsPtr;
typedef struct _drmBufDesc {
int count; /* Number of buffers of this size */
int size; /* Size in bytes */
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
} drmBufDesc, *drmBufDescPtr;
typedef struct _drmBufInfo {
int count; /* Number of buffers described in list */
drmBufDescPtr list; /* List of buffer descriptions */
} drmBufInfo, *drmBufInfoPtr;
typedef struct _drmBuf {
int idx; /* Index into master buflist */
int total; /* Buffer size */
int used; /* Amount of buffer in use (for DMA) */
drmAddress address; /* Address */
} drmBuf, *drmBufPtr;
typedef struct _drmBufMap {
int count; /* Number of buffers mapped */
drmBufPtr list; /* Buffers */
} drmBufMap, *drmBufMapPtr;
typedef struct _drmLock {
volatile unsigned int lock;
char padding[60];
/* This is big enough for most current (and future?) architectures:
DEC Alpha: 32 bytes
Intel Merced: ?
Intel P5/PPro/PII/PIII: 32 bytes
Intel StrongARM: 32 bytes
Intel i386/i486: 16 bytes
MIPS: 32 bytes (?)
Motorola 68k: 16 bytes
Motorola PowerPC: 32 bytes
Sun SPARC: 32 bytes
*/
} drmLock, *drmLockPtr;
typedef struct _drmDMAReq {
/* Indices here refer to the offset into
list in drmBufInfo */
drmContext context; /* Context handle */
int send_count; /* Number of buffers to send */
int *send_list; /* List of handles to buffers */
int *send_sizes; /* Lengths of data to send, in bytes */
drmDMAFlags flags; /* Flags */
int request_count; /* Number of buffers requested */
int request_size; /* Desired size of buffers requested */
int *request_list; /* Buffer information */
int *request_sizes; /* Minimum acceptable sizes */
int granted_count; /* Number of buffers granted at this size */
} drmDMAReq, *drmDMAReqPtr;
typedef struct _drmRegion {
drmHandle handle;
unsigned int offset;
drmSize size;
drmAddress map;
} drmRegion, *drmRegionPtr;
typedef struct _drmTextureRegion {
unsigned char next;
unsigned char prev;
unsigned char in_use;
unsigned char padding; /* Explicitly pad this out */
unsigned int age;
} drmTextureRegion, *drmTextureRegionPtr;
typedef struct _drmClipRect {
unsigned short x1; /* Upper left: inclusive */
unsigned short y1;
unsigned short x2; /* Lower right: exclusive */
unsigned short y2;
} drmClipRect, *drmClipRectPtr;
typedef enum {
DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drmVBlankSeqType;
typedef struct _drmVBlankReq {
drmVBlankSeqType type;
unsigned int sequence;
unsigned long signal;
} drmVBlankReq, *drmVBlankReqPtr;
typedef struct _drmVBlankReply {
drmVBlankSeqType type;
unsigned int sequence;
long tval_sec;
long tval_usec;
} drmVBlankReply, *drmVBlankReplyPtr;
typedef union _drmVBlank {
drmVBlankReq request;
drmVBlankReply reply;
} drmVBlank, *drmVBlankPtr;
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
#define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
#define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
#if __GNUC__ >= 2
# if defined(__i386) || defined(__x86_64__)
/* Reflect changes here to drmP.h */
#define DRM_CAS(lock,old,new,__ret) \
do { \
int __dummy; /* Can't mark eax as clobbered */ \
__asm__ __volatile__( \
"lock ; cmpxchg %4,%1\n\t" \
"setnz %0" \
: "=d" (__ret), \
"=m" (__drm_dummy_lock(lock)), \
"=a" (__dummy) \
: "2" (old), \
"r" (new)); \
} while (0)
#elif defined(__alpha__)
#define DRM_CAS(lock, old, new, ret) \
do { \
int old32; \
int cur32; \
__asm__ __volatile__( \
" mb\n" \
" zap %4, 0xF0, %0\n" \
" ldl_l %1, %2\n" \
" zap %1, 0xF0, %1\n" \
" cmpeq %0, %1, %1\n" \
" beq %1, 1f\n" \
" bis %5, %5, %1\n" \
" stl_c %1, %2\n" \
"1: xor %1, 1, %1\n" \
" stl %1, %3" \
: "+r" (old32), \
"+&r" (cur32), \
"=m" (__drm_dummy_lock(lock)),\
"=m" (ret) \
: "r" (old), \
"r" (new)); \
} while(0)
#elif defined(__sparc__)
#define DRM_CAS(lock,old,new,__ret) \
do { register unsigned int __old __asm("o0"); \
register unsigned int __new __asm("o1"); \
register volatile unsigned int *__lock __asm("o2"); \
__old = old; \
__new = new; \
__lock = (volatile unsigned int *)lock; \
__asm__ __volatile__( \
/*"cas [%2], %3, %0"*/ \
".word 0xd3e29008\n\t" \
/*"membar #StoreStore | #StoreLoad"*/ \
".word 0x8143e00a" \
: "=&r" (__new) \
: "0" (__new), \
"r" (__lock), \
"r" (__old) \
: "memory"); \
__ret = (__new != __old); \
} while(0)
#elif defined(__ia64__)
#if 0
/* this currently generates bad code (missing stop bits)... */
#include <ia64intrin.h>
#define DRM_CAS(lock,old,new,__ret) \
do { \
__ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \
(old), (new)) \
!= (old)); \
} while (0)
#else
#define DRM_CAS(lock,old,new,__ret) \
do { \
unsigned int __result, __old = (old); \
__asm__ __volatile__( \
"mf\n" \
"mov ar.ccv=%2\n" \
";;\n" \
"cmpxchg4.acq %0=%1,%3,ar.ccv" \
: "=r" (__result), "=m" (__drm_dummy_lock(lock)) \
: "r" (__old), "r" (new) \
: "memory"); \
__ret = (__result) != (__old); \
} while (0)
#endif
#elif defined(__powerpc__)
#define DRM_CAS(lock,old,new,__ret) \
do { \
__asm__ __volatile__( \
"sync;" \
"0: lwarx %0,0,%1;" \
" xor. %0,%3,%0;" \
" bne 1f;" \
" stwcx. %2,0,%1;" \
" bne- 0b;" \
"1: " \
"sync;" \
: "=&r"(__ret) \
: "r"(lock), "r"(new), "r"(old) \
: "cr0", "memory"); \
} while (0)
#endif /* architecture */
#endif /* __GNUC__ >= 2 */
#ifndef DRM_CAS
#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */
#endif
#if defined(__alpha__) || defined(__powerpc__)
#define DRM_CAS_RESULT(_result) int _result
#else
#define DRM_CAS_RESULT(_result) char _result
#endif
#define DRM_LIGHT_LOCK(fd,lock,context) \
do { \
DRM_CAS_RESULT(__ret); \
DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
if (__ret) drmGetLock(fd,context,0); \
} while(0)
/* This one counts fast locks -- for
benchmarking only. */
#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \
do { \
DRM_CAS_RESULT(__ret); \
DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
if (__ret) drmGetLock(fd,context,0); \
else ++count; \
} while(0)
#define DRM_LOCK(fd,lock,context,flags) \
do { \
if (flags) drmGetLock(fd,context,flags); \
else DRM_LIGHT_LOCK(fd,lock,context); \
} while(0)
#define DRM_UNLOCK(fd,lock,context) \
do { \
DRM_CAS_RESULT(__ret); \
DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \
if (__ret) drmUnlock(fd,context); \
} while(0)
/* Simple spin locks */
#define DRM_SPINLOCK(spin,val) \
do { \
DRM_CAS_RESULT(__ret); \
do { \
DRM_CAS(spin,0,val,__ret); \
if (__ret) while ((spin)->lock); \
} while (__ret); \
} while(0)
#define DRM_SPINLOCK_TAKE(spin,val) \
do { \
DRM_CAS_RESULT(__ret); \
int cur; \
do { \
cur = (*spin).lock; \
DRM_CAS(spin,cur,val,__ret); \
} while (__ret); \
} while(0)
#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \
do { \
int __i; \
__ret = 1; \
for (__i = 0; __ret && __i < count; __i++) { \
DRM_CAS(spin,0,val,__ret); \
if (__ret) for (;__i < count && (spin)->lock; __i++); \
} \
} while(0)
#define DRM_SPINUNLOCK(spin,val) \
do { \
DRM_CAS_RESULT(__ret); \
if ((*spin).lock == val) { /* else server stole lock */ \
do { \
DRM_CAS(spin,val,0,__ret); \
} while (__ret); \
} \
} while(0)
/* General user-level programmer's API: unprivileged */
extern int drmAvailable(void);
extern int drmOpen(const char *name, const char *busid);
extern int drmClose(int fd);
extern drmVersionPtr drmGetVersion(int fd);
extern drmVersionPtr drmGetLibVersion(int fd);
extern void drmFreeVersion(drmVersionPtr);
extern int drmGetMagic(int fd, drmMagicPtr magic);
extern char *drmGetBusid(int fd);
extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
int funcnum);
extern int drmGetMap(int fd, int idx, drmHandle *offset,
drmSize *size, drmMapType *type,
drmMapFlags *flags, drmHandle *handle,
int *mtrr);
extern int drmGetClient(int fd, int idx, int *auth, int *pid,
int *uid, unsigned long *magic,
unsigned long *iocs);
extern int drmGetStats(int fd, drmStatsT *stats);
extern int drmCommandNone(int fd, unsigned long drmCommandIndex);
extern int drmCommandRead(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
extern int drmCommandWrite(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
/* General user-level programmer's API: X server (root) only */
extern void drmFreeBusid(const char *busid);
extern int drmSetBusid(int fd, const char *busid);
extern int drmAuthMagic(int fd, drmMagic magic);
extern int drmAddMap(int fd,
drmHandle offset,
drmSize size,
drmMapType type,
drmMapFlags flags,
drmHandlePtr handle);
extern int drmRmMap(int fd, drmHandle handle);
extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id,
drmHandle handle);
extern int drmAddBufs(int fd, int count, int size,
drmBufDescFlags flags,
int agp_offset);
extern int drmMarkBufs(int fd, double low, double high);
extern int drmCreateContext(int fd, drmContextPtr handle);
extern int drmSetContextFlags(int fd, drmContext context,
drmContextFlags flags);
extern int drmGetContextFlags(int fd, drmContext context,
drmContextFlagsPtr flags);
extern int drmAddContextTag(int fd, drmContext context, void *tag);
extern int drmDelContextTag(int fd, drmContext context);
extern void *drmGetContextTag(int fd, drmContext context);
extern drmContextPtr drmGetReservedContextList(int fd, int *count);
extern void drmFreeReservedContextList(drmContextPtr);
extern int drmSwitchToContext(int fd, drmContext context);
extern int drmDestroyContext(int fd, drmContext handle);
extern int drmCreateDrawable(int fd, drmDrawablePtr handle);
extern int drmDestroyDrawable(int fd, drmDrawable handle);
extern int drmCtlInstHandler(int fd, int irq);
extern int drmCtlUninstHandler(int fd);
extern int drmInstallSIGIOHandler(int fd,
void (*f)(int fd,
void *oldctx,
void *newctx));
extern int drmRemoveSIGIOHandler(int fd);
/* General user-level programmer's API: authenticated client and/or X */
extern int drmMap(int fd,
drmHandle handle,
drmSize size,
drmAddressPtr address);
extern int drmUnmap(drmAddress address, drmSize size);
extern drmBufInfoPtr drmGetBufInfo(int fd);
extern drmBufMapPtr drmMapBufs(int fd);
extern int drmUnmapBufs(drmBufMapPtr bufs);
extern int drmDMA(int fd, drmDMAReqPtr request);
extern int drmFreeBufs(int fd, int count, int *list);
extern int drmGetLock(int fd,
drmContext context,
drmLockFlags flags);
extern int drmUnlock(int fd, drmContext context);
extern int drmFinish(int fd, int context, drmLockFlags flags);
extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id,
drmHandlePtr handle);
/* AGP/GART support: X server (root) only */
extern int drmAgpAcquire(int fd);
extern int drmAgpRelease(int fd);
extern int drmAgpEnable(int fd, unsigned long mode);
extern int drmAgpAlloc(int fd, unsigned long size,
unsigned long type, unsigned long *address,
unsigned long *handle);
extern int drmAgpFree(int fd, unsigned long handle);
extern int drmAgpBind(int fd, unsigned long handle,
unsigned long offset);
extern int drmAgpUnbind(int fd, unsigned long handle);
/* AGP/GART info: authenticated client and/or X */
extern int drmAgpVersionMajor(int fd);
extern int drmAgpVersionMinor(int fd);
extern unsigned long drmAgpGetMode(int fd);
extern unsigned long drmAgpBase(int fd); /* Physical location */
extern unsigned long drmAgpSize(int fd); /* Bytes */
extern unsigned long drmAgpMemoryUsed(int fd);
extern unsigned long drmAgpMemoryAvail(int fd);
extern unsigned int drmAgpVendorId(int fd);
extern unsigned int drmAgpDeviceId(int fd);
/* PCI scatter/gather support: X server (root) only */
extern int drmScatterGatherAlloc(int fd, unsigned long size,
unsigned long *handle);
extern int drmScatterGatherFree(int fd, unsigned long handle);
extern int drmWaitVBlank(int fd, drmVBlankPtr vbl);
/* Support routines */
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
extern void drmFree(void *pt);
/* Hash table routines */
extern void *drmHashCreate(void);
extern int drmHashDestroy(void *t);
extern int drmHashLookup(void *t, unsigned long key, void **value);
extern int drmHashInsert(void *t, unsigned long key, void *value);
extern int drmHashDelete(void *t, unsigned long key);
extern int drmHashFirst(void *t, unsigned long *key, void **value);
extern int drmHashNext(void *t, unsigned long *key, void **value);
/* PRNG routines */
extern void *drmRandomCreate(unsigned long seed);
extern int drmRandomDestroy(void *state);
extern unsigned long drmRandom(void *state);
extern double drmRandomDouble(void *state);
/* Skip list routines */
extern void *drmSLCreate(void);
extern int drmSLDestroy(void *l);
extern int drmSLLookup(void *l, unsigned long key, void **value);
extern int drmSLInsert(void *l, unsigned long key, void *value);
extern int drmSLDelete(void *l, unsigned long key);
extern int drmSLNext(void *l, unsigned long *key, void **value);
extern int drmSLFirst(void *l, unsigned long *key, void **value);
extern void drmSLDump(void *l);
extern int drmSLLookupNeighbors(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value);
#endif

435
src/dri-es/xf86drmHash.c Normal file
View File

@@ -0,0 +1,435 @@
/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
* Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, 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
* PRECISION INSIGHT 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: Rickard E. (Rik) Faith <faith@valinux.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
*
* DESCRIPTION
*
* This file contains a straightforward implementation of a fixed-sized
* hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
* collision resolution. There are two potentially interesting things
* about this implementation:
*
* 1) The table is power-of-two sized. Prime sized tables are more
* traditional, but do not have a significant advantage over power-of-two
* sized table, especially when double hashing is not used for collision
* resolution.
*
* 2) The hash computation uses a table of random integers [Hanson97,
* pp. 39-41].
*
* FUTURE ENHANCEMENTS
*
* With a table size of 512, the current implementation is sufficient for a
* few hundred keys. Since this is well above the expected size of the
* tables for which this implementation was designed, the implementation of
* dynamic hash tables was postponed until the need arises. A common (and
* naive) approach to dynamic hash table implementation simply creates a
* new hash table when necessary, rehashes all the data into the new table,
* and destroys the old table. The approach in [Larson88] is superior in
* two ways: 1) only a portion of the table is expanded when needed,
* distributing the expansion cost over several insertions, and 2) portions
* of the table can be locked, enabling a scalable thread-safe
* implementation.
*
* REFERENCES
*
* [Hanson97] David R. Hanson. C Interfaces and Implementations:
* Techniques for Creating Reusable Software. Reading, Massachusetts:
* Addison-Wesley, 1997.
*
* [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
* Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
*
* [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
* 1988, pp. 446-457.
*
*/
#define HASH_MAIN 0
#if HASH_MAIN
# include <stdio.h>
# include <stdlib.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define HASH_MAGIC 0xdeadbeef
#define HASH_DEBUG 0
#define HASH_SIZE 512 /* Good for about 100 entries */
/* If you change this value, you probably
have to change the HashHash hashing
function! */
#if HASH_MAIN
#define HASH_ALLOC malloc
#define HASH_FREE free
#define HASH_RANDOM_DECL
#define HASH_RANDOM_INIT(seed) srandom(seed)
#define HASH_RANDOM random()
#else
#define HASH_ALLOC drmMalloc
#define HASH_FREE drmFree
#define HASH_RANDOM_DECL void *state
#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
#define HASH_RANDOM drmRandom(state)
#endif
typedef struct HashBucket {
unsigned long key;
void *value;
struct HashBucket *next;
} HashBucket, *HashBucketPtr;
typedef struct HashTable {
unsigned long magic;
unsigned long entries;
unsigned long hits; /* At top of linked list */
unsigned long partials; /* Not at top of linked list */
unsigned long misses; /* Not in table */
HashBucketPtr buckets[HASH_SIZE];
int p0;
HashBucketPtr p1;
} HashTable, *HashTablePtr;
#if HASH_MAIN
extern void *N(HashCreate)(void);
extern int N(HashDestroy)(void *t);
extern int N(HashLookup)(void *t, unsigned long key, unsigned long *value);
extern int N(HashInsert)(void *t, unsigned long key, unsigned long value);
extern int N(HashDelete)(void *t, unsigned long key);
#endif
static unsigned long HashHash(unsigned long key)
{
unsigned long hash = 0;
unsigned long tmp = key;
static int init = 0;
static unsigned long scatter[256];
int i;
if (!init) {
HASH_RANDOM_DECL;
HASH_RANDOM_INIT(37);
for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
++init;
}
while (tmp) {
hash = (hash << 1) + scatter[tmp & 0xff];
tmp >>= 8;
}
hash %= HASH_SIZE;
#if HASH_DEBUG
printf( "Hash(%d) = %d\n", key, hash);
#endif
return hash;
}
void *N(HashCreate)(void)
{
HashTablePtr table;
int i;
table = HASH_ALLOC(sizeof(*table));
if (!table) return NULL;
table->magic = HASH_MAGIC;
table->entries = 0;
table->hits = 0;
table->partials = 0;
table->misses = 0;
for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
return table;
}
int N(HashDestroy)(void *t)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
HashBucketPtr next;
int i;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
for (i = 0; i < HASH_SIZE; i++) {
for (bucket = table->buckets[i]; bucket;) {
next = bucket->next;
HASH_FREE(bucket);
bucket = next;
}
}
HASH_FREE(table);
return 0;
}
/* Find the bucket and organize the list so that this bucket is at the
top. */
static HashBucketPtr HashFind(HashTablePtr table,
unsigned long key, unsigned long *h)
{
unsigned long hash = HashHash(key);
HashBucketPtr prev = NULL;
HashBucketPtr bucket;
if (h) *h = hash;
for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
if (bucket->key == key) {
if (prev) {
/* Organize */
prev->next = bucket->next;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
++table->partials;
} else {
++table->hits;
}
return bucket;
}
prev = bucket;
}
++table->misses;
return NULL;
}
int N(HashLookup)(void *t, unsigned long key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
bucket = HashFind(table, key, NULL);
if (!bucket) return 1; /* Not found */
*value = bucket->value;
return 0; /* Found */
}
int N(HashInsert)(void *t, unsigned long key, void *value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
unsigned long hash;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (HashFind(table, key, &hash)) return 1; /* Already in table */
bucket = HASH_ALLOC(sizeof(*bucket));
if (!bucket) return -1; /* Error */
bucket->key = key;
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
#if HASH_DEBUG
printf("Inserted %d at %d/%p\n", key, hash, bucket);
#endif
return 0; /* Added to table */
}
int N(HashDelete)(void *t, unsigned long key)
{
HashTablePtr table = (HashTablePtr)t;
unsigned long hash;
HashBucketPtr bucket;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
bucket = HashFind(table, key, &hash);
if (!bucket) return 1; /* Not found */
table->buckets[hash] = bucket->next;
HASH_FREE(bucket);
return 0;
}
int N(HashNext)(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
for (; table->p0 < HASH_SIZE;
++table->p0, table->p1 = table->buckets[table->p0]) {
if (table->p1) {
*key = table->p1->key;
*value = table->p1->value;
table->p1 = table->p1->next;
return 1;
}
}
return 0;
}
int N(HashFirst)(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
table->p0 = 0;
table->p1 = table->buckets[0];
return N(HashNext)(table, key, value);
}
#if HASH_MAIN
#define DIST_LIMIT 10
static int dist[DIST_LIMIT];
static void clear_dist(void) {
int i;
for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
}
static int count_entries(HashBucketPtr bucket)
{
int count = 0;
for (; bucket; bucket = bucket->next) ++count;
return count;
}
static void update_dist(int count)
{
if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
else ++dist[count];
}
static void compute_dist(HashTablePtr table)
{
int i;
HashBucketPtr bucket;
printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
table->entries, table->hits, table->partials, table->misses);
clear_dist();
for (i = 0; i < HASH_SIZE; i++) {
bucket = table->buckets[i];
update_dist(count_entries(bucket));
}
for (i = 0; i < DIST_LIMIT; i++) {
if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
else printf("other %10d\n", dist[i]);
}
}
static void check_table(HashTablePtr table,
unsigned long key, unsigned long value)
{
unsigned long retval = 0;
int retcode = N(HashLookup)(table, key, &retval);
switch (retcode) {
case -1:
printf("Bad magic = 0x%08lx:"
" key = %lu, expected = %lu, returned = %lu\n",
table->magic, key, value, retval);
break;
case 1:
printf("Not found: key = %lu, expected = %lu returned = %lu\n",
key, value, retval);
break;
case 0:
if (value != retval)
printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
key, value, retval);
break;
default:
printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
retcode, key, value, retval);
break;
}
}
int main(void)
{
HashTablePtr table;
int i;
printf("\n***** 256 consecutive integers ****\n");
table = N(HashCreate)();
for (i = 0; i < 256; i++) N(HashInsert)(table, i, i);
for (i = 0; i < 256; i++) check_table(table, i, i);
for (i = 256; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 consecutive integers ****\n");
table = N(HashCreate)();
for (i = 0; i < 1024; i++) N(HashInsert)(table, i, i);
for (i = 0; i < 1024; i++) check_table(table, i, i);
for (i = 1024; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
table = N(HashCreate)();
for (i = 0; i < 1024; i++) N(HashInsert)(table, i*4096, i);
for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 1024 random integers ****\n");
table = N(HashCreate)();
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) N(HashInsert)(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
compute_dist(table);
N(HashDestroy)(table);
printf("\n***** 5000 random integers ****\n");
table = N(HashCreate)();
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) N(HashInsert)(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
compute_dist(table);
N(HashDestroy)(table);
return 0;
}
#endif

219
src/dri-es/xf86drmRandom.c Normal file
View File

@@ -0,0 +1,219 @@
/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
* Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, 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
* PRECISION INSIGHT 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: Rickard E. (Rik) Faith <faith@valinux.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 2000/06/17 00:03:34 martin Exp $
*
* DESCRIPTION
*
* This file contains a simple, straightforward implementation of the Park
* & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
* multiplicative linear congruential generator (MLCG) with a period of
* 2^31-1.
*
* This implementation is intended to provide a reliable, portable PRNG
* that is suitable for testing a hash table implementation and for
* implementing skip lists.
*
* FUTURE ENHANCEMENTS
*
* If initial seeds are not selected randomly, two instances of the PRNG
* can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
* that can eliminate this problem.
*
* If PRNGs are used for simulation, the period of the current
* implementation may be too short. [LE88] discusses methods of combining
* MLCGs to produce much longer periods, and suggests some alternative
* values for A and M. [LE90 and Sch92] also provide information on
* long-period PRNGs.
*
* REFERENCES
*
* [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
* Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
*
* [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
* Generators". CACM 31(6), June 1988, pp. 742-774.
*
* [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
* October 1990, pp. 85-97.
*
* [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
* Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
*
* [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
* CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
*
* [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
* "Technical Correspondence: Remarks on Choosing and Implementing Random
* Number Generators". CACM 36(7), July 1993, pp. 105-110.
*
*/
#define RANDOM_MAIN 0
#if RANDOM_MAIN
# include <stdio.h>
# include <stdlib.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define RANDOM_MAGIC 0xfeedbeef
#define RANDOM_DEBUG 0
#if RANDOM_MAIN
#define RANDOM_ALLOC malloc
#define RANDOM_FREE free
#else
#define RANDOM_ALLOC drmMalloc
#define RANDOM_FREE drmFree
#endif
typedef struct RandomState {
unsigned long magic;
unsigned long a;
unsigned long m;
unsigned long q; /* m div a */
unsigned long r; /* m mod a */
unsigned long check;
long seed;
} RandomState;
#if RANDOM_MAIN
extern void *N(RandomCreate)(unsigned long seed);
extern int N(RandomDestroy)(void *state);
extern unsigned long N(Random)(void *state);
extern double N(RandomDouble)(void *state);
#endif
void *N(RandomCreate)(unsigned long seed)
{
RandomState *state;
state = RANDOM_ALLOC(sizeof(*state));
if (!state) return NULL;
state->magic = RANDOM_MAGIC;
#if 0
/* Park & Miller, October 1988 */
state->a = 16807;
state->m = 2147483647;
state->check = 1043618065; /* After 10000 iterations */
#else
/* Park, Miller, and Stockmeyer, July 1993 */
state->a = 48271;
state->m = 2147483647;
state->check = 399268537; /* After 10000 iterations */
#endif
state->q = state->m / state->a;
state->r = state->m % state->a;
state->seed = seed;
/* Check for illegal boundary conditions,
and choose closest legal value. */
if (state->seed <= 0) state->seed = 1;
if (state->seed >= state->m) state->seed = state->m - 1;
return state;
}
int N(RandomDestroy)(void *state)
{
RANDOM_FREE(state);
return 0;
}
unsigned long N(Random)(void *state)
{
RandomState *s = (RandomState *)state;
long hi;
long lo;
hi = s->seed / s->q;
lo = s->seed % s->q;
s->seed = s->a * lo - s->r * hi;
if (s->seed <= 0) s->seed += s->m;
return s->seed;
}
double N(RandomDouble)(void *state)
{
RandomState *s = (RandomState *)state;
return (double)N(Random)(state)/(double)s->m;
}
#if RANDOM_MAIN
static void check_period(long seed)
{
unsigned long count = 0;
unsigned long initial;
void *state;
state = N(RandomCreate)(seed);
initial = N(Random)(state);
++count;
while (initial != N(Random)(state)) {
if (!++count) break;
}
printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
seed, count, count);
N(RandomDestroy)(state);
}
int main(void)
{
RandomState *state;
int i;
unsigned long rand;
state = N(RandomCreate)(1);
for (i = 0; i < 10000; i++) {
rand = N(Random)(state);
}
printf("After 10000 iterations: %lu (%lu expected): %s\n",
rand, state->check,
rand - state->check ? "*INCORRECT*" : "CORRECT");
N(RandomDestroy)(state);
printf("Checking periods...\n");
check_period(1);
check_period(2);
check_period(31415926);
return 0;
}
#endif

490
src/dri-es/xf86drmSL.c Normal file
View File

@@ -0,0 +1,490 @@
/* xf86drmSL.c -- Skip list support
* Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, 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
* PRECISION INSIGHT 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: Rickard E. (Rik) Faith <faith@valinux.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.3 2000/06/17 00:03:34 martin Exp $
*
* DESCRIPTION
*
* This file contains a straightforward skip list implementation.n
*
* FUTURE ENHANCEMENTS
*
* REFERENCES
*
* [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
* Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
*
*/
#define SL_MAIN 0
#if SL_MAIN
# include <stdio.h>
# include <stdlib.h>
# include <sys/time.h>
#else
# include "xf86drm.h"
# ifdef XFree86LOADER
# include "xf86.h"
# include "xf86_ansic.h"
# else
# include <stdio.h>
# include <stdlib.h>
# endif
#endif
#define N(x) drm##x
#define SL_LIST_MAGIC 0xfacade00LU
#define SL_ENTRY_MAGIC 0x00fab1edLU
#define SL_FREED_MAGIC 0xdecea5edLU
#define SL_MAX_LEVEL 16
#define SL_DEBUG 0
#define SL_RANDOM_SEED 0xc01055a1LU
#if SL_MAIN
#define SL_ALLOC malloc
#define SL_FREE free
#define SL_RANDOM_DECL static int state = 0;
#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
#define SL_RANDOM random()
#else
#define SL_ALLOC drmMalloc
#define SL_FREE drmFree
#define SL_RANDOM_DECL static void *state = NULL
#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
#define SL_RANDOM drmRandom(state)
#endif
typedef struct SLEntry {
unsigned long magic; /* SL_ENTRY_MAGIC */
unsigned long key;
void *value;
int levels;
struct SLEntry *forward[1]; /* variable sized array */
} SLEntry, *SLEntryPtr;
typedef struct SkipList {
unsigned long magic; /* SL_LIST_MAGIC */
int level;
int count;
SLEntryPtr head;
SLEntryPtr p0; /* Position for iteration */
} SkipList, *SkipListPtr;
#if SL_MAIN
extern void *N(SLCreate)(void);
extern int N(SLDestroy)(void *l);
extern int N(SLLookup)(void *l, unsigned long key, void **value);
extern int N(SLInsert)(void *l, unsigned long key, void *value);
extern int N(SLDelete)(void *l, unsigned long key);
extern int N(SLNext)(void *l, unsigned long *key, void **value);
extern int N(SLFirst)(void *l, unsigned long *key, void **value);
extern void N(SLDump)(void *l);
extern int N(SLLookupNeighbors)(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value);
#endif
static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
{
SLEntryPtr entry;
if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
entry = SL_ALLOC(sizeof(*entry)
+ (max_level + 1) * sizeof(entry->forward[0]));
if (!entry) return NULL;
entry->magic = SL_ENTRY_MAGIC;
entry->key = key;
entry->value = value;
entry->levels = max_level + 1;
return entry;
}
static int SLRandomLevel(void)
{
int level = 1;
SL_RANDOM_DECL;
SL_RANDOM_INIT(SL_RANDOM_SEED);
while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
return level;
}
void *N(SLCreate)(void)
{
SkipListPtr list;
int i;
list = SL_ALLOC(sizeof(*list));
if (!list) return NULL;
list->magic = SL_LIST_MAGIC;
list->level = 0;
list->head = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
list->count = 0;
for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
return list;
}
int N(SLDestroy)(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
SLEntryPtr next;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
for (entry = list->head; entry; entry = next) {
if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
next = entry->forward[0];
entry->magic = SL_FREED_MAGIC;
SL_FREE(entry);
}
list->magic = SL_FREED_MAGIC;
SL_FREE(list);
return 0;
}
static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) return NULL;
for (i = list->level, entry = list->head; i >= 0; i--) {
while (entry->forward[i] && entry->forward[i]->key < key)
entry = entry->forward[i];
update[i] = entry;
}
return entry->forward[0];
}
int N(SLInsert)(void *l, unsigned long key, void *value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
SLEntryPtr update[SL_MAX_LEVEL + 1];
int level;
int i;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = SLLocate(list, key, update);
if (entry && entry->key == key) return 1; /* Already in list */
level = SLRandomLevel();
if (level > list->level) {
level = ++list->level;
update[level] = list->head;
}
entry = SLCreateEntry(level, key, value);
/* Fix up forward pointers */
for (i = 0; i <= level; i++) {
entry->forward[i] = update[i]->forward[i];
update[i]->forward[i] = entry;
}
++list->count;
return 0; /* Added to table */
}
int N(SLDelete)(void *l, unsigned long key)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = SLLocate(list, key, update);
if (!entry || entry->key != key) return 1; /* Not found */
/* Fix up forward pointers */
for (i = 0; i <= list->level; i++) {
if (update[i]->forward[i] == entry)
update[i]->forward[i] = entry->forward[i];
}
entry->magic = SL_FREED_MAGIC;
SL_FREE(entry);
while (list->level && !list->head->forward[list->level]) --list->level;
--list->count;
return 0;
}
int N(SLLookup)(void *l, unsigned long key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
entry = SLLocate(list, key, update);
if (entry && entry->key == key) {
*value = entry;
return 0;
}
*value = NULL;
return -1;
}
int N(SLLookupNeighbors)(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
SLEntryPtr entry;
int retcode = 0;
entry = SLLocate(list, key, update);
*prev_key = *next_key = key;
*prev_value = *next_value = NULL;
if (update[0]) {
*prev_key = update[0]->key;
*prev_value = update[0]->value;
++retcode;
if (update[0]->forward[0]) {
*next_key = update[0]->forward[0]->key;
*next_value = update[0]->forward[0]->value;
++retcode;
}
}
return retcode;
}
int N(SLNext)(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
entry = list->p0;
if (entry) {
list->p0 = entry->forward[0];
*key = entry->key;
*value = entry->value;
return 1;
}
list->p0 = NULL;
return 0;
}
int N(SLFirst)(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
list->p0 = list->head->forward[0];
return N(SLNext)(list, key, value);
}
/* Dump internal data structures for debugging. */
void N(SLDump)(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
int i;
if (list->magic != SL_LIST_MAGIC) {
printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
list->magic, SL_LIST_MAGIC);
return;
}
printf("Level = %d, count = %d\n", list->level, list->count);
for (entry = list->head; entry; entry = entry->forward[0]) {
if (entry->magic != SL_ENTRY_MAGIC) {
printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
list->magic, SL_ENTRY_MAGIC);
}
printf("\nEntry %p <0x%08lx, %p> has %2d levels\n",
entry, entry->key, entry->value, entry->levels);
for (i = 0; i < entry->levels; i++) {
if (entry->forward[i]) {
printf(" %2d: %p <0x%08lx, %p>\n",
i,
entry->forward[i],
entry->forward[i]->key,
entry->forward[i]->value);
} else {
printf(" %2d: %p\n", i, entry->forward[i]);
}
}
}
}
#if SL_MAIN
static void print(SkipListPtr list)
{
unsigned long key;
void *value;
if (N(SLFirst)(list, &key, &value)) {
do {
printf("key = %5lu, value = %p\n", key, value);
} while (N(SLNext)(list, &key, &value));
}
}
static double do_time(int size, int iter)
{
SkipListPtr list;
int i, j;
unsigned long keys[1000000];
unsigned long previous;
unsigned long key;
void *value;
struct timeval start, stop;
double usec;
SL_RANDOM_DECL;
SL_RANDOM_INIT(12345);
list = N(SLCreate)();
for (i = 0; i < size; i++) {
keys[i] = SL_RANDOM;
N(SLInsert)(list, keys[i], NULL);
}
previous = 0;
if (N(SLFirst)(list, &key, &value)) {
do {
if (key <= previous) {
printf( "%lu !< %lu\n", previous, key);
}
previous = key;
} while (N(SLNext)(list, &key, &value));
}
gettimeofday(&start, NULL);
for (j = 0; j < iter; j++) {
for (i = 0; i < size; i++) {
if (N(SLLookup)(list, keys[i], &value))
printf("Error %lu %d\n", keys[i], i);
}
}
gettimeofday(&stop, NULL);
usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
- start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
printf("%0.2f microseconds for list length %d\n", usec, size);
N(SLDestroy)(list);
return usec;
}
static void print_neighbors(void *list, unsigned long key)
{
unsigned long prev_key = 0;
unsigned long next_key = 0;
void *prev_value;
void *next_value;
int retval;
retval = drmSLLookupNeighbors(list, key,
&prev_key, &prev_value,
&next_key, &next_value);
printf("Neighbors of %5lu: %d %5lu %5lu\n",
key, retval, prev_key, next_key);
}
int main(void)
{
SkipListPtr list;
double usec, usec2, usec3, usec4;
list = N(SLCreate)();
printf( "list at %p\n", list);
print(list);
printf("\n==============================\n\n");
N(SLInsert)(list, 123, NULL);
N(SLInsert)(list, 213, NULL);
N(SLInsert)(list, 50, NULL);
print(list);
printf("\n==============================\n\n");
print_neighbors(list, 0);
print_neighbors(list, 50);
print_neighbors(list, 51);
print_neighbors(list, 123);
print_neighbors(list, 200);
print_neighbors(list, 213);
print_neighbors(list, 256);
printf("\n==============================\n\n");
N(SLDelete)(list, 50);
print(list);
printf("\n==============================\n\n");
N(SLDump)(list);
N(SLDestroy)(list);
printf("\n==============================\n\n");
usec = do_time(100, 10000);
usec2 = do_time(1000, 500);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
1000.0/100.0, usec2 / usec);
usec3 = do_time(10000, 50);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
10000.0/100.0, usec3 / usec);
usec4 = do_time(100000, 4);
printf("Table size increased by %0.2f, search time increased by %0.2f\n",
100000.0/100.0, usec4 / usec);
return 0;
}
#endif

View File

@@ -1,5 +1,9 @@
/**
* \file mm.c
* \brief Memory block management.
*/
/*
* GLX Hardware Device Driver common code
* Copyright (C) 1999 Keith Whitwell
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -19,20 +23,29 @@
* 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.3 2001/08/18 02:51:03 dawes Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include "mm.h"
#include "hwlog.h"
/* KW: I don't know who the author of this code is, but it wasn't me
* despite what the copyright says...
*/
/**
* \brief Dump memory information about the heap.
*
* \param heap memory heap.
*
* \note For debugging purposes.
*
* \internal
* Prints the offset, size and flags for each block.
*/
void mmDumpMemInfo( memHeap_t *heap )
{
TMemBlock *p;
@@ -52,6 +65,19 @@ void mmDumpMemInfo( memHeap_t *heap )
fprintf(stderr, "End of memory blocks\n");
}
/**
* \brief Memory heap initialization.
*
* \param offset offset in bytes.
* \param size total size in bytes
*
* \return a heap pointer on success, or NULL on failure.
*
* \internal
* Allocate a mem_block_t structure and initialize it with the heap
* information.
*/
memHeap_t *mmInit(int ofs,
int size)
{
@@ -71,6 +97,22 @@ memHeap_t *mmInit(int ofs,
}
/**
* \brief Slice a free memory block.
*
* \param p memory block.
* \param startofs slice start offset.
* \param size slice size.
* \param reserved reserved flag.
* \param alignment slice alignment.
*
* \return pointer to the slice block on success, or NULL on failure.
*
* \internal
* Creates a new block to the left with the memory before the slice start (if
* any), a block to the right with the memory after the slice (if any), and
* returns the reduced memory block itself as the slice.
*/
static TMemBlock* SliceBlock(TMemBlock *p,
int startofs, int size,
int reserved, int alignment)
@@ -111,6 +153,27 @@ static TMemBlock* SliceBlock(TMemBlock *p,
return p;
}
/**
* \brief Allocate a memory block.
*
* Allocate \p size bytes with a \p 2^align2 bytes alignment, restricting the
* search to free memory after \p startSearch. Depth and back buffers should
* be in different 4MB banks to get better page hits if possible.
*
* \param heap memory heap.
* \param size size to allocate in bytes.
* \param align2 base 2 log of the block alignment in bytes.
* \param startSearch linear offset from start of the heap to begin the
* search.
*
* \return pointer to the allocated block on success, or NULL on failure.
*
* \internal
* Walks through the free blocks on the heap and if it finds one above
* \p startSearch and large enough slices it via SliceBlock() and returns the
* result.
*/
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
{
int mask,startofs,endofs;
@@ -140,6 +203,17 @@ PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
return p;
}
/**
* \brief Join two successive free memory blocks.
*
* \param p pointer to first memory block.
*
* \return 1 on success, or 0 on failure.
*
* \internal
* Adds the size of the second block to the first and frees its data structure.
*/
static __inline__ int Join2Blocks(TMemBlock *p)
{
if (p->free && p->next && p->next->free) {
@@ -152,6 +226,18 @@ static __inline__ int Join2Blocks(TMemBlock *p)
return 0;
}
/**
* \brief Free a memory block.
*
* \param pointer to a block.
*
* \return 0 on success, or -1 on failure.
*
* \internal
* Search the given block on the heap, mark it as free and attempt to join it
* with the next one via Join2Blocks().
*/
int mmFreeMem(PMemBlock b)
{
TMemBlock *p,*prev;
@@ -185,6 +271,14 @@ int mmFreeMem(PMemBlock b)
}
/**
* \brief Destroy the memory heap.
*
* \param heap memory heap.
*
* \internal
* Frees each block in the heap.
*/
void mmDestroy(memHeap_t *heap)
{
TMemBlock *p,*q;

View File

@@ -1,5 +1,9 @@
/**
* \file mm.h
* \brief Memory block management.
*/
/*
* GLX Hardware Device Driver common code
* Copyright (C) 1999 Keith Whitwell
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,58 +29,57 @@
#ifndef MM_INC
#define MM_INC
/**
* \brief Memory block/heap.
*/
struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *heap;
int ofs,size;
int align;
int free:1;
int reserved:1;
struct mem_block_t *next; /**< \brief pointer to next block in the heap */
struct mem_block_t *heap; /**< \brief pointer to the heap (first block) */
int ofs; /**< \brief offset */
int size; /**< \brief size */
int align; /**< \brief alignment */
int free:1; /**< \brief free flag */
int reserved:1; /**< \brief reserved flag */
};
/**
* \brief Memory block.
*/
typedef struct mem_block_t TMemBlock;
/**
* \brief Memory block pointer.
*/
typedef struct mem_block_t *PMemBlock;
/* a heap is just the first block in a chain */
/**
* \brief Memory heap.
*
* \note A heap is just the first block in a chain
*/
typedef struct mem_block_t memHeap_t;
/**
* \brief Get Memory block size.
*/
static __inline__ int mmBlockSize(PMemBlock b)
{ return b->size; }
/**
* \brief Get Memory block offset.
*/
static __inline__ int mmOffset(PMemBlock b)
{ return b->ofs; }
/*
* input: total size in bytes
* return: a heap pointer if OK, NULL if error
*/
memHeap_t *mmInit( int ofs, int size );
/*
* Allocate 'size' bytes with 2^align2 bytes alignment,
* restrict the search to free memory after 'startSearch'
* depth and back buffers should be in different 4mb banks
* to get better page hits if possible
* input: size = size of block
* align2 = 2^align2 bytes alignment
* startSearch = linear offset from start of heap to begin search
* return: pointer to the allocated block, 0 if error
*/
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2,
int startSearch );
/*
* Free block starts at offset
* input: pointer to a block
* return: 0 if OK, -1 if error
*/
int mmFreeMem( PMemBlock b );
/*
* destroy MM
*/
void mmDestroy( memHeap_t *mmInit );
void mmDestroy( memHeap_t *heap );
/* For debuging purpose. */
void mmDumpMemInfo( memHeap_t *mmInit );
void mmDumpMemInfo( memHeap_t *heap );
#endif

View File

@@ -1,5 +1,9 @@
/**
* \file mm.c
* \brief Memory block management.
*/
/*
* GLX Hardware Device Driver common code
* Copyright (C) 1999 Keith Whitwell
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -19,20 +23,29 @@
* 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.3 2001/08/18 02:51:03 dawes Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include "mm.h"
#include "hwlog.h"
/* KW: I don't know who the author of this code is, but it wasn't me
* despite what the copyright says...
*/
/**
* \brief Dump memory information about the heap.
*
* \param heap memory heap.
*
* \note For debugging purposes.
*
* \internal
* Prints the offset, size and flags for each block.
*/
void mmDumpMemInfo( memHeap_t *heap )
{
TMemBlock *p;
@@ -52,6 +65,19 @@ void mmDumpMemInfo( memHeap_t *heap )
fprintf(stderr, "End of memory blocks\n");
}
/**
* \brief Memory heap initialization.
*
* \param offset offset in bytes.
* \param size total size in bytes
*
* \return a heap pointer on success, or NULL on failure.
*
* \internal
* Allocate a mem_block_t structure and initialize it with the heap
* information.
*/
memHeap_t *mmInit(int ofs,
int size)
{
@@ -71,6 +97,22 @@ memHeap_t *mmInit(int ofs,
}
/**
* \brief Slice a free memory block.
*
* \param p memory block.
* \param startofs slice start offset.
* \param size slice size.
* \param reserved reserved flag.
* \param alignment slice alignment.
*
* \return pointer to the slice block on success, or NULL on failure.
*
* \internal
* Creates a new block to the left with the memory before the slice start (if
* any), a block to the right with the memory after the slice (if any), and
* returns the reduced memory block itself as the slice.
*/
static TMemBlock* SliceBlock(TMemBlock *p,
int startofs, int size,
int reserved, int alignment)
@@ -111,6 +153,27 @@ static TMemBlock* SliceBlock(TMemBlock *p,
return p;
}
/**
* \brief Allocate a memory block.
*
* Allocate \p size bytes with a \p 2^align2 bytes alignment, restricting the
* search to free memory after \p startSearch. Depth and back buffers should
* be in different 4MB banks to get better page hits if possible.
*
* \param heap memory heap.
* \param size size to allocate in bytes.
* \param align2 base 2 log of the block alignment in bytes.
* \param startSearch linear offset from start of the heap to begin the
* search.
*
* \return pointer to the allocated block on success, or NULL on failure.
*
* \internal
* Walks through the free blocks on the heap and if it finds one above
* \p startSearch and large enough slices it via SliceBlock() and returns the
* result.
*/
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
{
int mask,startofs,endofs;
@@ -140,6 +203,17 @@ PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
return p;
}
/**
* \brief Join two successive free memory blocks.
*
* \param p pointer to first memory block.
*
* \return 1 on success, or 0 on failure.
*
* \internal
* Adds the size of the second block to the first and frees its data structure.
*/
static __inline__ int Join2Blocks(TMemBlock *p)
{
if (p->free && p->next && p->next->free) {
@@ -152,6 +226,18 @@ static __inline__ int Join2Blocks(TMemBlock *p)
return 0;
}
/**
* \brief Free a memory block.
*
* \param pointer to a block.
*
* \return 0 on success, or -1 on failure.
*
* \internal
* Search the given block on the heap, mark it as free and attempt to join it
* with the next one via Join2Blocks().
*/
int mmFreeMem(PMemBlock b)
{
TMemBlock *p,*prev;
@@ -185,6 +271,14 @@ int mmFreeMem(PMemBlock b)
}
/**
* \brief Destroy the memory heap.
*
* \param heap memory heap.
*
* \internal
* Frees each block in the heap.
*/
void mmDestroy(memHeap_t *heap)
{
TMemBlock *p,*q;

View File

@@ -1,5 +1,9 @@
/**
* \file mm.h
* \brief Memory block management.
*/
/*
* GLX Hardware Device Driver common code
* Copyright (C) 1999 Keith Whitwell
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,58 +29,57 @@
#ifndef MM_INC
#define MM_INC
/**
* \brief Memory block/heap.
*/
struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *heap;
int ofs,size;
int align;
int free:1;
int reserved:1;
struct mem_block_t *next; /**< \brief pointer to next block in the heap */
struct mem_block_t *heap; /**< \brief pointer to the heap (first block) */
int ofs; /**< \brief offset */
int size; /**< \brief size */
int align; /**< \brief alignment */
int free:1; /**< \brief free flag */
int reserved:1; /**< \brief reserved flag */
};
/**
* \brief Memory block.
*/
typedef struct mem_block_t TMemBlock;
/**
* \brief Memory block pointer.
*/
typedef struct mem_block_t *PMemBlock;
/* a heap is just the first block in a chain */
/**
* \brief Memory heap.
*
* \note A heap is just the first block in a chain
*/
typedef struct mem_block_t memHeap_t;
/**
* \brief Get Memory block size.
*/
static __inline__ int mmBlockSize(PMemBlock b)
{ return b->size; }
/**
* \brief Get Memory block offset.
*/
static __inline__ int mmOffset(PMemBlock b)
{ return b->ofs; }
/*
* input: total size in bytes
* return: a heap pointer if OK, NULL if error
*/
memHeap_t *mmInit( int ofs, int size );
/*
* Allocate 'size' bytes with 2^align2 bytes alignment,
* restrict the search to free memory after 'startSearch'
* depth and back buffers should be in different 4mb banks
* to get better page hits if possible
* input: size = size of block
* align2 = 2^align2 bytes alignment
* startSearch = linear offset from start of heap to begin search
* return: pointer to the allocated block, 0 if error
*/
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2,
int startSearch );
/*
* Free block starts at offset
* input: pointer to a block
* return: 0 if OK, -1 if error
*/
int mmFreeMem( PMemBlock b );
/*
* destroy MM
*/
void mmDestroy( memHeap_t *mmInit );
void mmDestroy( memHeap_t *heap );
/* For debuging purpose. */
void mmDumpMemInfo( memHeap_t *mmInit );
void mmDumpMemInfo( memHeap_t *heap );
#endif

View File

@@ -0,0 +1 @@
*.d

View File

@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1.2.12 2003/01/20 14:50:18 keithw Exp $
# $Id: Makefile,v 1.1.2.25 2003/02/23 20:24:11 keithw Exp $
# Mesa 3-D graphics library
# Version: 5.0
@@ -9,15 +9,27 @@
MESA = ../../..
MESABUILDDIR = ../..
INCLUDES = -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common \
-I$(MESABUILDDIR)/miniglx -Iserver
SHARED_INCLUDES = -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -Iserver
MINIGLX_INCLUDES = -I$(MESABUILDDIR)/miniglx
DRI_INCLUDES = -I$(MESABUILDDIR)/dri
DEFINES = -D_HAVE_SWRAST=1 -D_HAVE_SWTNL=1 -D_HAVE_SANITY=1
CFLAGS = $(INCLUDES) $(DEFINES) -g -MD -DGLX_DIRECT_RENDERING
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
CFLAGS = $(INCLUDES) $(DEFINES) -g -MD -Wall -Wpointer-arith \
-Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wnested-externs
# The .a files for each mesa module required by this driver:
#
COREMESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \
FULL_MESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \
$(MESABUILDDIR)/tnl/tnl.a \
$(MESABUILDDIR)/math/math.a \
$(MESABUILDDIR)/array_cache/array_cache.a \
@@ -25,31 +37,53 @@ COREMESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \
$(MESABUILDDIR)/mesa.a \
$(MESABUILDDIR)/math/math.a #kludge
DRIVER_SOURCES = server/radeon_dri.c \
radeon_compat.c \
radeon_context.c \
SUBSET_MESA = $(MESABUILDDIR)/mesa.a \
$(MESABUILDDIR)/math/math.a
DRI = $(MESABUILDDIR)/dri/dri.a
MINIGLX_SOURCES = server/radeon_dri.c
DRIVER_SOURCES = radeon_context.c \
radeon_ioctl.c \
radeon_lock.c \
radeon_maos.c \
radeon_sanity.c \
radeon_screen.c \
radeon_span.c \
radeon_state.c \
radeon_state_init.c \
radeon_swtcl.c \
radeon_tcl.c \
../common/mm.c
SUBSET_DRIVER_SOURCES = \
radeon_subset_bitmap.c \
radeon_subset_readpix.c \
radeon_subset_select.c \
radeon_subset_tex.c \
radeon_subset_vtx.c
FULL_DRIVER_SOURCES = \
radeon_tex.c \
radeon_texmem.c \
radeon_texstate.c \
radeon_lighting.c \
radeon_userclip.c \
radeon_texgen.c \
radeon_tcl.c \
radeon_swtcl.c \
radeon_span.c \
radeon_maos.c \
radeon_sanity.c \
radeon_compat.c \
radeon_vtxfmt.c \
radeon_vtxfmt_c.c \
radeon_vtxfmt_sse.c \
radeon_vtxfmt_x86.c \
../common/mm.c
radeon_vtxfmt_x86.c
INCLUDES = $(MINIGLX_INCLUDES) \
$(SHARED_INCLUDES)
C_SOURCES = $(DRIVER_SOURCES) \
$(DRI_SOURCES)
$(SUBSET_DRIVER_SOURCES) \
$(MINIGLX_SOURCES)
ASM_SOURCES =
@@ -70,8 +104,16 @@ OBJECTS = $(C_SOURCES:.c=.o) \
default: radeon_dri.so install
radeon_dri.so: $(COREMESA) $(OBJECTS) Makefile
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(COREMESA) -L$(MESA)/src/miniglx -lGL -lc -lm
radeon_dri.so: $(SUBSET_MESA) $(OBJECTS) Makefile
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(SUBSET_MESA) -L$(MESA)/src/miniglx -lGL -lc -lm
#radeon_dri.so: $(SUBSET_MESA) $(DRI) $(OBJECTS) Makefile
# rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(SUBSET_MESA) $(DRI) -lc -lm
loc:
wc -l $(DRIVER_SOURCES) $(SUBSET_DRIVER_SOURCES)
wc -l $(DRIVER_SOURCES) $(FULL_DRIVER_SOURCES) radeon_maos_verts.c radeon_maos_vbtmp.h
install:
rm -f $(MESA)/lib/radeon_dri.so && \

View File

@@ -33,6 +33,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#if _HAVE_SWTNL
#include "glheader.h"
#include "imports.h"
@@ -302,3 +304,4 @@ void radeonCompatEmitPrimitive( radeonContextPtr rmesa,
UNLOCK_HARDWARE( rmesa );
}
#endif

View File

@@ -1,40 +1,40 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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.
**************************************************************************/
/**
* \file radeon_context.c
* \brief Device specific context initialization.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
#include "glheader.h"
#include "imports.h"
#include "api_arrayelt.h"
@@ -43,26 +43,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "matrix.h"
#include "extensions.h"
#if _HAVE_SWRAST
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "radeon_span.h"
#endif
#if _HAVE_SWTNL
#include "array_cache/acache.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "radeon_swtcl.h"
#include "radeon_maos.h"
#endif
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tex.h"
#if _HAVE_FULL_GL
#include "radeon_tcl.h"
#include "radeon_vtxfmt.h"
#include "radeon_tex.h"
#else
#include "radeon_subset.h"
#endif
#if defined(USE_X86_ASM)
#include "X86/common_x86_asm.h"
@@ -75,8 +66,15 @@ int RADEON_DEBUG = (0);
#endif
/* Return the width and height of the given buffer.
/**
* \brief Return the width and height of the given buffer.
*
* \param buffer frame buffer. Not used.
* \param width will hold the width of the buffer.
* \param height will hold the height of the buffer.
*
* Returns the width and height of the current drawable while holding the
* hardware lock.
*/
static void radeonGetBufferSize( GLframebuffer *buffer,
GLuint *width, GLuint *height )
@@ -90,11 +88,22 @@ static void radeonGetBufferSize( GLframebuffer *buffer,
UNLOCK_HARDWARE( rmesa );
}
/* Return various strings for glGetString().
/**
* \brief Return various strings for glGetString().
*
* \param ctx GL context.
* \param name name of the string to return.
*
* \param pointer to a static string describing the aspect specified by \p
* name.
*
* \sa glGetString().
*
* Returns the wanted string, appending miscellaneous information (such as AGP
* mode, processor abilities, TCL support, etc.) for the GL_RENDERER aspect.
*/
static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
static char buffer[128];
switch ( name ) {
@@ -102,58 +111,7 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
return (GLubyte *)"Tungsten Graphics, Inc.";
case GL_RENDERER:
sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE);
/* Append any chipset-specific information. None yet.
*/
/* Append any AGP-specific information.
*/
switch ( rmesa->radeonScreen->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->dri.drmMinor < 3 ) {
strncat( buffer, " DRM-COMPAT", 11 );
}
if ( !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) ) {
strncat( buffer, " TCL", 4 );
}
else {
strncat( buffer, " NO-TCL", 7 );
}
sprintf( buffer, "Mesa DRI Radeon SUBSET " RADEON_DATE);
return (GLubyte *)buffer;
@@ -163,10 +121,14 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
}
/* Extension strings exported by the R100 driver.
/**
* \brief Device specific extension names exported by the R100 driver.
*
* \note None in the case of the subset driver.
*/
static const char * const radeon_extensions[] =
{
#if _HAVE_FULL_GL
"GL_ARB_multisample",
"GL_ARB_multitexture",
"GL_ARB_texture_border_clamp",
@@ -189,10 +151,17 @@ static const char * const radeon_extensions[] =
"GL_NV_blend_square",
"GL_SGIS_generate_mipmap",
"GL_SGIS_texture_border_clamp",
#endif
NULL
};
/* Initialize the extensions supported by this driver.
/**
* \brief Initialize the extensions supported by this driver.
*
* \param ctx GL context.
*
* Enables the imaging extensions plus every extension specified in in the
* ::radeon_extensions table.
*/
static void radeonInitExtensions( GLcontext *ctx )
{
@@ -204,43 +173,15 @@ static void radeonInitExtensions( GLcontext *ctx )
}
}
#if _HAVE_SWTNL
extern const struct gl_pipeline_stage _radeon_render_stage;
extern const struct gl_pipeline_stage _radeon_tcl_stage;
static const struct gl_pipeline_stage *radeon_pipeline[] = {
/* Try and go straight to t&l
*/
&_radeon_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.
*/
&_radeon_render_stage,
&_tnl_render_stage, /* FALLBACK: */
0,
};
#endif
/**
* \brief Resize the buffers.
*
* \param buffer frame buffer to be resized.
*
* Informs the software rasterizer (if enabled at compile time) of the buffer
* resizing.
*/
static void ResizeBuffers( GLframebuffer *buffer )
{
#if _HAVE_SWRAST
@@ -248,7 +189,11 @@ static void ResizeBuffers( GLframebuffer *buffer )
#endif
}
/* Initialize the driver's misc functions.
/**
* \brief Initialize the driver miscellaneous function callbacks.
*
* \param ctx GL context.
*/
static void radeonInitDriverFuncs( GLcontext *ctx )
{
@@ -257,12 +202,33 @@ static void radeonInitDriverFuncs( GLcontext *ctx )
ctx->Driver.ResizeBuffers = ResizeBuffers;
ctx->Driver.Error = NULL;
ctx->Driver.DrawPixels = NULL;
ctx->Driver.Bitmap = NULL;
ctx->Driver.Bitmap = radeonPointsBitmap;
ctx->Driver.ReadPixels = radeonReadPixels;
}
/* Create the device specific context.
/**
* \brief Create the device specific context.
*
* \param glVisual visual information.
* \param driContextPriv DRI specific context data.
* \param sharedContextPrivate shared context.
*
* \return GL_TRUE if successful, or GL_FALSE otherwise.
*
* Allocates a Radeon context and initializes it, adding a Mesa context. Fills
* in with information from the Radeon specific screen data in
* __DRIscreenPrivateRec::private, such as the SAREA pointer, DMA buffers
* addresses and texture heaps.
*
* Calls the \c radeonInit* functions to populate the driver callback
* functions. Among these are radeonInitState(), radeonInitExtensions(),
* radeonInitDriverFuncs(), radeonInitIoctlFuncs(), radeonInitStateFuncs(),
* radeonInitTextureFuncs() and radeonInitSelect().
*
* If compiled with debug support, reads the RADEON_DEBUG environment variable
* and sets the debugging flags accordingly.
*/
static GLboolean
radeonCreateContext( const __GLcontextModes *glVisual,
@@ -273,7 +239,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
radeonScreenPtr radeonScreen = (radeonScreenPtr)(sPriv->private);
radeonContextPtr rmesa;
GLcontext *ctx, *shareCtx;
int i;
int i, nr;
assert(glVisual);
assert(driContextPriv);
@@ -327,8 +293,9 @@ radeonCreateContext( const __GLcontextModes *glVisual,
rmesa->texture.numHeaps = radeonScreen->numTexHeaps;
make_empty_list( &rmesa->texture.swapped );
rmesa->swtcl.RenderIndex = ~0;
rmesa->lost_context = 1;
rmesa->tcl.tcl_flag = RADEON_CP_VC_CNTL_TCL_ENABLE;
/* KW: Set the maximum texture size small enough that we can
* guarentee that both texture units can bind a maximal texture
@@ -336,20 +303,27 @@ radeonCreateContext( const __GLcontextModes *glVisual,
* Test for 2 textures * 4 bytes/texel * size * size.
*/
ctx = rmesa->glCtx;
if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 2048 * 2048) {
#if _HAVE_FULL_GL
nr = 2;
#else
nr = 1;
#endif
ctx->Const.MaxTextureUnits = nr;
if (radeonScreen->texSize[RADEON_CARD_HEAP] >= nr * 4 * 2048 * 2048) {
ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */
}
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 1024 * 1024) {
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= nr * 4 * 1024 * 1024) {
ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */
}
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 512 * 512) {
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= nr * 4 * 512 * 512) {
ctx->Const.MaxTextureLevels = 10; /* 512x512 */
}
else {
ctx->Const.MaxTextureLevels = 9; /* 256x256 */
}
ctx->Const.MaxTextureUnits = 2;
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
/* No wide points.
@@ -365,57 +339,22 @@ radeonCreateContext( const __GLcontextModes *glVisual,
ctx->Const.MaxLineWidthAA = 10.0;
ctx->Const.LineWidthGranularity = 0.0625;
/* Set maxlocksize (and hence vb size) small enough to avoid
* fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
* fit in a single dma buffer for indexed rendering of quad strips,
* etc.
*/
/* ctx->Const.MaxArrayLockSize = */
/* MIN2( ctx->Const.MaxArrayLockSize, */
/* RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); */
if (getenv("LIBGL_PERFORMANCE_BOXES"))
rmesa->boxes = 1;
else
rmesa->boxes = 0;
/* Initialize the software rasterizer and helper modules.
*/
#if _HAVE_SWRAST
_swrast_CreateContext( ctx );
/* Configure swrast to match hardware characteristics:
*/
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
radeonCreateSwrastContext( ctx );
#endif
_ae_create_context( ctx );
#if _HAVE_SWTNL
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
/* Install the customized pipeline:
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, radeon_pipeline );
/* Try and keep materials and vertices separate:
*/
_tnl_isolate_materials( ctx, GL_TRUE );
#if _HAVE_SWRAST
_swsetup_CreateContext( ctx );
#endif
radeonCreateTnlContext( ctx );
#endif
radeonInitState( rmesa );
_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 );
#if _HAVE_TEXGEN
radeonInitTexTransform( ctx );
#endif
#if _HAVE_LIGHTING
radeonInitLightStateFuncs( ctx );
#endif
radeonInitExtensions( ctx );
radeonInitDriverFuncs( ctx );
radeonInitIoctlFuncs( ctx );
@@ -424,10 +363,11 @@ radeonCreateContext( const __GLcontextModes *glVisual,
radeonInitSpanFuncs( ctx );
#endif
radeonInitTextureFuncs( ctx );
radeonInitState( rmesa );
#if _HAVE_SWTNL
radeonInitSwtcl( ctx );
#endif
radeonInitSelect( ctx );
rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS"));
rmesa->irqsEmitted = 0;
@@ -477,6 +417,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
}
#endif
#if _HAVE_SWRAST && _HAVE_SWTNL
if (getenv("RADEON_NO_RAST")) {
fprintf(stderr, "disabling 3D acceleration\n");
FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
@@ -496,17 +437,27 @@ radeonCreateContext( const __GLcontextModes *glVisual,
if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
if (!getenv("RADEON_NO_VTXFMT"))
radeonVtxfmtInit( ctx );
#if _HAVE_SWTNL
_tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
#endif
}
#else
radeonVtxfmtInit( ctx );
#endif
return GL_TRUE;
}
/* Destroy the device specific context.
*/
/* Destroy the Mesa and driver specific context data.
/**
* \brief Destroy the device specific context data.
*
* \param driContextPriv DRI specific context data.
*
* If destroying the currently bound context, fires the vertices and unbinds it
* first.
*
* Frees the radeon context resources, freeing the Mesa context. Frees the
* private texture object from the shared context data if its reference count
* reaches zero.
*/
static void
radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
@@ -561,9 +512,11 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
radeonFlushCmdBuf( rmesa, __FUNCTION__ );
}
#if _HAVE_FULL_GL
if (!rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
if (!getenv("RADEON_NO_VTXFMT"))
radeonVtxfmtDestroy( rmesa->glCtx );
#endif
/* free the Mesa context */
rmesa->glCtx->DriverCtx = NULL;
@@ -580,10 +533,16 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
}
/* Create and initialize the Mesa and driver specific pixmap buffer
/**
* \brief Create and initialize the Mesa and device specific pixmap buffer
* data.
*
* \param driScrnPriv DRI specific screen data.
* \param driDrawPriv DRI specific drawable data.
* \param mesaVis visual.
* \param isPixmap must be GL_FALSE. Not implemented.
*
* Calls _mesa_create_framebuffer() to create the framebuffer.
*/
static GLboolean
radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
@@ -595,11 +554,18 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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;
GLboolean swDepth = GL_FALSE;
GLboolean swAlpha = GL_FALSE;
GLboolean swAccum = mesaVis->accumRedBits > 0;
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24);
#if !_HAVE_SWRAST
/* Don't allow these if we don't have fallback support.
*/
swAccum = swStencil = GL_FALSE;
#endif
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer( mesaVis,
swDepth,
@@ -611,6 +577,13 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
}
/**
* \brief Destroy device specific pixmap data.
*
* \param driDrawPriv DRI specific drawable data.
*
* Calls _mesa_destroy_framebuffer() to destroy Mesa framebuffer.
*/
static void
radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
@@ -618,7 +591,14 @@ radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
}
/**
* \brief Swap buffers.
*
* \param dPriv DRI specific drawable data.
*
* If in double buffer mode then it dispatches the call to radeonCopyBuffer()
* or radeonPageFlip() if page flipping is also enabled.
*/
static void
radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
{
@@ -646,8 +626,19 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
}
/* Force the context `c' to be the current context and associate with it
* buffer `b'.
/**
* \brief Set the current context.
*
* \param driContextPriv DRI specific context data to be activated.
* \param driDrawPriv DRI specific drawable data, to which the context is to be
* associated for writing.
* \param driReadPriv DRI specific drawable data, to which the context is to be
* associated for reading.
*
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* If drawables differ form the current ones then update the window and
* viewport information. Calls _mesa_make_current2() to set the context.
*/
static GLboolean
radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
@@ -676,8 +667,10 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
driDrawPriv->w, driDrawPriv->h );
}
if (newRadeonCtx->vb.enabled)
radeonVtxfmtMakeCurrent( newRadeonCtx->glCtx );
#if _HAVE_FULL_GL
if (newRadeonCtx->vb.enabled)
radeonVtxfmtMakeCurrent( newRadeonCtx->glCtx );
#endif
} else {
if (RADEON_DEBUG & DEBUG_DRI)
@@ -690,7 +683,15 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
return GL_TRUE;
}
/* Force the context `c' to be unbound from its buffer.
/**
* \brief Unbind context from its buffer.
*
* \param driContextPriv DRI specifc context data.
*
* \returns always GL_TRUE.
*
* Calls radeonVtxfmtUnbindContext().
*/
static GLboolean
radeonUnbindContext( __DRIcontextPrivate *driContextPriv )
@@ -704,12 +705,22 @@ radeonUnbindContext( __DRIcontextPrivate *driContextPriv )
return GL_TRUE;
}
/* 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.
/**
* \brief Open/close fullscreen mode.
*
* Pageflipping is now done automatically whenever there is a single
* 3d client.
* \note Fullscreen mode isn't used for much - it could be a way to shrink
* front/back buffers and get more texture memory if the client has changed the
* video resolution.
*
* \par
* Pageflipping is now done automatically whenever there is a single 3D client.
*
* \param driContextPriv DRI specific context data. Not used.
*
* \return always GL_TRUE.
*
* This function is a no-op.
*/
static GLboolean
radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
@@ -727,8 +738,15 @@ __driRegisterExtensions( void )
/* Initialize the driver specific screen private data. (Called as
* callback from __driUtilCreateScreen below).
/**
* \brief Initialize the driver specific screen private data.
*
* \param sPriv DRI specific screen data.
*
* \return GL_TRUE on success or GL_FALSE on faillure.
*
* Calls radeonCreateScreen() and if it fails calls radeonDestroyScreen()
* before returning.
*/
static GLboolean
radeonInitDriver( __DRIscreenPrivate *sPriv )
@@ -743,7 +761,11 @@ radeonInitDriver( __DRIscreenPrivate *sPriv )
}
/**
* \brief Driver interface structure
*
* Holds the DRI driver callbacks.
*/
static struct __DriverAPIRec radeonAPI = {
radeonInitDriver,
radeonDestroyScreen,
@@ -760,10 +782,14 @@ static struct __DriverAPIRec radeonAPI = {
/*
* This is the bootstrap function for the driver.
* The __driCreateScreen name is the symbol that libGL.so fetches.
* Return: pointer to a __DRIscreenPrivate.
/**
* \brief Bootstrap function for the driver.
*
* The \e __driCreateScreen name is the symbol that libGL.so fetches.
*
* \return pointer to a ::__DRIscreenPrivate structure.
*
* Calls __driUtilCreateScreen() with ::radeonAPI.
*/
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)

View File

@@ -1,44 +1,44 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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.
**************************************************************************/
/**
* \file radeon_context.h
* \brief Radeon OpenGL context definition.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
#ifndef __RADEON_CONTEXT_H__
#define __RADEON_CONTEXT_H__
#ifdef GLX_DIRECT_RENDERING
struct radeon_context;
typedef struct radeon_context radeonContextRec;
typedef struct radeon_context *radeonContextPtr;
@@ -49,67 +49,60 @@ typedef struct radeon_context *radeonContextPtr;
#include "radeon_screen.h"
#include "mm.h"
/* Flags for software fallback cases */
/* See correponding strings in radeon_swtcl.c */
#define RADEON_FALLBACK_TEXTURE 0x0001
#define RADEON_FALLBACK_DRAW_BUFFER 0x0002
#define RADEON_FALLBACK_STENCIL 0x0004
#define RADEON_FALLBACK_RENDER_MODE 0x0008
#define RADEON_FALLBACK_BLEND_EQ 0x0010
#define RADEON_FALLBACK_BLEND_FUNC 0x0020
#define RADEON_FALLBACK_DISABLE 0x0040
#if _HAVE_SWTNL
#include "radeon_swtcl.h"
#endif
/* Use the templated vertex format:
/**
* \brief Color buffer state.
*/
#define COLOR_IS_RGBA
#define TAG(x) radeon##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
typedef void (*radeon_tri_func)( radeonContextPtr,
radeonVertex *,
radeonVertex *,
radeonVertex * );
typedef void (*radeon_line_func)( radeonContextPtr,
radeonVertex *,
radeonVertex * );
typedef void (*radeon_point_func)( radeonContextPtr,
radeonVertex * );
struct radeon_colorbuffer_state {
GLuint clear;
GLint drawOffset, drawPitch;
GLuint clear; /**< \brief Clear value */
GLint drawOffset; /**< \brief Drawing offset */
GLint drawPitch; /**< \brief Drawing pitch */
};
/**
* \brief Depth buffer state.
*/
struct radeon_depthbuffer_state {
GLuint clear;
GLfloat scale;
GLuint clear; /**< \brief Clear value */
GLfloat scale; /**< \brief Depth scale */
};
/**
* \brief Pixel state.
*/
struct radeon_pixel_state {
GLint readOffset, readPitch;
GLint readOffset; /**< \brief Reading offset */
GLint readPitch; /**< \brief Reading pitch */
};
/**
* \brief Scissor state.
*/
struct radeon_scissor_state {
XF86DRIClipRectRec rect;
GLboolean enabled;
GLboolean enabled; /**< \brief Whether scissoring enable */
GLuint numClipRects; /* Cliprects active */
GLuint numAllocedClipRects; /* Cliprects available */
XF86DRIClipRectPtr pClipRects;
GLuint numClipRects; /**< \brief Number of active cliprects */
GLuint numAllocedClipRects; /**< \brief Number of available cliprects */
XF86DRIClipRectPtr pClipRects; /**< \brief Cliprects */
};
/**
* \brief Stencil buffer state.
*/
struct radeon_stencilbuffer_state {
GLboolean hwBuffer;
GLuint clear; /* rb3d_stencilrefmask value */
GLboolean hwBuffer; /**< \brief Hardware buffer available? */
GLuint clear; /**< \brief rb3d_stencilrefmask value */
};
/**
* \brief Stipple state.
*/
struct radeon_stipple_state {
GLuint mask[32];
GLuint mask[32]; /**< \brief Mask */
};
@@ -118,69 +111,98 @@ struct radeon_stipple_state {
#define TEX_1 0x2
#define TEX_ALL 0x3
typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr;
/* Texture object in locally shared texture space.
typedef struct radeon_tex_obj radeonTexObj; /**< \brief Alias for radeon_tex_obj. */
typedef struct radeon_tex_obj *radeonTexObjPtr; /**< \brief Alias for radeon_tex_obj. */
/**
* \brief Texture object in locally shared texture space.
*/
struct radeon_tex_obj {
radeonTexObjPtr next, prev;
struct gl_texture_object *tObj; /* Mesa texture object */
/** \brief Mesa texture object */
struct gl_texture_object *tObj;
PMemBlock memBlock; /* Memory block containing texture */
GLuint bufAddr; /* Offset to start of locally
shared texture block */
/** \brief Memory block containing texture */
PMemBlock memBlock;
/** \brief Offset to start of locally shared texture block */
GLuint bufAddr;
/**
* \brief Flags for whether or not images need to be uploaded to local or AGP
* texture space
*/
GLuint dirty_images;
GLuint dirty_images; /* Flags for whether or not
images need to be uploaded to
local or AGP texture space */
/**
* \brief Flags (one per texture unit) for whether or not this texture
* object has dirty hardware state (\c pp_*) that needs to be brought into
* the texunit.
*/
GLuint dirty_state;
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 */
/** \brief Texture heap currently stored in */
GLint heap;
/** \brief Texture images */
drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS];
GLint totalSize; /* Total size of the texture
including all mipmap levels */
/** \brief Total size of the texture including all mipmap levels */
GLint totalSize;
GLuint pp_txfilter; /* hardware register values */
/**
* \name Hardware register values.
*/
/*@{*/
GLuint pp_txfilter;
GLuint pp_txformat;
GLuint pp_txoffset;
GLuint pp_border_color;
/*@}*/
/* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the
/**
* \name Images to upload
*
* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the
* images to upload.
*/
/*@{*/
GLint firstLevel;
GLint lastLevel;
GLint lastLevel;
/*@}*/
};
/**
* \brief Texture environment state.
*/
struct radeon_texture_env_state {
radeonTexObjPtr texobj;
GLenum format;
GLenum envMode;
radeonTexObjPtr texobj; /**< \brief texture object */
GLenum format; /**< \brief format */
GLenum envMode; /**< \brief environment mode */
};
/**
* \brief Texture state
*/
struct radeon_texture_state {
struct radeon_texture_env_state unit[RADEON_MAX_TEXTURE_UNITS];
struct radeon_texture_env_state unit[RADEON_MAX_TEXTURE_UNITS]; /**< \brief for each unit */
};
/**
* \brief Radeon state atom double-linked list.
*/
struct radeon_state_atom {
struct radeon_state_atom *next, *prev;
const char *name; /* for debug */
int cmd_size; /* size in bytes */
GLuint is_tcl;
int *cmd; /* one or more cmd's */
int *lastcmd; /* one or more cmd's */
GLboolean (*check)( GLcontext * ); /* is this state active? */
const char *name; /**< \brief for debugging purposes */
int cmd_size; /**< \brief size in bytes */
GLuint is_tcl; /**< \brief whether is associated with TCL */
int *cmd; /**< \brief one or more cmd's */
int *lastcmd; /**< \brief one or more cmd's */
GLboolean (*check)( GLcontext * ); /**< \brief callback to determin whether this state is active */
};
@@ -227,14 +249,14 @@ struct radeon_state_atom {
#define MSK_RB3D_PLANEMASK 3
#define MSK_STATE_SIZE 4
#define VPT_CMD_0 0
#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 VPT_STATE_SIZE 7
#define MSC_CMD_0 0
#define MSC_RE_MISC 1
@@ -251,12 +273,12 @@ struct radeon_state_atom {
#define TEX_PP_BORDER_COLOR 8
#define TEX_STATE_SIZE 9
#define ZBS_CMD_0 0
#define ZBS_SE_ZBIAS_FACTOR 1
#define ZBS_SE_ZBIAS_CONSTANT 2
#define ZBS_STATE_SIZE 3
#define ZBS_CMD_0 0
#define ZBS_SE_ZBIAS_FACTOR 1
#define ZBS_SE_ZBIAS_CONSTANT 2
#define ZBS_STATE_SIZE 3
#define TCL_CMD_0 0
#define TCL_CMD_0 0
#define TCL_OUTPUT_VTXFMT 1
#define TCL_OUTPUT_VTXSEL 2
#define TCL_MATRIX_SELECT_0 3
@@ -268,7 +290,7 @@ struct radeon_state_atom {
#define TCL_PER_LIGHT_CTL_1 9
#define TCL_PER_LIGHT_CTL_2 10
#define TCL_PER_LIGHT_CTL_3 11
#define TCL_STATE_SIZE 12
#define TCL_STATE_SIZE 12
#define MTL_CMD_0 0
#define MTL_EMMISSIVE_RED 1
@@ -383,126 +405,176 @@ struct radeon_state_atom {
#define SHN_STATE_SIZE 2
/**
* \brief Hardware state management.
*/
struct radeon_hw_state {
/* All state should be on one of these lists:
/**
* \name State
*
* All state should be on one of these lists
*/
struct radeon_state_atom dirty; /* dirty list head placeholder */
struct radeon_state_atom clean; /* clean list head placeholder */
/*@{*/
struct radeon_state_atom dirty; /**< \brief dirty list head placeholder */
struct radeon_state_atom clean; /**< \brief 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)
/**
* \name Hardware state
*
* Stored as cmdbuf commands:
* - Need to doublebuffer for
* - reviving state after loss of context
* - eliding no-op statechange loops? (except line stipple count)
*/
/*@{*/
struct radeon_state_atom ctx;
struct radeon_state_atom set;
struct radeon_state_atom lin;
struct radeon_state_atom msk;
struct radeon_state_atom vpt;
struct radeon_state_atom tcl;
struct radeon_state_atom tcl; /**< \ brief TCL */
struct radeon_state_atom msc;
struct radeon_state_atom tex[2];
struct radeon_state_atom zbs;
struct radeon_state_atom mtl;
struct radeon_state_atom mat[5];
struct radeon_state_atom lit[8]; /* includes vec, scl commands */
struct radeon_state_atom mat[5]; /**< \brief matrix transformations */
#if _HAVE_LIGHTING
struct radeon_state_atom lit[8]; /**< \brief includes vec, scl commands */
#endif
#if _HAVE_USERCLIP
struct radeon_state_atom ucp[6];
struct radeon_state_atom eye; /* eye pos */
struct radeon_state_atom grd; /* guard band clipping */
struct radeon_state_atom fog;
#endif
struct radeon_state_atom eye; /**< \brief eye pos */
struct radeon_state_atom grd; /**< \brief guard band clipping */
struct radeon_state_atom fog; /**< \brief fog */
struct radeon_state_atom glt;
/*@}*/
};
/**
* \brief Derived state for internal purposes:
*/
struct radeon_state {
/* Derived state for internal purposes:
*/
struct radeon_colorbuffer_state color;
struct radeon_depthbuffer_state depth;
struct radeon_pixel_state pixel;
struct radeon_scissor_state scissor;
struct radeon_stencilbuffer_state stencil;
struct radeon_stipple_state stipple;
struct radeon_texture_state texture;
struct radeon_colorbuffer_state color; /**< \brief Color buffer */
struct radeon_depthbuffer_state depth; /**< \brief Depth buffer */
struct radeon_pixel_state pixel; /**< \brief Pixel */
struct radeon_scissor_state scissor; /**< \brief Scissor */
struct radeon_stencilbuffer_state stencil; /**< \brief Stencil buffer */
struct radeon_stipple_state stipple; /**< \brief Stipple */
struct radeon_texture_state texture; /**< \brief Textures */
};
/**
* \brief Texture information
*/
struct radeon_texture {
radeonTexObj objects[RADEON_NR_TEX_HEAPS];
radeonTexObj swapped;
radeonTexObj objects[RADEON_NR_TEX_HEAPS]; /**< \brief texture objects */
radeonTexObj swapped; /**< \brief swapped texture */
memHeap_t *heap[RADEON_NR_TEX_HEAPS];
GLint age[RADEON_NR_TEX_HEAPS];
memHeap_t *heap[RADEON_NR_TEX_HEAPS]; /**< \brief texture heaps */
GLint age[RADEON_NR_TEX_HEAPS]; /**< \brief aging */
GLint numHeaps;
GLint numHeaps; /**< \brief number of active heaps */
};
/* Need refcounting on dma buffers:
/**
* \brief Reference counting on DMA buffers.
*/
struct radeon_dma_buffer {
int refcount; /* the number of retained regions in buf */
drmBufPtr buf;
int refcount; /**< \brief number of retained regions in radeon_dma_buffer::buf */
drmBufPtr buf; /**< \brief DMA buffer */
};
#define GET_START(rvb) (rmesa->radeonScreen->agp_buffer_offset + \
/**
* \brief Get the start of a DMA region.
*
* \param rvb pointer to a radeon_dma_region structure.
*
* \return pointer to the region start.
*/
#define GET_START(rvb) (rmesa->radeonScreen->agp_buffer_offset + \
(rvb)->address - rmesa->dma.buf0_address + \
(rvb)->start)
/* A retained region, eg vertices for indexed vertices.
/**
* \brief A retained DMA region.
*
* e.g. vertices for indexed vertices.
*/
struct radeon_dma_region {
struct radeon_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 radeon_dma_buffer *buf; /**< \brief DMA buffer */
char *address; /**< \brief buf->address */
int start; /**< \brief start offset from start of radeon_dma_region::buf */
int end; /**< \brief end offset from start of radeon_dma_region::buf */
int ptr; /**< \brief offsets from start of radeon_dma_region::buf */
int aos_start; /**< \brief array of structures start */
int aos_stride; /**< \brief array of structures stride */
int aos_size; /**< \brief array of structures size */
};
/**
* \brief DMA information
*/
struct radeon_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();
/**
* \brief Active DMA region.
*
* Allocations for vertices and retained regions come from here. Also used
* for emitting random vertices, these may be flushed by calling
* radeon_dma::flush.
*/
struct radeon_dma_region current;
/**
* \brief Callback to flush the vertices in radeon_dma::current.
*/
void (*flush)( radeonContextPtr );
char *buf0_address; /* start of buf[0], for index calcs */
GLuint nr_released_bufs; /* flush after so many buffers released */
char *buf0_address; /**< \brief start of buf[0], for index calculations */
GLuint nr_released_bufs; /**< \brief flush after so many buffers released */
};
/**
* \brief Mirror some DRI context.
*/
struct radeon_dri_mirror {
__DRIcontextPrivate *context; /* DRI context */
__DRIscreenPrivate *screen; /* DRI screen */
__DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
__DRIcontextPrivate *context; /**< \brief DRI context */
__DRIscreenPrivate *screen; /**< \brief DRI screen */
__DRIdrawablePrivate *drawable; /**< \brief DRI drawable bound to this context */
drmContext hwContext;
drmLock *hwLock;
int fd;
int drmMinor;
drmContext hwContext;
drmLock *hwLock; /**< \brief hardware lock */
int fd; /**< \brief DRM device file descriptor */
int drmMinor; /**< \brief DRM device minor number */
};
/**
* \brief Command buffer size
*/
#define RADEON_CMD_BUF_SZ (8*1024)
/**
* \brief Command buffering.
*/
struct radeon_store {
GLuint statenr;
GLuint primnr;
char cmd_buf[RADEON_CMD_BUF_SZ];
int cmd_used;
GLuint statenr; /**< \brief state number */
GLuint primnr; /**< \brief primitive number */
char cmd_buf[RADEON_CMD_BUF_SZ]; /**< \brief command buffer */
int cmd_used; /**< \brief used commands */
int elts_start;
};
/* radeon_tcl.c
/**
* \brief TCL information.
*/
struct radeon_tcl_info {
GLuint vertex_format;
GLint last_offset;
GLuint hw_primitive;
GLuint tcl_flag; /**< \brief Whether TCL is inabled */
struct radeon_dma_region *aos_components[8];
GLuint nr_aos_components;
@@ -519,214 +591,98 @@ struct radeon_tcl_info {
};
/* radeon_swtcl.c
/**
* \brief Retained buffer.
*/
struct radeon_swtcl_info {
GLuint SetupIndex;
GLuint SetupNewInputs;
GLuint RenderIndex;
GLuint vertex_size;
GLuint vertex_stride_shift;
GLuint vertex_format;
char *verts;
/* Fallback rasterization functions
*/
radeon_point_func draw_point;
radeon_line_func draw_line;
radeon_tri_func draw_tri;
GLuint hw_primitive;
GLenum render_primitive;
GLuint numverts;
struct radeon_dma_region indexed_verts;
};
struct radeon_ioctl {
GLuint vertex_offset;
GLuint vertex_size;
GLuint vertex_offset; /**< \brief offset of the vertex buffer */
GLuint vertex_size; /**< \brief size of the vertex buffer */
};
#define RADEON_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?
/**
* \brief Radeon GL context.
*/
struct dynfn {
struct dynfn *next, *prev;
int key;
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 *, int );
struct dynfn *(*Vertex2fv)( GLcontext *, int );
struct dynfn *(*Vertex3f)( GLcontext *, int );
struct dynfn *(*Vertex3fv)( GLcontext *, int );
struct dynfn *(*Color4ub)( GLcontext *, int );
struct dynfn *(*Color4ubv)( GLcontext *, int );
struct dynfn *(*Color3ub)( GLcontext *, int );
struct dynfn *(*Color3ubv)( GLcontext *, int );
struct dynfn *(*Color4f)( GLcontext *, int );
struct dynfn *(*Color4fv)( GLcontext *, int );
struct dynfn *(*Color3f)( GLcontext *, int );
struct dynfn *(*Color3fv)( GLcontext *, int );
struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int );
struct dynfn *(*Normal3f)( GLcontext *, int );
struct dynfn *(*Normal3fv)( GLcontext *, int );
struct dynfn *(*TexCoord2f)( GLcontext *, int );
struct dynfn *(*TexCoord2fv)( GLcontext *, int );
struct dynfn *(*TexCoord1f)( GLcontext *, int );
struct dynfn *(*TexCoord1fv)( GLcontext *, int );
struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int );
};
struct radeon_vb {
/* Keep these first: referenced from codegen templates:
*/
GLint counter, initial_counter;
GLint *dmaptr;
void (*notify)( void );
GLint vertex_size;
union { float f; int i; radeon_color_t color; } vertex[15];
GLfloat *normalptr;
GLfloat *floatcolorptr;
radeon_color_t *colorptr;
radeon_color_t *specptr;
GLfloat *texcoordptr[2];
GLcontext *context; /* current context : Single thread only! */
};
struct radeon_prim {
GLuint start;
GLuint end;
GLuint prim;
};
struct radeon_vbinfo {
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
GLuint primflags;
GLboolean enabled; /* RADEON_NO_VTXFMT//RADEON_NO_TCL env vars */
GLboolean installed;
GLboolean fell_back;
GLboolean recheck;
GLint initial_counter;
GLint nrverts;
GLuint vertex_format;
GLuint installed_vertex_format;
GLuint installed_color_3f_sz;
struct radeon_prim primlist[RADEON_MAX_PRIMS];
int nrprims;
struct dfn_lists dfn_cache;
struct dfn_generators codegen;
GLvertexformat vtxfmt;
};
struct radeon_context {
GLcontext *glCtx; /* Mesa context */
/* Driver and hardware state management
/**
* \brief Mesa context.
*/
struct radeon_hw_state hw;
struct radeon_state state;
GLcontext *glCtx;
/* Texture object bookkeeping
/**
* \name Driver and hardware state management
*/
/*@{*/
struct radeon_hw_state hw; /**< \brief Hardware state */
struct radeon_state state; /**< \brief Internal state */
/*@}*/
/**
* \brief Texture object bookkeeping
*/
struct radeon_texture texture;
/* Rasterization and vertex state:
/**
* \name Rasterization and vertex state
*/
/*@{*/
GLuint TclFallback;
GLuint Fallback;
GLuint NewGLState;
/*@}*/
/* Temporaries for translating away float colors:
/**
* \name Temporaries for translating away float colors
*/
/*@{*/
struct gl_client_array UbyteColor;
struct gl_client_array UbyteSecondaryColor;
/*@}*/
/* Vertex buffers
/**
* \name Vertex buffers
*/
struct radeon_ioctl ioctl;
struct radeon_dma dma;
struct radeon_store store;
/*@{*/
struct radeon_ioctl ioctl; /**< \brief Retained vertex buffer */
struct radeon_dma dma; /**< \brief DMA information */
struct radeon_store store; /**< \brief Command buffer */
/*@}*/
/* Page flipping
/**
* \brief Page flipping
*/
GLuint doPageFlip;
/* Busy waiting
/**
* \name Busy waiting
*/
/*@{*/
GLuint do_usleeps;
GLuint do_irqs;
GLuint irqsEmitted;
GLuint do_irqs; /**< \brief Do IRQs */
GLuint irqsEmitted; /**< \brief IRQ transition counter.
* \sa radeonWaitForFrameCompletion(). */
drmRadeonIrqWait iw;
/*@}*/
/* Drawable, cliprect and scissor information
/**
* \name Drawable, cliprect and scissor information
*/
GLuint numClipRects; /* Cliprects for the draw buffer */
XF86DRIClipRectPtr pClipRects;
/*@{*/
GLuint numClipRects; /**< \brief Number of cliprects */
XF86DRIClipRectPtr pClipRects; /**< \brief cliprects for the draw buffer */
unsigned int lastStamp;
GLboolean lost_context;
radeonScreenPtr radeonScreen; /* Screen private DRI data */
RADEONSAREAPrivPtr sarea; /* Private SAREA data */
GLboolean lost_context; /**< \brief re-emit all state */
radeonScreenPtr radeonScreen; /**< \brief Screen private DRI data */
RADEONSAREAPrivPtr sarea; /**< \brief Private SAREA data */
/*@}*/
/* TCL stuff
/**
* \name TCL stuff
*/
/*@{*/
GLmatrix TexGenMatrix[RADEON_MAX_TEXTURE_UNITS];
GLboolean recheck_texgen[RADEON_MAX_TEXTURE_UNITS];
GLboolean TexGenNeedNormals[RADEON_MAX_TEXTURE_UNITS];
@@ -734,8 +690,10 @@ struct radeon_context {
GLuint TexGenEnabled;
GLmatrix tmpmat;
GLuint last_ReallyEnabled;
/*@}*/
/* VBI
/**
* \brief VBI
*/
GLuint vbl_seq;
@@ -745,31 +703,38 @@ struct radeon_context {
/* radeon_swtcl.c
*/
#if _HAVE_SWTNL
struct radeon_swtcl_info swtcl;
#endif
/* radeon_vtxfmt.c
*/
struct radeon_vbinfo vb;
/* struct radeon_vbinfo vb; */
/* Mirrors of some DRI state
/**
* \brief Mirrors of some DRI state
*/
struct radeon_dri_mirror dri;
/* Performance counters
*/
GLuint boxes; /* Draw performance boxes */
GLuint hardwareWentIdle;
GLuint c_clears;
GLuint c_drawWaits;
GLuint c_textureSwaps;
GLuint c_textureBytes;
GLuint c_vertexBuffers;
};
/**
* \brief Get the pointer to the Radeon context from the GL context.
*/
#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx))
/**
* \brief Pack color.
*
* \param cpp desired characters (bytes) per pixel. Shouble be either 2 or 4.
* \param r red color component.
* \param r green color component.
* \param b blue color component.
* \param a alpha color component.
*
* \return the packed color, or zero if \p cpp is not supported.
*/
static __inline GLuint radeonPackColor( GLuint cpp,
GLubyte r, GLubyte g,
GLubyte b, GLubyte a )
@@ -784,9 +749,8 @@ static __inline GLuint radeonPackColor( GLuint cpp,
}
}
#define RADEON_OLD_PACKETS 1
/* ================================================================
/******************************************************************
* Debugging:
*/
#define DO_DEBUG 1
@@ -810,5 +774,4 @@ extern int RADEON_DEBUG;
#define DEBUG_DMA 0x400
#define DEBUG_SANITY 0x800
#endif
#endif /* __RADEON_CONTEXT_H__ */

View File

@@ -1,43 +1,49 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.7 2002/09/16 18:05:19 eich Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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.
**************************************************************************/
/**
* \file radeon_ioctl.c
* \brief DRM interface functions.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.7 2002/09/16 18:05:19 eich Exp $ */
#include "glheader.h"
#include "imports.h"
#include "simple_list.h"
#include "radeon_context.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#include "radeon_macros.h" /* for INREG() */
#include <unistd.h> /* for usleep() */
#include <errno.h>
#if _HAVE_SWRAST
#include "swrast/swrast.h"
@@ -46,33 +52,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_sanity.h"
#endif
#include "radeon_context.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#include "radeon_tcl.h"
#include "radeon_macros.h" /* for INREG() */
#undef usleep
#include <unistd.h> /* for usleep() */
#include <errno.h>
#define RADEON_TIMEOUT 512
#define RADEON_IDLE_RETRY 16
static void do_usleep( int nr, const char *caller )
{
if (0) fprintf(stderr, "usleep %d in %s\n", nr, caller );
if (1) usleep( nr );
}
static void radeonWaitForIdle( radeonContextPtr rmesa );
/* =============================================================
* Kernel command buffer handling
/***************************************************************/
/** \name Kernel command buffer handling
*/
/*@{*/
/**
* \brief Print state atom information.
*
* For debugging purposes only.
*
* \param state state atom.
*/
static void print_state_atom( struct radeon_state_atom *state )
{
int i;
@@ -85,6 +82,16 @@ static void print_state_atom( struct radeon_state_atom *state )
}
/**
* \brief Emit a list of state atoms.
*
* \param rmesa Radeon context.
* \param list state atom list.
*
* For each active state in the list copies the associated commands into the
* command buffer, and moves the atom into the clean list.
*
*/
static void radeon_emit_state_list( radeonContextPtr rmesa,
struct radeon_state_atom *list )
{
@@ -105,6 +112,20 @@ static void radeon_emit_state_list( radeonContextPtr rmesa,
}
/**
* \brief Emit dirty state.
*
* \param rmesa Radeon context.
*
* Calls radeon_emit_state_list() with the radeon_hw_state::dirty list.
*
* If radeon_context::lost_context is set then all state is emited by moving
* everything in radeon_hw_state::dirty prior to the radeon_emit_state_list()
* call.
*
* \note For working around a Quake3 lock-up radeon_hw_state::zbs is always
* made \e dirty.
*/
void radeonEmitState( radeonContextPtr rmesa )
{
struct radeon_state_atom *state, *tmp;
@@ -123,19 +144,18 @@ void radeonEmitState( radeonContextPtr rmesa )
rmesa->lost_context = 0;
}
else if (1) {
/* This is a darstardly kludge to work around a lockup that I
* haven't otherwise figured out.
else {
/* Work around q3 lockup:
*/
move_to_tail(&(rmesa->hw.dirty), &(rmesa->hw.zbs) );
}
if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
foreach_s( state, tmp, &(rmesa->hw.dirty) ) {
if (state->is_tcl) {
move_to_head( &(rmesa->hw.clean), state );
}
}
foreach_s( state, tmp, &(rmesa->hw.dirty) ) {
if (state->is_tcl) {
move_to_head( &(rmesa->hw.clean), state );
}
}
}
radeon_emit_state_list( rmesa, &rmesa->hw.dirty );
@@ -143,8 +163,17 @@ void radeonEmitState( radeonContextPtr rmesa )
/* Fire a section of the retained (indexed_verts) buffer as a regular
* primtive.
/**
* \brief Fire a section of the retained buffer as a regular
* primitive.
*
* \param rmesa Radeon context.
* \param vertex_format vertex format.
* \param primitive primitive.
* \param vertex_nr number of vertices.
*
* Emits the dirty state and adds a new command to the command buffer for
* firing the vertices pointed by radeon_context::ioctl.
*/
extern void radeonEmitVbufPrim( radeonContextPtr rmesa,
GLuint vertex_format,
@@ -163,7 +192,6 @@ extern void radeonEmitVbufPrim( radeonContextPtr rmesa,
fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__,
rmesa->store.cmd_used/4);
#if RADEON_OLD_PACKETS
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 6 * sizeof(*cmd),
__FUNCTION__ );
cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
@@ -181,38 +209,15 @@ extern void radeonEmitVbufPrim( radeonContextPtr rmesa,
fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n",
__FUNCTION__,
cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i);
#else
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 4 * sizeof(*cmd),
__FUNCTION__ );
cmd[0].i = 0;
cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16);
cmd[2].i = vertex_format;
cmd[3].i = (primitive |
RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
RADEON_CP_VC_CNTL_MAOS_ENABLE |
RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
(vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n",
__FUNCTION__,
cmd[1].i, cmd[2].i, cmd[3].i);
#endif
}
#if _HAVE_FULL_GL
void radeonFlushElts( radeonContextPtr rmesa )
{
int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
int dwords;
#if RADEON_OLD_PACKETS
int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2;
#else
int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2;
#endif
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -225,13 +230,8 @@ void radeonFlushElts( radeonContextPtr rmesa )
rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
#if RADEON_OLD_PACKETS
cmd[1] |= (dwords - 3) << 16;
cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
#else
cmd[1] |= (dwords - 3) << 16;
cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
#endif
}
@@ -251,7 +251,6 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
radeonEmitState( rmesa );
#if RADEON_OLD_PACKETS
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa,
24 + min_nr*2,
__FUNCTION__ );
@@ -267,22 +266,6 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
retval = (GLushort *)(cmd+6);
#else
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa,
16 + min_nr*2,
__FUNCTION__ );
cmd[0].i = 0;
cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX;
cmd[2].i = vertex_format;
cmd[3].i = (primitive |
RADEON_CP_VC_CNTL_PRIM_WALK_IND |
RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
RADEON_CP_VC_CNTL_MAOS_ENABLE |
RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
retval = (GLushort *)(cmd+4);
#endif
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n",
@@ -297,92 +280,54 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
return retval;
}
void radeonEmitVertexAOS( radeonContextPtr rmesa,
GLuint vertex_size,
GLuint offset )
{
#if RADEON_OLD_PACKETS
rmesa->ioctl.vertex_size = vertex_size;
rmesa->ioctl.vertex_offset = offset;
#else
drmRadeonCmdHeader *cmd;
assert(rmesa->dri.drmMinor >= 3);
if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
__FUNCTION__, vertex_size, offset);
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 5 * sizeof(int),
__FUNCTION__ );
cmd[0].i = 0;
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16);
cmd[2].i = 1;
cmd[3].i = vertex_size | (vertex_size << 8);
cmd[4].i = offset;
#endif
}
void radeonEmitAOS( radeonContextPtr rmesa,
struct radeon_dma_region **component,
GLuint nr,
GLuint offset )
{
#if RADEON_OLD_PACKETS
assert( nr == 1 );
assert( component[0]->aos_size == component[0]->aos_stride );
rmesa->ioctl.vertex_size = component[0]->aos_size;
rmesa->ioctl.vertex_offset =
(component[0]->aos_start + offset * component[0]->aos_stride * 4);
#else
drmRadeonCmdHeader *cmd;
int sz = 3 + (nr/2 * 3) + (nr & 1) * 2;
int i;
int *tmp;
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(rmesa->dri.drmMinor >= 3);
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int),
__FUNCTION__ );
cmd[0].i = 0;
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
cmd[1].i = RADEON_CP_PACKET3_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 (RADEON_DEBUG & DEBUG_VERTS) {
fprintf(stderr, "%s:\n", __FUNCTION__);
for (i = 0 ; i < sz ; i++)
fprintf(stderr, " %d: %x\n", i, tmp[i]);
}
#endif
}
#endif
/**
* \brief Emit vertex array of structures.
*
* \param rmesa Radeon context.
* \param vertex_size size of the vertex buffer.
* \param offset offset of the vertex buffer.
*
* Updates radeon_context::ioctl with the given parameters.
*/
void radeonEmitVertexAOS( radeonContextPtr rmesa,
GLuint vertex_size,
GLuint offset )
{
rmesa->ioctl.vertex_size = vertex_size;
rmesa->ioctl.vertex_offset = offset;
}
/**
* \brief Flush the command buffer while holding the hardware lock.
*
* \param rmesa Radeon context.
* \param caller name of the calling function for debugging purposes.
*
* \return zero on success, non-zero otherwise.
*
* Issues a DRM_RADEON_CMDBUF command to the DRM passing a drmRadeonCmdBuffer
* structure as argument. The command buffer is reset before returning.
*
* If debugging is enabled, it prints several debug information and performs a
* sanity check before.
*
* \note Does not emit any commands to avoid recursion on radeonAllocCmdBuf().
*/
static int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
const char * caller )
{
@@ -427,15 +372,6 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
cmd.boxes = (drmClipRect *)rmesa->pClipRects;
}
if (0) {
int i;
for (i = 0 ; i < cmd.nbox ; i++)
fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n",
i, cmd.nbox,
cmd.boxes[i].x1, cmd.boxes[i].y1,
cmd.boxes[i].x2, cmd.boxes[i].y2);
}
ret = drmCommandWrite( rmesa->dri.fd,
DRM_RADEON_CMDBUF,
&cmd, sizeof(cmd) );
@@ -449,20 +385,22 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
}
/* Note: does not emit any commands to avoid recursion on
* radeonAllocCmdBuf.
/**
* \brief Flush the command buffer.
*
* \param rmesa Radeon context.
* \param caller name of the calling function for debugging purposes.
*
* Locks the hardware and calls radeonFlushCmdBufLocked(), aborting in case of
* failure.
*/
void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
{
int ret;
assert (rmesa->dri.drmMinor >= 3);
LOCK_HARDWARE( rmesa );
ret = radeonFlushCmdBufLocked( rmesa, caller );
UNLOCK_HARDWARE( rmesa );
if (ret) {
@@ -471,12 +409,27 @@ void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
}
}
/*@}*/
/* =============================================================
* Hardware vertex buffer handling
/***************************************************************/
/** \name Hardware vertex buffer handling
*/
/*@{*/
/**
* \brief Refill the current DMA region.
*
* \param rmesa Radeon context.
*
* Releases and eventually flushes the current DMA region (if the number of
* released buffers is greater than 4). Locks the hardware and requests a new
* DMA buffer as the new current DMA region.
*
* In case of failure in the first try to get a new DMA buffer, flushes any
* previously released buffers, waits for engine is idle and tries once more,
* aborting if it fails.
*/
void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa )
{
struct radeon_dma_buffer *dmabuf;
@@ -548,10 +501,18 @@ void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa )
rmesa->dma.current.end = dmabuf->buf->total;
rmesa->dma.current.start = 0;
rmesa->dma.current.ptr = 0;
rmesa->c_vertexBuffers++;
}
/**
* \brief Release DMA region.
*
* \param rmesa Radeon context.
* \param region ragion to be released.
* \param caller caller's name for debugging purposes.
*
* Decreases the region reference count, and if it reaches zero sends the
* RADEON_CMD_DMA_DISCARD with its buffer index.
*/
void radeonReleaseDmaRegion( radeonContextPtr rmesa,
struct radeon_dma_region *region,
const char *caller )
@@ -584,8 +545,16 @@ void radeonReleaseDmaRegion( radeonContextPtr rmesa,
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)
/**
* \brief Allocates a new region from radeon_dma::current.
*
* \param rmesa Radeon context.
* \param region region will received the allocated region.
* \param bytes size.
* \param alignment alignment.
*
* If there isn't enough space in the current DMA buffer, grab a new buffer
* (and discard what was left of it).
*/
void radeonAllocDmaRegion( radeonContextPtr rmesa,
struct radeon_dma_region *region,
@@ -623,6 +592,11 @@ void radeonAllocDmaRegion( radeonContextPtr rmesa,
radeonRefillCurrentDmaRegion( rmesa );
}
/**
* \brief Allocate a DMA region for vertices.
*
* Calls radeonAllocDmaRegion() with \p bytes = \p vertsize * \p numverts.
*/
void radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
struct radeon_dma_region *region,
int numverts,
@@ -632,10 +606,24 @@ void radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
radeonAllocDmaRegion( rmesa, region, vertsize * numverts, alignment );
}
/* ================================================================
* SwapBuffers with client-side throttling
*/
/*@}*/
/******************************************************************/
/** \name SwapBuffers with client-side throttling
*/
/*@{*/
/**
* \brief Get last frame.
*
* \param rmesa Radeon context.
*
* \return last frame number.
*
* Gets the last frame number via the DRM_RADEON_GETPARAM command in recent
* DRMs, or via the RADEON_LAST_FRAME_REG register.
*/
static GLuint radeonGetLastFrame (radeonContextPtr rmesa)
{
unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
@@ -664,6 +652,14 @@ static GLuint radeonGetLastFrame (radeonContextPtr rmesa)
return frame;
}
/**
* \brief Emit an IRQ while holding the hardware lock.
*
* \param rmesa Radeon context.
*
* Sends the DRM_RADEON_IRQ_EMIT command, aborting on failure.
*/
static void radeonEmitIrqLocked( radeonContextPtr rmesa )
{
drmRadeonIrqEmit ie;
@@ -679,6 +675,13 @@ static void radeonEmitIrqLocked( radeonContextPtr rmesa )
}
/**
* \brief Wait on IRQ.
*
* \param rmesa Radeon context.
*
* Sends the DRM_RADEON_IRQ_WAIT command, aborting on failure.
*/
static void radeonWaitIrq( radeonContextPtr rmesa )
{
int ret;
@@ -695,6 +698,54 @@ static void radeonWaitIrq( radeonContextPtr rmesa )
}
/**
* \brief Wait for frame completion.
*
* \param rmesa Radeon context.
*
* Waits until the number of processed frames reaches RADEONSAREAPriv::last_frame in the
* SAREA.
*
* The idea is to only emit IRQ's if the graphics card is the bottleneck -- ie
* only do it if we find that the previous frame hasn't completed. When the
* card is the bottlneck one'd like to do something like:
*
*\code
* render frame 0
* swap buffers
* emit IRQ 0
* render frame 1
* wait on IRQ 0 (i.e. wait for last frame to complete)
* swap buffers
* emit IRQ 1,
* ...
* \endcode
*
* But, if there's no need to wait for hardware (i.e., the application/driver
* is bottleneck), then one'd prefer:
*
* \code
* render frame 0
* swapbuffers
* render frame 1
* swapbuffers
* ...
* \endcode
*
* without any doing any IRQ or waiting.
*
* The radeon_context::irqsEmitted determines transition between these modes.
* It is set to 10 if it ever has to wait, and decremented otherwise. If it
* finds it has to wait, checks radeon_context::irqsEmitted to determine if
* there is an IRQ pending that we can wait on -- otherwise do busy wait.
* Finally, after the waiting/not-waiting is over, checks
* radeon_context::irqsEmitted, if non-zero, emits an IRQ.
*
* If IRQ's aren't supported for whatever reason, it always busy waits.
*
* This function assumes that the hardware was locked prior to the call but
* all waits are internally done with the hardware unlocked.
*/
static void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
{
RADEONSAREAPrivPtr sarea = rmesa->sarea;
@@ -722,13 +773,20 @@ static void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
while (radeonGetLastFrame (rmesa) < sarea->last_frame) {
UNLOCK_HARDWARE( rmesa );
if (rmesa->do_usleeps)
do_usleep(1, __FUNCTION__);
usleep(1);
LOCK_HARDWARE( rmesa );
}
}
}
/* Copy the back color buffer to the front color buffer.
/**
* \brief Copy the back color buffer to the front color buffer.
*
* \param dPriv DRI specific drawable data.
*
* Fires the existing vertices and waits for frame completion and vertical
* retrace. Sends the DRM_RADEON_SWAP command for each set of existing
* cliprects.
*/
void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
{
@@ -746,10 +804,8 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
}
RADEON_FIREVERTICES( rmesa );
LOCK_HARDWARE( rmesa );
/* Throttle the frame rate -- only allow one pending swap buffers
* request at a time.
*/
@@ -782,6 +838,18 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
UNLOCK_HARDWARE( rmesa );
}
/**
* \brief Do page flipping.
*
* \param dPriv DRI drawable speficic data.
*
* Fires the existing vertices and waits for frame completion and vertical
* retrace. Sends the DRM_RADEON_FLIP command and updates the value of
* radeon_colorbuffer_state::drawOffset and
* radeon_colorbuffer_state::drawPitch to point to the front or back color
* buffer.
*/
void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
{
radeonContextPtr rmesa;
@@ -841,12 +909,39 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
}
/*@}*/
/* ================================================================
* Buffer clear
/******************************************************************/
/* \name Buffer clear
*/
/*@{*/
/**
* \brief Maximum number of clears to buffer.
*/
#define RADEON_MAX_CLEARS 256
/**
* \brief Clear buffers.
*
* \param ctx GL context.
* \param mask buffer clear mask.
* \param all whether to clear them all or just a rectangle.
* \param cx clearing rectangle abcissa.
* \param cy clearing rectangle ordinate.
* \param cw clearing rectangle width.
* \param ch clearing rectangle height.
*
* First emits the current state, fires the vertices and calculate the clearing
* flags to pass to the clear ioctl later.
*
* Locks the hardware and throttles the number of clear ioctl's done, allowing
* up to #RADEON_MAX_CLEARS. For each set of cliprects, intersects them with
* the clearing rectangle (if not clearing all) and uploads them to the SAREA,
* setups a drmRadeonClearT structure sends it to the DRM_RADEON_CLEAR
* command.
*/
static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
@@ -940,7 +1035,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
if ( rmesa->do_usleeps ) {
UNLOCK_HARDWARE( rmesa );
do_usleep(1, __FUNCTION__);
usleep(1);
LOCK_HARDWARE( rmesa );
}
}
@@ -1015,26 +1110,24 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
}
/**
* \brief Wait for engine idle while holding the hardware lock.
*
* \param rmesa Radeon context.
*
* Sends the DRM_RADEON_CP_IDLE command until the engine is reported as idle or
* a timeout occurs.
*/
void radeonWaitForIdleLocked( radeonContextPtr rmesa )
{
int fd = rmesa->dri.fd;
int to = 0;
int ret, i = 0;
rmesa->c_drawWaits++;
do {
do {
ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE);
} while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY );
if (ret && ret != -EBUSY) {
/*
* JO - I'm reluctant to print this message while holding the lock
*
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"%s: CP idle %d\n", __FUNCTION__, ret);
*/
}
} while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) );
if ( ret < 0 ) {
@@ -1045,6 +1138,13 @@ void radeonWaitForIdleLocked( radeonContextPtr rmesa )
}
/**
* \brief Wait for engine idle.
*
* \param rmesa Radeon context.
*
* Locks the hardware and calls radeonWaitForIdleLocked().
*/
static void radeonWaitForIdle( radeonContextPtr rmesa )
{
LOCK_HARDWARE(rmesa);
@@ -1053,6 +1153,13 @@ static void radeonWaitForIdle( radeonContextPtr rmesa )
}
/**
* \brief Wait for vertical retrace.
*
* \param rmesa Radeon context.
*
* Disabled - no-op.
*/
void radeonWaitForVBlank( radeonContextPtr rmesa )
{
#if 0
@@ -1090,6 +1197,14 @@ void radeonWaitForVBlank( radeonContextPtr rmesa )
#endif
}
/**
* \brief Flush all dirty state and pending buffers.
*
* \param ctx GL context.
*
* Calls radeonEmitState() with the dirty state list if not empty, and
* radeonFlushCmdBuf() if the command buffer has been used.
*/
void radeonFlush( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
@@ -1109,8 +1224,14 @@ void radeonFlush( GLcontext *ctx )
}
}
/* Make sure all commands have been sent to the hardware and have
/**
* \brief Make sure all commands have been sent to the hardware and have
* completed processing.
*
* \param ctx GL context.
*
* If IRQs are enabled then emits and waits on the IRQ, otherwise waits for
* engine idle.
*/
void radeonFinish( GLcontext *ctx )
{
@@ -1128,6 +1249,13 @@ void radeonFinish( GLcontext *ctx )
}
/**
* \brief Setup the GL context callbacks.
*
* \param ctx GL context.
*
* \sa Called by radeonCreateContext().
*/
void radeonInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Clear = radeonClear;
@@ -1135,3 +1263,4 @@ void radeonInitIoctlFuncs( GLcontext *ctx )
ctx->Driver.Flush = radeonFlush;
}
/*@}*/

View File

@@ -1,44 +1,42 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.4 2002/09/16 18:05:20 eich Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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.
**************************************************************************/
/**
* \file radeon_ioctl.h
* \brief DRM interface functions.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.4 2002/09/16 18:05:20 eich Exp $ */
#ifndef __RADEON_IOCTL_H__
#define __RADEON_IOCTL_H__
#ifdef GLX_DIRECT_RENDERING
#include "simple_list.h"
#include "radeon_lock.h"
@@ -106,7 +104,10 @@ extern void radeonCompatEmitPrimitive( radeonContextPtr rmesa,
* Helper macros:
*/
/* Close off the last primitive, if it exists.
/**
* \brief Close off the last primitive, if it exists.
*
* \param rmesa Radeon context.
*/
#define RADEON_NEWPRIM( rmesa ) \
do { \
@@ -114,8 +115,12 @@ do { \
rmesa->dma.flush( rmesa ); \
} while (0)
/* Can accomodate several state changes and primitive changes without
/**
* Can accomodate several state changes and primitive changes without
* actually firing the buffer.
*
* \param rmesa Radeon context.
* \param ATOM state atom variable name.
*/
#define RADEON_STATECHANGE( rmesa, ATOM ) \
do { \
@@ -145,7 +150,10 @@ static __inline int RADEON_DB_STATECHANGE(
}
/* Fire the buffered vertices no matter what.
/**
* \brief Fire the buffered vertices no matter what.
*
* \param rmesa Radeon context.
*/
#define RADEON_FIREVERTICES( rmesa ) \
do { \
@@ -154,7 +162,15 @@ do { \
} \
} while (0)
/* Alloc space in the command buffer
/**
* \brief Allocate space in the command buffer.
*
* \param rmesa Radeon context.
* \param bytes number of bytes to allocate.
* \param where Not used.
*
* If there isn't enough space available flush the command buffer, otherwise
* just advance the buffer head the requested ammount.
*/
static __inline char *radeonAllocCmdBuf( radeonContextPtr rmesa,
int bytes, const char *where )
@@ -172,7 +188,4 @@ static __inline char *radeonAllocCmdBuf( radeonContextPtr rmesa,
}
#endif
#endif /* __RADEON_IOCTL_H__ */

View File

@@ -0,0 +1,681 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ */
/*
* Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
*
* 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
* VA LINUX SYSTEMS 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:
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "imports.h"
#include "api_arrayelt.h"
#include "mmath.h"
#include "enums.h"
#include "colormac.h"
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_vtxfmt.h"
/* =============================================================
* Materials
*/
/* Update on colormaterial, material emmissive/ambient,
* lightmodel.globalambient
*/
void update_global_ambient( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
float *fcmd = (float *)RADEON_DB_STATE( glt );
/* Need to do more if both emmissive & ambient are PREMULT:
*/
if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
(3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
{
COPY_3V( &fcmd[GLT_RED],
ctx->Light.Material[0].Emission);
ACC_SCALE_3V( &fcmd[GLT_RED],
ctx->Light.Model.Ambient,
ctx->Light.Material[0].Ambient);
}
else
{
COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
}
RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
}
/* Update on change to
* - light[p].colors
* - light[p].enabled
* - material,
* - colormaterial enabled
* - colormaterial bitmask
*/
void update_light_colors( GLcontext *ctx, GLuint p )
{
struct gl_light *l = &ctx->Light.Light[p];
/* fprintf(stderr, "%s\n", __FUNCTION__); */
if (l->Enabled) {
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
GLuint bitmask = ctx->Light.ColorMaterialBitmask;
struct gl_material *mat = &ctx->Light.Material[0];
COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
if (!ctx->Light.ColorMaterialEnabled)
bitmask = 0;
if ((bitmask & FRONT_AMBIENT_BIT) == 0)
SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient );
if ((bitmask & FRONT_DIFFUSE_BIT) == 0)
SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse );
if ((bitmask & FRONT_SPECULAR_BIT) == 0)
SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular );
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
}
}
/* Also fallback for asym colormaterial mode in twoside lighting...
*/
void check_twoside_fallback( GLcontext *ctx )
{
GLboolean fallback = GL_FALSE;
if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
if (memcmp( &ctx->Light.Material[0],
&ctx->Light.Material[1],
sizeof(struct gl_material)) != 0)
fallback = GL_TRUE;
else if (ctx->Light.ColorMaterialEnabled &&
(ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
fallback = GL_TRUE;
}
TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
}
void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
{
if (ctx->Light.ColorMaterialEnabled) {
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
GLuint mask = ctx->Light.ColorMaterialBitmask;
/* Default to PREMULT:
*/
light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
(3 << RADEON_AMBIENT_SOURCE_SHIFT) |
(3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
(3 << RADEON_SPECULAR_SOURCE_SHIFT));
if (mask & FRONT_EMISSION_BIT) {
light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_EMISSIVE_SOURCE_SHIFT);
}
if (mask & FRONT_AMBIENT_BIT) {
light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_AMBIENT_SOURCE_SHIFT);
}
if (mask & FRONT_DIFFUSE_BIT) {
light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_DIFFUSE_SOURCE_SHIFT);
}
if (mask & FRONT_SPECULAR_BIT) {
light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_SPECULAR_SOURCE_SHIFT);
}
if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
GLuint p;
RADEON_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl;
for (p = 0 ; p < MAX_LIGHTS; p++)
update_light_colors( ctx, p );
update_global_ambient( ctx );
}
}
check_twoside_fallback( ctx );
}
void radeonUpdateMaterial( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
GLuint p;
GLuint mask = ~0;
if (ctx->Light.ColorMaterialEnabled)
mask &= ~ctx->Light.ColorMaterialBitmask;
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
if (mask & FRONT_EMISSION_BIT) {
fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0];
fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1];
fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2];
fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3];
}
if (mask & FRONT_AMBIENT_BIT) {
fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0];
fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1];
fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2];
fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3];
}
if (mask & FRONT_DIFFUSE_BIT) {
fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0];
fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1];
fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2];
fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3];
}
if (mask & FRONT_SPECULAR_BIT) {
fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0];
fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1];
fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2];
fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3];
}
if (mask & FRONT_SHININESS_BIT) {
fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess;
}
if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) {
for (p = 0 ; p < MAX_LIGHTS; p++)
update_light_colors( ctx, p );
check_twoside_fallback( ctx );
update_global_ambient( ctx );
}
else if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_STATE))
fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__);
}
/* _NEW_LIGHT
* _NEW_MODELVIEW
* _MESA_NEW_NEED_EYE_COORDS
*
* Uses derived state from mesa:
* _VP_inf_norm
* _h_inf_norm
* _Position
* _NormDirection
* _ModelViewInvScale
* _NeedEyeCoords
* _EyeZDir
*
* which are calculated in light.c and are correct for the current
* lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
* and _MESA_NEW_NEED_EYE_COORDS.
*/
void radeonUpdateLighting( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
/* Have to check these, or have an automatic shortcircuit mechanism
* to remove noop statechanges. (Or just do a better job on the
* front end).
*/
{
GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
if (ctx->_NeedEyeCoords)
tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
else
tmp |= RADEON_LIGHT_IN_MODELSPACE;
/* Leave this test disabled: (unexplained q3 lockup) (even with
new packets)
*/
if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
{
RADEON_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
}
}
{
GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
fcmd[EYE_X] = ctx->_EyeZDir[0];
fcmd[EYE_Y] = ctx->_EyeZDir[1];
fcmd[EYE_Z] = - ctx->_EyeZDir[2];
fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
}
/* RADEON_STATECHANGE( rmesa, glt ); */
if (ctx->Light.Enabled) {
GLint p;
for (p = 0 ; p < MAX_LIGHTS; p++) {
if (ctx->Light.Light[p].Enabled) {
struct gl_light *l = &ctx->Light.Light[p];
GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
if (l->EyePosition[3] == 0.0) {
COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
fcmd[LIT_POSITION_W] = 0;
fcmd[LIT_DIRECTION_W] = 0;
} else {
COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];
fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];
fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];
fcmd[LIT_DIRECTION_W] = 0;
}
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
}
}
}
}
void radeonLightfv( GLcontext *ctx, GLenum light,
GLenum pname, const GLfloat *params )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLint p = light - GL_LIGHT0;
struct gl_light *l = &ctx->Light.Light[p];
GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
switch (pname) {
case GL_AMBIENT:
case GL_DIFFUSE:
case GL_SPECULAR:
update_light_colors( ctx, p );
break;
case GL_SPOT_DIRECTION:
/* picked up in update_light */
break;
case GL_POSITION: {
/* positions picked up in update_light, but can do flag here */
GLuint flag = (p&1)? RADEON_LIGHT_1_IS_LOCAL : RADEON_LIGHT_0_IS_LOCAL;
GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
RADEON_STATECHANGE(rmesa, tcl);
if (l->EyePosition[3] != 0.0F)
rmesa->hw.tcl.cmd[idx] |= flag;
else
rmesa->hw.tcl.cmd[idx] &= ~flag;
break;
}
case GL_SPOT_EXPONENT:
RADEON_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_SPOT_EXPONENT] = params[0];
break;
case GL_SPOT_CUTOFF: {
GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
RADEON_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
RADEON_STATECHANGE(rmesa, tcl);
if (l->SpotCutoff != 180.0F)
rmesa->hw.tcl.cmd[idx] |= flag;
else
rmesa->hw.tcl.cmd[idx] &= ~flag;
break;
}
case GL_CONSTANT_ATTENUATION:
RADEON_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_ATTEN_CONST] = params[0];
break;
case GL_LINEAR_ATTENUATION:
RADEON_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_ATTEN_LINEAR] = params[0];
break;
case GL_QUADRATIC_ATTENUATION:
RADEON_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_ATTEN_QUADRATIC] = params[0];
break;
default:
return;
}
}
void radeonLightModelfv( GLcontext *ctx, GLenum pname,
const GLfloat *param )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
switch (pname) {
case GL_LIGHT_MODEL_AMBIENT:
update_global_ambient( ctx );
break;
case GL_LIGHT_MODEL_LOCAL_VIEWER:
RADEON_STATECHANGE( rmesa, tcl );
if (ctx->Light.Model.LocalViewer)
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
else
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
break;
case GL_LIGHT_MODEL_TWO_SIDE:
RADEON_STATECHANGE( rmesa, tcl );
if (ctx->Light.Model.TwoSide)
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
else
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
check_twoside_fallback( ctx );
#if _HAVE_SWTNL
if (rmesa->TclFallback) {
radeonChooseRenderState( ctx );
radeonChooseVertexState( ctx );
}
#endif
break;
case GL_LIGHT_MODEL_COLOR_CONTROL:
radeonUpdateSpecular(ctx);
RADEON_STATECHANGE( rmesa, tcl );
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
~RADEON_DIFFUSE_SPECULAR_COMBINE;
else
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=
RADEON_DIFFUSE_SPECULAR_COMBINE;
break;
default:
break;
}
}
/* =============================================================
* Fog
*/
static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
union { int i; float f; } c, d;
GLchan col[4];
c.i = rmesa->hw.fog.cmd[FOG_C];
d.i = rmesa->hw.fog.cmd[FOG_D];
switch (pname) {
case GL_FOG_MODE:
if (!ctx->Fog.Enabled)
return;
RADEON_STATECHANGE(rmesa, tcl);
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
switch (ctx->Fog.Mode) {
case GL_LINEAR:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
if (ctx->Fog.Start == ctx->Fog.End) {
c.f = 1.0F;
d.f = 1.0F;
}
else {
c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
}
break;
case GL_EXP:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
c.f = 0.0;
d.f = ctx->Fog.Density;
break;
case GL_EXP2:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
c.f = 0.0;
d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
default:
return;
}
break;
case GL_FOG_DENSITY:
switch (ctx->Fog.Mode) {
case GL_EXP:
c.f = 0.0;
d.f = ctx->Fog.Density;
break;
case GL_EXP2:
c.f = 0.0;
d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
default:
break;
}
break;
case GL_FOG_START:
case GL_FOG_END:
if (ctx->Fog.Mode == GL_LINEAR) {
if (ctx->Fog.Start == ctx->Fog.End) {
c.f = 1.0F;
d.f = 1.0F;
} else {
c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
}
}
break;
case GL_FOG_COLOR:
RADEON_STATECHANGE( rmesa, ctx );
UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] =
radeonPackColor( 4, col[0], col[1], col[2], 0 );
break;
case GL_FOG_COORDINATE_SOURCE_EXT:
/* What to do?
*/
break;
default:
return;
}
if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
RADEON_STATECHANGE( rmesa, fog );
rmesa->hw.fog.cmd[FOG_C] = c.i;
rmesa->hw.fog.cmd[FOG_D] = d.i;
}
}
/* Examine lighting and texture state to determine if separate specular
* should be enabled.
*/
void radeonUpdateSpecular( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
if ( ctx->_TriangleCaps & DD_SEPARATE_SPECULAR ) {
p |= RADEON_SPECULAR_ENABLE;
} else {
p &= ~RADEON_SPECULAR_ENABLE;
}
if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
RADEON_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
}
/* Bizzare: have to leave lighting enabled to get fog.
*/
RADEON_STATECHANGE( rmesa, tcl );
if ((ctx->Light.Enabled &&
ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
}
else if (ctx->Fog.Enabled) {
if (ctx->Light.Enabled) {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
} else {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
}
}
else if (ctx->Light.Enabled) {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
} else if (ctx->Fog.ColorSumEnabled ) {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
} else {
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
}
#if _HAVE_SWTNL
/* Update vertex/render formats
*/
if (rmesa->TclFallback) {
radeonChooseRenderState( ctx );
radeonChooseVertexState( ctx );
}
#endif
}
static void radeonLightingSpaceChange( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLboolean tmp;
RADEON_STATECHANGE( rmesa, tcl );
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords);
if (ctx->_NeedEyeCoords)
tmp = ctx->Transform.RescaleNormals;
else
tmp = !ctx->Transform.RescaleNormals;
if ( tmp ) {
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
} else {
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
}
}
void radeonInitLightStateFuncs( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
int i;
ctx->Driver.LightModelfv = radeonLightModelfv;
ctx->Driver.Lightfv = radeonLightfv;
ctx->Driver.Fogfv = radeonFogfv;
ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
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 );
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 );
}

View File

@@ -37,15 +37,67 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "glheader.h"
#include "radeon_context.h"
#include "radeon_lock.h"
#include "radeon_tex.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#if _HAVE_FULL_GL
#include "radeon_tex.h"
#else
#include "radeon_subset.h"
#endif
#if DEBUG_LOCKING
char *prevLockFile = NULL;
int prevLockLine = 0;
#endif
void radeonUpdateViewportOffset( 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;
GLfloat tx = v[MAT_TX] + xoffset;
GLfloat ty = (- v[MAT_TY]) + yoffset;
if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx ||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty )
{
/* Note: this should also modify whatever data the context reset
* code uses...
*/
rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
/* update polygon stipple x/y screen offset */
{
GLuint stx, sty;
GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
RADEON_STIPPLE_Y_OFFSET_MASK);
/* add magic offsets, then invert */
stx = 31 - ((rmesa->dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK);
sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1)
& RADEON_STIPPLE_COORD_MASK);
m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
(sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
RADEON_STATECHANGE( rmesa, msc );
rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
}
}
}
radeonUpdateScissor( ctx );
}
/* Turn on/off page flipping according to the flags in the sarea:
*/
static void
@@ -57,7 +109,6 @@ 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);
@@ -70,10 +121,6 @@ radeonUpdatePageFlipping( radeonContextPtr rmesa )
rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
}
fprintf(stderr, "%s: pfCurrentPage %d COLOROFFSET %x\n", __FUNCTION__,
rmesa->sarea->pfCurrentPage,
rmesa->state.color.drawOffset);
RADEON_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;

View File

@@ -37,8 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_LOCK_H__
#define __RADEON_LOCK_H__
#ifdef GLX_DIRECT_RENDERING
extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags );
/* Turn DEBUG_LOCKING on to find locking conflicts.
@@ -109,5 +107,4 @@ extern int prevLockLine;
DEBUG_RESET(); \
} while (0)
#endif
#endif /* __RADEON_LOCK_H__ */

View File

@@ -1,14 +1,4 @@
#if _HAVE_SWTNL
/* If using new packets, can choose either verts or arrays.
* Otherwise, must use verts.
*/
#include "radeon_context.h"
#define RADEON_MAOS_VERTS 1
#if (RADEON_MAOS_VERTS) || (RADEON_OLD_PACKETS)
#include "radeon_maos_verts.c"
#else
#include "radeon_maos_arrays.c"
#endif
#endif

View File

@@ -36,12 +36,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_MAOS_H__
#define __RADEON_MAOS_H__
#ifdef GLX_DIRECT_RENDERING
#include "radeon_context.h"
extern void radeonEmitArrays( GLcontext *ctx, GLuint inputs );
extern void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs );
#endif
#endif

View File

@@ -51,6 +51,54 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_swtcl.h"
#include "radeon_maos.h"
void radeonEmitAOS( radeonContextPtr rmesa,
struct radeon_dma_region **component,
GLuint nr,
GLuint offset )
{
drmRadeonCmdHeader *cmd;
int sz = 3 + (nr/2 * 3) + (nr & 1) * 2;
int i;
int *tmp;
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(rmesa->dri.drmMinor >= 3);
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int),
__FUNCTION__ );
cmd[0].i = 0;
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
cmd[1].i = RADEON_CP_PACKET3_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 (RADEON_DEBUG & DEBUG_VERTS) {
fprintf(stderr, "%s:\n", __FUNCTION__);
for (i = 0 ; i < sz ; i++)
fprintf(stderr, " %d: %x\n", i, tmp[i]);
}
}
/* Usage:
* - from radeon_tcl_render
* - call radeonEmitArrays to ensure uptodate arrays in dma

View File

@@ -1,39 +1,40 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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>
*
/**
* \file radeon_screen.c
* \brief Screen initialization functions.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */
#include "glheader.h"
#include "imports.h"
@@ -60,7 +61,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
/* Create the device specific screen private data struct.
/**
* \brief Create the device specific screen data structure.
*
* \param sPriv DRI specific screen data.
*
* \return pointer to the device specific screen private data.
*
* Checks the version compatability of the DRI extension, the DDX driver and
* the DRM driver.
*
* Disables the TCL for DRM versions less than 1.3.x, or if the RADEON_COMPAT
* environment variable is set. Requests the AGP buffer offset to the DRM for
* versions >=1.3.x, and the IRQ number for >=1.6.x.
*
* Maps the MMIO region, the status region, the vertex buffers and (if
* available) the AGP texture region.
*
* Fills in the device screen private data with the DRI screen private data
* supplied.
*/
radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
{
@@ -246,7 +265,13 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
return radeonScreen;
}
/* Destroy the device specific screen private data struct.
/**
* \brief Destroy the device specific screen data.
*
* \param sPriv DRI specific screen data.
*
* Unmaps all previously mapped regions and deallocates the device specific
* private data.
*/
void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
{

View File

@@ -1,44 +1,43 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.3 2002/02/22 21:45:01 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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.
**************************************************************************/
/**
* \file radeon_screen.h
* \brief Screen initialization functions.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.3 2002/02/22 21:45:01 dawes Exp $ */
#ifndef __RADEON_SCREEN_H__
#define __RADEON_SCREEN_H__
#ifdef GLX_DIRECT_RENDERING
/*
* IMPORTS: these headers contain all the DRI, X and kernel-related
* definitions that we need.
@@ -50,22 +49,28 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_sarea.h"
/**
* \brief DRM region information.
*/
typedef struct {
drmHandle handle; /* Handle to the DRM region */
drmSize size; /* Size of the DRM region */
drmAddress map; /* Mapping of the DRM region */
drmHandle handle; /**< \brief Handle to the DRM region */
drmSize size; /**< \brief Size of the DRM region */
drmAddress map; /**< \brief Mapping of the DRM region */
} radeonRegionRec, *radeonRegionPtr;
/* chipset features */
#define RADEON_CHIPSET_TCL (1 << 0)
/**
* \brief Device specific screen data.
*/
typedef struct {
int chipset;
int cpp;
int IsPCI; /* Current card is a PCI card */
int AGPMode;
unsigned int irq; /* IRQ number (0 means none) */
int IsPCI; /**< \brief Current card is a PCI card */
int AGPMode; /**< \brief AGP mode */
unsigned int irq; /**< \brief IRQ number (0 means none) */
unsigned int frontOffset;
unsigned int frontPitch;
@@ -75,11 +80,15 @@ typedef struct {
unsigned int depthOffset;
unsigned int depthPitch;
/* Shared texture data */
/**
* \name Shared texture data
*/
/*@{*/
int numTexHeaps;
int texOffset[RADEON_NR_TEX_HEAPS];
int texSize[RADEON_NR_TEX_HEAPS];
int logTexGranularity[RADEON_NR_TEX_HEAPS];
/*@}*/
radeonRegionRec mmio;
radeonRegionRec status;
@@ -91,11 +100,10 @@ typedef struct {
__DRIscreenPrivate *driScreen;
unsigned int sarea_priv_offset;
unsigned int agp_buffer_offset; /* offset in card memory space */
unsigned int agp_buffer_offset; /**< offset in card memory space */
} radeonScreenRec, *radeonScreenPtr;
extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv );
extern void radeonDestroyScreen( __DRIscreenPrivate *sPriv );
#endif
#endif /* __RADEON_SCREEN_H__ */

View File

@@ -411,6 +411,32 @@ void radeonInitSpanFuncs( GLcontext *ctx )
swdd->SpanRenderStart = radeonSpanRenderStart;
swdd->SpanRenderFinish = radeonSpanRenderFinish;
/* 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; */
/* Swrast hooks for imaging extensions:
*/
ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
}
void radeonCreateSwrastContext( GLcontext *ctx )
{
_swrast_CreateContext( ctx );
/* Configure swrast to match hardware characteristics:
*/
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
}
#endif

View File

@@ -37,9 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_SPAN_H__
#define __RADEON_SPAN_H__
#ifdef GLX_DIRECT_RENDERING
extern void radeonInitSpanFuncs( GLcontext *ctx );
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,45 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.3 2002/09/16 18:05:20 eich Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
VA Linux Systems Inc., Fremont, California.
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, 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>
/**
* \file radeon_state.h
* \brief State management.
*
* \authors Kevin E. Martin <martin@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
*/
/*
*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* VA Linux Systems Inc., Fremont, California.
*
* 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, 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.
*
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.3 2002/09/16 18:05:20 eich Exp $ */
#ifndef __RADEON_STATE_H__
#define __RADEON_STATE_H__
#ifdef GLX_DIRECT_RENDERING
#include "radeon_context.h"
extern void radeonInitState( radeonContextPtr rmesa );
@@ -58,6 +59,7 @@ extern void radeonPrintDirty( radeonContextPtr rmesa,
extern void radeonFallback( 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 ); \
@@ -72,5 +74,14 @@ extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define TEXMAT_1 4
#define TEXMAT_2 5
#endif
extern void radeonUpdateSpecular( GLcontext *ctx );
extern void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq );
extern void radeonUploadMatrixTranspose( radeonContextPtr rmesa, GLfloat *src,
int idx );
extern void radeonUploadMatrix( radeonContextPtr rmesa, GLfloat *src, int idx );
extern void radeonUpdateScissor( GLcontext *ctx );
#endif

View File

@@ -1,4 +1,11 @@
/* $XFree86$ */
/**
* \file radeon_state_init.c
* \brief State initialization.
*
* \author Gareth Hughes <gareth@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
*
@@ -22,12 +29,10 @@
* 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:
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86$ */
#include "glheader.h"
#include "imports.h"
#include "mmath.h"
@@ -46,14 +51,11 @@
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_vtxfmt.h"
/* =============================================================
* State initialization
/**
* \brief Print the dirty context state info.
*/
void radeonPrintDirty( radeonContextPtr rmesa, const char *msg )
{
struct radeon_state_atom *l;
@@ -68,6 +70,14 @@ void radeonPrintDirty( radeonContextPtr rmesa, const char *msg )
fprintf(stderr, "\n");
}
/**
* \brief Constructs a register packet command.
*
* \param register ID.
* \return integer equivalent of the command.
*
* \sa drmRadeonCmdHeader and drmRadeonCmdType::RADEON_CMD_PACKET.
*/
static int cmdpkt( int id )
{
drmRadeonCmdHeader h;
@@ -77,6 +87,17 @@ static int cmdpkt( int id )
return h.i;
}
/**
* \brief Constructs a vector data command
*
* \param offset data offset.
* \param stride array stride.
* \param count vector count.
*
* \return integer equivalent of the command.
*
* \sa drmRadeonCmdHeader and drmRadeonCmdType::RADEON_CMD_VECTORS.
*/
static int cmdvec( int offset, int stride, int count )
{
drmRadeonCmdHeader h;
@@ -88,6 +109,17 @@ static int cmdvec( int offset, int stride, int count )
return h.i;
}
/**
* \brief Constructs a scalar data command.
*
* \param offset data offset.
* \param stride array stride.
* \param count scalar count.
*
* \return integer equivalent of the command.
*
* \sa drmRadeonCmdHeader and drmRadeonCmdType::RADEON_CMD_SCALARS.
*/
static int cmdscl( int offset, int stride, int count )
{
drmRadeonCmdHeader h;
@@ -99,12 +131,34 @@ static int cmdscl( int offset, int stride, int count )
return h.i;
}
/**
* \brief Utility macro for state checking functions definition.
*
* It is used for a shorthand definiton of the state checking functions. Four
* functions are defined:
* - one which always returns GL_TRUE for state which is always active;
* - two which determine whether the respective texture unit is enabled;
* - one which determines whether fog is enabled.
*/
#define CHECK( NM, FLAG ) \
static GLboolean check_##NM( GLcontext *ctx ) \
{ \
return FLAG; \
}
/**
* \brief Utility macro for TCL state checking functions definition.
*
* Same as for #CHECK but the functions defined by this macro always check
* whether TCL is enabled. Several functions are defined:
* - one which simply returns whether TCL is enabled;
* - for the texture units (2);
* - ligthing
* - eye-space coordinates and lighting
* - lights sources (8).
* - clip planes (6)
* - eye-space coordinates or fog
*/
#define TCL_CHECK( NM, FLAG ) \
static GLboolean check_##NM( GLcontext *ctx ) \
{ \
@@ -122,6 +176,7 @@ TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled )
TCL_CHECK( tcl_tex1, ctx->Texture.Unit[1]._ReallyEnabled )
TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled )
#if _HAVE_LIGHTING
TCL_CHECK( tcl_lit0, ctx->Light.Enabled && ctx->Light.Light[0].Enabled )
TCL_CHECK( tcl_lit1, ctx->Light.Enabled && ctx->Light.Light[1].Enabled )
TCL_CHECK( tcl_lit2, ctx->Light.Enabled && ctx->Light.Light[2].Enabled )
@@ -130,17 +185,42 @@ TCL_CHECK( tcl_lit4, ctx->Light.Enabled && ctx->Light.Light[4].Enabled )
TCL_CHECK( tcl_lit5, ctx->Light.Enabled && ctx->Light.Light[5].Enabled )
TCL_CHECK( tcl_lit6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled )
TCL_CHECK( tcl_lit7, ctx->Light.Enabled && ctx->Light.Light[7].Enabled )
#endif
#if _HAVE_USERCLIP
TCL_CHECK( tcl_ucp0, (ctx->Transform.ClipPlanesEnabled & 0x1) )
TCL_CHECK( tcl_ucp1, (ctx->Transform.ClipPlanesEnabled & 0x2) )
TCL_CHECK( tcl_ucp2, (ctx->Transform.ClipPlanesEnabled & 0x4) )
TCL_CHECK( tcl_ucp3, (ctx->Transform.ClipPlanesEnabled & 0x8) )
TCL_CHECK( tcl_ucp4, (ctx->Transform.ClipPlanesEnabled & 0x10) )
TCL_CHECK( tcl_ucp5, (ctx->Transform.ClipPlanesEnabled & 0x20) )
#endif
TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled )
/**
* \def ALLOC_STATE
* \brief Utility macro to initialize a state atom.
*
* Used internally by radeonInitState() to allocate the state atom command
* buffer and initiaze the state checking function.
*
* \param ATOM atom name, as defined in radeon_hw_state.
* \param CHK state checking function, as defined by #CHECK or #TCL_CHECK.
* \param SZ command buffer size.
* \param NM C string name for debugging output purposes.
* \param FLAG whether is a TCL dependent flag.
*/
/* Initialize the context's hardware state.
/**
* \brief Initialize the context's hardware state.
*
* \param rmesa Radeon context.
*
* Initalizes all state atoms giving apropriate inital state values. Allocates
* the state atoms' command buffers, using internally the #ALLOC_STATE macro
* for this effect. Fills in the packet headers with the register ID
* associated with the atom, via cmdpkt().
*/
void radeonInitState( radeonContextPtr rmesa )
{
@@ -211,14 +291,14 @@ void radeonInitState( radeonContextPtr rmesa )
make_empty_list(&(rmesa->hw.clean));
#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \
#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \
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.is_tcl = FLAG; \
rmesa->hw.ATOM.check = check_##CHK; \
rmesa->hw.ATOM.is_tcl = FLAG; \
rmesa->hw.ATOM.check = check_##CHK; \
insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \
} while (0)
@@ -245,12 +325,15 @@ void radeonInitState( radeonContextPtr rmesa )
ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 );
ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 );
#if _HAVE_USERCLIP
ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 );
ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 );
ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 );
ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 );
ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 );
#endif
#if _HAVE_LIGHTING
ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 );
ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 );
ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 );
@@ -259,7 +342,7 @@ void radeonInitState( radeonContextPtr rmesa )
ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 );
ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 );
ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 );
#endif
/* Fill in the packet headers:
*/
@@ -295,17 +378,21 @@ void radeonInitState( radeonContextPtr rmesa )
cmdvec( RADEON_VS_MATRIX_0_ADDR + i*4, 1, 16);
}
#if _HAVE_LIGHTING
for (i = 0 ; i < 8; i++) {
rmesa->hw.lit[i].cmd[LIT_CMD_0] =
cmdvec( RADEON_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 );
rmesa->hw.lit[i].cmd[LIT_CMD_1] =
cmdscl( RADEON_SS_LIGHT_DCD_ADDR + i, 8, 6 );
}
#endif
#if _HAVE_USERCLIP
for (i = 0 ; i < 6; i++) {
rmesa->hw.ucp[i].cmd[UCP_CMD_0] =
cmdvec( RADEON_VS_UCP_ADDR + i, 1, 4 );
}
#endif
rmesa->last_ReallyEnabled = -1;
@@ -390,11 +477,7 @@ void radeonInitState( radeonContextPtr rmesa )
RADEON_TEX1_W_ROUTING_USE_Q1);
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
((0x0000 & RADEON_LINE_PATTERN_MASK) |
(0 << RADEON_LINE_REPEAT_COUNT_SHIFT) |
(0 << RADEON_LINE_PATTERN_START_SHIFT) |
RADEON_LINE_PATTERN_LITTLE_BIT_ORDER);
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff);
rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] =
((0 << RADEON_LINE_CURRENT_PTR_SHIFT) |
@@ -513,52 +596,6 @@ void radeonInitState( radeonContextPtr rmesa )
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_SPECULAR_SOURCE_SHIFT));
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 );
#if _HAVE_SWTNL
TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
#endif
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 );
/* Set up vector and scalar state commands:
*/
/* upload_matrix( rmesa, ctx->ModelView.m, MODEL ); */
/* upload_matrix_t( rmesa, ctx->ModelView.inv, MODEL_IT ); */
/* upload_matrix( rmesa, ctx->TextureMatrix[0].m, TEXMAT_0 ); */
/* upload_matrix( rmesa, ctx->TextureMatrix[1].m, TEXMAT_1 ); */
/* upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, TEXMAT_2 ); */
rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE;
rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE;

View File

@@ -0,0 +1,77 @@
/**
* \file radeon_subset.h
* \brief Radeon subset driver declarations.
*
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* Tungsten Grahpics Inc., Austin, 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 GRAHPICS 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.
*/
/* $XFree86$ */
#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,
const GLubyte *bitmap );
extern void radeonReadPixels( GLcontext *ctx,
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 );
extern void radeonInitSelect( GLcontext *ctx );
extern void radeonVtxfmtDestroy( GLcontext *ctx );
extern void radeonVtxfmtMakeCurrent( GLcontext *ctx );
extern void radeonVtxfmtUnbindContext( GLcontext *ctx );
extern void radeonVtxfmtInit( GLcontext *ctx );
extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
extern void radeonVtxfmtInvalidate( GLcontext *ctx );
extern void radeonSubsetVtxEnableTCL( radeonContextPtr rmesa, GLboolean flag );
extern void radeonUpdateTextureState( GLcontext *ctx );
extern void radeonInitTextureFuncs( GLcontext *ctx );
extern void radeonAgeTextures( radeonContextPtr rmesa, int heap );
extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
#endif

View File

@@ -0,0 +1,180 @@
/**
* \file radeon_subset_bitmap.c
* \brief Bitmap drawing.
*
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Copyright 2003 ATI Technologies Inc., Ontario, Canada, and
* 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.
*
*/
/* $XFree86$ */
#include "glheader.h"
#include "mtypes.h"
#include "colormac.h"
#include "enums.h"
#include "imports.h"
#include "image.h"
#include "mmath.h"
#include "macros.h"
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_subset.h"
/**
* \brief Cope with depth operations by drawing individual pixels as points
*
* \param ctx GL context.
* \param px x coordinate of the bitmap corner.
* \param py y coordinate of the bitmap corner.
* \param width bitmap width.
* \param height bitmap height.
* \param unpack unpacking pixel attributes.
* \param bitmap bitmap pointer.
*
* Clips the bitmap coordinates and adjusts for windows coordinates. Draws the
* bitmap with glPoints(), turning off TCL and hardware viewport transformation
* to emit raw pixel coordinates. Finally fires any outstanding vertices and
* 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 )
{
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;
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;
/* vertical clipping */
if (py < 0) {
skipRows -= py;
height += py;
py = 0;
}
if (py + height > (GLint) ctx->ReadBuffer->Height)
height -= (py + height - (GLint) ctx->ReadBuffer->Height);
if (height <= 0)
return;
/* Turn off tcl and the hw viewport transformation so that we can
* emit raw pixel coordinates:
*/
radeonSubsetVtxEnableTCL( rmesa, GL_FALSE );
RADEON_STATECHANGE( rmesa, set );
orig_se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL];
rmesa->hw.set.cmd[SET_SE_CNTL] &= ~(RADEON_VPORT_XY_XFORM_ENABLE |
RADEON_VPORT_Z_XFORM_ENABLE);
/* Adjust for window coordinates, flip y values:
*/
h = rmesa->dri.drawable->h + rmesa->dri.drawable->y - 1;
px += rmesa->dri.drawable->x;
/* Save current color, texcoord to restore later:
*/
COPY_4V( saved_color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
COPY_2V( saved_tex0, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
/* Just use the GL entrypoints to talk to radeon_subset_vtx.c:
*/
glBegin( GL_POINTS );
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 );
}
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 );
/* Fire outstanding vertices, restore state
*/
RADEON_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_SE_CNTL] = orig_se_cntl;
radeonSubsetVtxEnableTCL( rmesa, GL_TRUE );
}

View File

@@ -0,0 +1,207 @@
/**
* \file radeon_subset_readpix.c
* \brief Pixel reading.
*
* \author Keith Whitwell <keith@tungstengraphics.com>
* \author Brian Paul <brian@tungstengraphics.com>
*/
/*
* Copyright 2003 ATI Technologies Inc., Ontario, Canada, and
* 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.
*/
/* $XFree86$ */
#include "glheader.h"
#include "mtypes.h"
#include "colormac.h"
#include "enums.h"
#include "imports.h"
#include "mmath.h"
#include "macros.h"
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_subset.h"
/**
* \brief Read pixel in RGBA format on a Radeon 16bpp frame buffer.
*
* \param rgba destination pointer.
* \param ptr pointer to the pixel in the frame buffer.
*/
#define READ_RGBA_16( rgba, ptr ) \
do { \
GLushort p = *(GLushort *)ptr; \
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)
/**
* \brief Read pixel in RGBA format on a Radeon 32bpp frame buffer.
*
* \param rgba destination pointer.
* \param ptr pointer to the pixel in the frame buffer.
*/
#define READ_RGBA_32( rgba, ptr ) \
do { \
GLuint p = *(GLuint *)ptr; \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = (p >> 24) & 0xff; \
} while (0)
/**
* \brief Read a span in RGBA format.
*
* \param ctx GL context.
* \param n number of pixels in the span.
* \param x x position of the span start.
* \param y y position of the span.
* \param rgba destination buffer.
*
* Calculates the pointer to the span start in the frame buffer and uses either
* #READ_RGBA_16 or #READ_RGBA_32 macros to copy the values.
*/
static void ReadRGBASpan( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4])
{
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;
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 );
}
/**
* \brief Optimized glReadPixels().
*
* To be used with particular pixel formats GL_UNSIGNED_BYTE and GL_RGBA, when pixel
* scaling, biasing and mapping are disabled.
*
* \param ctx GL context.
* \param x x start position of the reading rectangle.
* \param y y start position of the reading rectangle.
* \param width width of the reading rectangle.
* \param height height of the reading recatangle.
* \param format pixel format. Must be GL_RGBA.
* \param format pixel type. Must be GL_UNSIGNED_BYTE.
* \param packing packing attributes. Must specify byte alignment and no byte
* swaping or LSB ordering.
*
* After asserting the above conditions, compensates for clipping and calls
* ReadRGBASpan() to read each row.
*/
void radeonReadPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *packing,
GLvoid *pixels )
{
GLint srcX = x;
GLint srcY = y;
GLint readWidth = width; /* actual width read */
GLint readHeight = height; /* actual height read */
GLint skipRows = packing->SkipRows;
GLint skipPixels = packing->SkipPixels;
GLint rowLength;
/* can't do scale, bias, mapping, etc */
assert(!ctx->_ImageTransferState);
/* can't do fancy pixel packing */
assert (packing->Alignment == 1 &&
!packing->SwapBytes &&
!packing->LsbFirst);
if (packing->RowLength > 0)
rowLength = packing->RowLength;
else
rowLength = width;
/* horizontal clipping */
if (srcX < 0) {
skipPixels -= srcX;
readWidth += srcX;
srcX = 0;
}
if (srcX + readWidth > (GLint) ctx->ReadBuffer->Width)
readWidth -= (srcX + readWidth - (GLint) ctx->ReadBuffer->Width);
if (readWidth <= 0)
return;
/* vertical clipping */
if (srcY < 0) {
skipRows -= srcY;
readHeight += srcY;
srcY = 0;
}
if (srcY + readHeight > (GLint) ctx->ReadBuffer->Height)
readHeight -= (srcY + readHeight - (GLint) ctx->ReadBuffer->Height);
if (readHeight <= 0)
return;
/*
* Ready to read!
* The window region at (destX, destY) of size (readWidth, readHeight)
* will be read back.
* We'll write pixel data to buffer pointed to by "pixels" but we'll
* skip "skipRows" rows and skip "skipPixels" pixels/row.
*/
if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
GLchan *dest = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels) * 4;
GLint row;
for (row=0; row<readHeight; row++) {
ReadRGBASpan(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest);
dest += rowLength * 4;
srcY++;
}
}
else {
/* can't do this format/type combination */
assert(0);
}
}

View File

@@ -0,0 +1,993 @@
/**
* \file radeon_subset_select.c
* \brief Selection.
*/
/*
* Mesa 3-D graphics library
* Version: 4.1
*
* Copyright (C) 1999-2002 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.
*/
/* $Id: radeon_subset_select.c,v 1.1.2.4 2003/02/23 16:50:48 jrfonseca Exp $ */
#include "glheader.h"
#include "imports.h"
#include "context.h"
#include "mmath.h"
#include "mtypes.h"
#include "enums.h"
#include "glapi.h"
#include "feedback.h"
#include "radeon_context.h"
#include "radeon_subset.h"
/**
* \brief Vertex.
*/
typedef struct {
struct { GLfloat x, y, z, w; } pos; /**< \brief position */
struct { GLfloat x, y, z, w; } eyePos; /**< \brief position, eye coordinates */
struct { GLfloat x, y, z, w; } clipPos; /**< \brief clipped coordiantes */
struct { GLfloat x, y, z, w; } winPos; /**< \brief position, windows coordinates */
struct { GLfloat s, t; } texCoord; /**< \brief texture coordinates */
struct { GLfloat r, g, b, a; } color; /**< \brief color */
} vertex;
/**
* \brief Vertex buffer.
*/
static struct select_vb_t {
GLuint vCount; /**< \brief vertex count */
vertex vBuffer[4]; /**< \brief vertex buffer */
GLboolean lineReset;
GLboolean partialLineLoop; /**< \brief whether we are in a middle of a line loop */
} vb;
/**********************************************************************/
/** \name Vertex Transformation and Clipping */
/**********************************************************************/
/*@{*/
/**
* \brief Transform a point (column vector) by a matrix: Q = M * P.
*
* \param Q destination point.
* \param P source point.
* \param M transformation matrix.
*/
#define TRANSFORM_POINT( Q, M, P ) \
Q.x = M[0] * P.x + M[4] * P.y + M[8] * P.z + M[12] * P.w; \
Q.y = M[1] * P.x + M[5] * P.y + M[9] * P.z + M[13] * P.w; \
Q.z = M[2] * P.x + M[6] * P.y + M[10] * P.z + M[14] * P.w; \
Q.w = M[3] * P.x + M[7] * P.y + M[11] * P.z + M[15] * P.w;
/**
* \brief Clip coord to window coord mapping.
*
* \param Q destination point.
* \param P source point.
* \param VP view port.
*/
#define MAP_POINT( Q, P, VP ) \
Q.x = (GLfloat) (((P.x / P.w) + 1.0) * VP.Width / 2.0 + VP.X); \
Q.y = (GLfloat) (((P.y / P.w) + 1.0) * VP.Height / 2.0 + VP.Y); \
Q.z = (GLfloat) (((P.z / P.w) + 1.0) * (VP.Far - VP.Near) / 2.0 + VP.Near);\
Q.w = (GLfloat) P.w;
/**
* \brief Linear interpolation: (1 - T) * A + T * B.
*
* \param T interpolation factor.
* \param A first value.
* \param B second value.
* \result interpolated value.
*/
#define INTERPOLATE(T, A, B) ((A) + ((B) - (A)) * (T))
/**
* \brief Interpolate vertex position, color, texcoords, etc.
*
* \param t interpolation factor.
* \param v0 first vertex.
* \param v1 second vertex.
* \param vOut output vertex.
*
* Uses the #INTERPOLATE macro for all the interpolation of all elements.
*/
static void
interpolate_vertex(GLfloat t, const vertex *v0, const vertex *v1,
vertex *vOut)
{
vOut->eyePos.x = INTERPOLATE(t, v0->eyePos.x, v1->eyePos.x);
vOut->eyePos.y = INTERPOLATE(t, v0->eyePos.y, v1->eyePos.y);
vOut->eyePos.z = INTERPOLATE(t, v0->eyePos.z, v1->eyePos.z);
vOut->eyePos.w = INTERPOLATE(t, v0->eyePos.w, v1->eyePos.w);
vOut->clipPos.x = INTERPOLATE(t, v0->clipPos.x, v1->clipPos.x);
vOut->clipPos.y = INTERPOLATE(t, v0->clipPos.y, v1->clipPos.y);
vOut->clipPos.z = INTERPOLATE(t, v0->clipPos.z, v1->clipPos.z);
vOut->clipPos.w = INTERPOLATE(t, v0->clipPos.w, v1->clipPos.w);
vOut->color.r = INTERPOLATE(t, v0->color.r, v1->color.r);
vOut->color.g = INTERPOLATE(t, v0->color.g, v1->color.g);
vOut->color.b = INTERPOLATE(t, v0->color.b, v1->color.b);
vOut->color.a = INTERPOLATE(t, v0->color.a, v1->color.a);
vOut->texCoord.s = INTERPOLATE(t, v0->texCoord.s, v1->texCoord.s);
vOut->texCoord.t = INTERPOLATE(t, v0->texCoord.t, v1->texCoord.t);
}
/*
* Clip bit codes
*/
#define CLIP_LEFT 1
#define CLIP_RIGHT 2
#define CLIP_BOTTOM 4
#define CLIP_TOP 8
#define CLIP_NEAR 16
#define CLIP_FAR 32
/**
* \brief Apply view volume clip testing to a point.
*
* \param v point to test.
* \return zero if visible, or the clip code mask, i.e., binary OR of a
* combination of the #CLIP_LEFT, #CLIP_RIGHT, #CLIP_BOTTOM, #CLIP_TOP, #CLIP_NEAR,
* #CLIP_FAR clip bit codes.
*/
static GLuint
clip_point(const vertex *v)
{
GLuint mask = 0;
if (v->clipPos.x > v->clipPos.w) mask |= CLIP_RIGHT;
if (v->clipPos.x < -v->clipPos.w) mask |= CLIP_LEFT;
if (v->clipPos.y > v->clipPos.w) mask |= CLIP_TOP;
if (v->clipPos.y < -v->clipPos.w) mask |= CLIP_BOTTOM;
if (v->clipPos.z > v->clipPos.w) mask |= CLIP_FAR;
if (v->clipPos.z < -v->clipPos.w) mask |= CLIP_NEAR;
return mask;
}
/**
* \def GENERAL_CLIP
* \brief Clipping utility macro.
*
* We use 6 instances of this code in each of the clip_line() and
* clip_polygon() to clip against the 6 planes. For each plane, we define the
* #OUTSIDE and #COMPUTE_INTERSECTION macros appropriately.
*/
/**
* \brief Apply clipping to a line segment.
*
* \param v0in input start vertice
* \param v1in input end vertice
* \param v0new output start vertice
* \param v1new output end vertice
*
* \return GL_TRUE if the line segment is visible, or GL_FALSE if it is totally
* clipped.
*
* \sa #GENERAL_CLIP.
*/
static GLboolean
clip_line(const vertex *v0in, const vertex *v1in,
vertex *v0new, vertex *v1new)
{
vertex v0, v1, vNew;
GLfloat dx, dy, dz, dw, t;
GLuint code0, code1;
code0 = clip_point(v0in);
code1 = clip_point(v1in);
if (code0 & code1)
return GL_FALSE; /* totally clipped */
*v0new = *v0in;
*v1new = *v1in;
if (code0 == 0 && code1 == 0)
return GL_TRUE; /* no clipping needed */
v0 = *v0in;
v1 = *v1in;
#define GENERAL_CLIP \
if (OUTSIDE(v0)) { \
if (OUTSIDE(v1)) { \
/* both verts are outside ==> return 0 */ \
return 0; \
} \
else { \
/* v0 is outside, v1 is inside ==> clip */ \
COMPUTE_INTERSECTION( v1, v0, vNew ) \
interpolate_vertex(t, &v1, &v0, &vNew); \
v0 = vNew; \
} \
} \
else { \
if (OUTSIDE(v1)) { \
/* v0 is inside, v1 is outside ==> clip */ \
COMPUTE_INTERSECTION( v0, v1, vNew ) \
interpolate_vertex(t, &v0, &v1, &vNew); \
v1 = vNew; \
} \
/* else both verts are inside ==> do nothing */ \
}
/* Clip against +X side */
#define OUTSIDE(V) (V.clipPos.x > V.clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dx = OUT.clipPos.x - IN.clipPos.x; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = (IN.clipPos.x - IN.clipPos.w) / (dw-dx);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
/* Clip against -X side */
#define OUTSIDE(V) (V.clipPos.x < -(V.clipPos.w))
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dx = OUT.clipPos.x - IN.clipPos.x; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = -(IN.clipPos.x + IN.clipPos.w) / (dw+dx);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
/* Clip against +Y side */
#define OUTSIDE(V) (V.clipPos.y > V.clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dy = OUT.clipPos.y - IN.clipPos.y; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = (IN.clipPos.y - IN.clipPos.w) / (dw-dy);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
/* Clip against -Y side */
#define OUTSIDE(V) (V.clipPos.y < -(V.clipPos.w))
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dy = OUT.clipPos.y - IN.clipPos.y; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = -(IN.clipPos.y + IN.clipPos.w) / (dw+dy);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
/* Clip against +Z side */
#define OUTSIDE(V) (V.clipPos.z > V.clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dz = OUT.clipPos.z - IN.clipPos.z; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = (IN.clipPos.z - IN.clipPos.w) / (dw-dz);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
/* Clip against -Z side */
#define OUTSIDE(V) (V.clipPos.z < -(V.clipPos.w))
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dz = OUT.clipPos.z - IN.clipPos.z; \
dw = OUT.clipPos.w - IN.clipPos.w; \
t = -(IN.clipPos.z + IN.clipPos.w) / (dw+dz);
GENERAL_CLIP
#undef OUTSIDE
#undef COMPUTE_INTERSECTION
#undef GENERAL_CLIP
*v0new = v0;
*v1new = v1;
return GL_TRUE;
}
/**
* \brief Apply clipping to a polygon.
*
* \param vIn array of input vertices.
* \param inCount number of input vertices
* \param vOut array of output vertices.
*
* \return number of vertices in \p vOut.
*
* \sa #GENERAL_CLIP.
*/
static GLuint
clip_polygon(const vertex *vIn, unsigned int inCount, vertex *vOut)
{
vertex inlist[20], outlist[20];
GLfloat dx, dy, dz, dw, t;
GLuint incount, outcount, previ, curri, result;
const vertex *currVert, *prevVert;
vertex *newVert;
#define GENERAL_CLIP(INCOUNT, INLIST, OUTCOUNT, OUTLIST) \
if (INCOUNT < 3) \
return GL_FALSE; \
previ = INCOUNT - 1; /* let previous = last vertex */ \
prevVert = INLIST + previ; \
OUTCOUNT = 0; \
for (curri = 0; curri < INCOUNT; curri++) { \
currVert = INLIST + curri; \
if (INSIDE(currVert)) { \
if (INSIDE(prevVert)) { \
/* both verts are inside ==> copy current to outlist */ \
OUTLIST[OUTCOUNT] = *currVert; \
OUTCOUNT++; \
} \
else { \
newVert = OUTLIST + OUTCOUNT; \
/* current is inside and previous is outside ==> clip */ \
COMPUTE_INTERSECTION( currVert, prevVert, newVert ) \
OUTCOUNT++; \
/* Output current */ \
OUTLIST[OUTCOUNT] = *currVert; \
OUTCOUNT++; \
} \
} \
else { \
if (INSIDE(prevVert)) { \
newVert = OUTLIST + OUTCOUNT; \
/* current is outside and previous is inside ==> clip */ \
COMPUTE_INTERSECTION( prevVert, currVert, newVert ); \
OUTLIST[OUTCOUNT] = *newVert; \
OUTCOUNT++; \
} \
/* else both verts are outside ==> do nothing */ \
} \
/* let previous = current */ \
previ = curri; \
prevVert = currVert; \
}
/*
* Clip against +X
*/
#define INSIDE(V) (V->clipPos.x <= V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dx = OUT->clipPos.x - IN->clipPos.x; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = (IN->clipPos.x - IN->clipPos.w) / (dw - dx); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(inCount, vIn, outcount, outlist)
#undef INSIDE
#undef COMPUTE_INTERSECTION
/*
* Clip against -X
*/
#define INSIDE(V) (V->clipPos.x >= -V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dx = OUT->clipPos.x - IN->clipPos.x; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = -(IN->clipPos.x + IN->clipPos.w) / (dw + dx); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(outcount, outlist, incount, inlist)
#undef INSIDE
#undef COMPUTE_INTERSECTION
/*
* Clip against +Y
*/
#define INSIDE(V) (V->clipPos.y <= V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dy = OUT->clipPos.y - IN->clipPos.y; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = (IN->clipPos.y - IN->clipPos.w) / (dw - dy); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(incount, inlist, outcount, outlist)
#undef INSIDE
#undef COMPUTE_INTERSECTION
/*
* Clip against -Y
*/
#define INSIDE(V) (V->clipPos.y >= -V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dy = OUT->clipPos.y - IN->clipPos.y; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = -(IN->clipPos.y + IN->clipPos.w) / (dw + dy); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(outcount, outlist, incount, inlist)
#undef INSIDE
#undef COMPUTE_INTERSECTION
/*
* Clip against +Z
*/
#define INSIDE(V) (V->clipPos.z <= V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dz = OUT->clipPos.z - IN->clipPos.z; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = (IN->clipPos.z - IN->clipPos.w) / (dw - dz); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(incount, inlist, outcount, outlist)
#undef INSIDE
#undef COMPUTE_INTERSECTION
/*
* Clip against -Z
*/
#define INSIDE(V) (V->clipPos.z >= -V->clipPos.w)
#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
dz = OUT->clipPos.z - IN->clipPos.z; \
dw = OUT->clipPos.w - IN->clipPos.w; \
t = -(IN->clipPos.z + IN->clipPos.w) / (dw + dz); \
interpolate_vertex(t, IN, OUT, NEW );
GENERAL_CLIP(outcount, outlist, result, vOut)
#undef INSIDE
#undef COMPUTE_INTERSECTION
#undef GENERAL_CLIP
return result;
}
/*@}*/
/**********************************************************************/
/** \name Selection */
/**********************************************************************/
/*@{*/
/**
* \brief Select point.
*
* \param v vertex.
*
* If the clipped point is visible then maps the vertex into window coordinates
* and calls _mesa_update_hitflag().
*/
static void
select_point(const vertex *v)
{
GET_CURRENT_CONTEXT(ctx);
if (clip_point(v) == 0)
{
vertex c = *v;
MAP_POINT(c.winPos, c.clipPos, ctx->Viewport);
_mesa_update_hitflag(ctx, c.winPos.z);
}
}
/**
* \brief Select line.
*
* \param v0 first vertex.
* \param v1 second vertex.
*
* If the clipped line is visible then maps the vertices into window coordinates
* and calls _mesa_update_hitflag().
*/
static void
select_line(const vertex *v0, const vertex *v1)
{
GET_CURRENT_CONTEXT(ctx);
vertex c0, c1;
if (clip_line(v0, v1, &c0, &c1))
{
MAP_POINT(c0.winPos, c0.clipPos, ctx->Viewport);
MAP_POINT(c1.winPos, c1.clipPos, ctx->Viewport);
_mesa_update_hitflag(ctx, c0.winPos.z);
_mesa_update_hitflag(ctx, c1.winPos.z);
}
}
/**
* \brief Select line.
*
* \param v0 first vertex.
* \param v1 second vertex.
* \param v2 third vertex.
*
* If the clipped polygon is visible then maps the vertices into window
* coordinates and calls _mesa_update_hitflag().
*/
static void
select_triangle(const vertex *v0,
const vertex *v1,
const vertex *v2)
{
GET_CURRENT_CONTEXT(ctx);
vertex vlist[3], vclipped[8];
GLuint i, n;
vlist[0] = *v0;
vlist[1] = *v1;
vlist[2] = *v2;
n = clip_polygon(vlist, 3, vclipped);
for (i = 0; i < n; i++) {
MAP_POINT(vclipped[i].winPos, vclipped[i].clipPos, ctx->Viewport);
_mesa_update_hitflag(ctx, vclipped[i].winPos.z);
}
}
/**
* \brief Set current vertex coordinates.
*
* \param x x vertex coordinate.
* \param y y vertex coordinate.
* \param z z vertex coordinate.
*
* Stores the vertex and current attributes in ::vb, transforms it into eye space and then clip space.
*
* If a sufficient number of vertices is stored calls one of select_point(),
* select_line() or select_triangle(), according to the current primtive.
*/
static void
radeon_select_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_polygon_attrib *p = &(ctx->Polygon);
vertex *v = vb.vBuffer + vb.vCount;
/* store the vertex */
v->pos.x = x;
v->pos.y = y;
v->pos.z = z;
v->pos.w = w;
v->color.r = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
v->color.g = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
v->color.b = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
v->color.a = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
v->texCoord.s = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0];
v->texCoord.t = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1];
/* transform to eye space, then clip space */
TRANSFORM_POINT(v->eyePos, ctx->ModelviewMatrixStack.Top->m, v->pos);
TRANSFORM_POINT(v->clipPos, ctx->ProjectionMatrixStack.Top->m, v->eyePos);
switch (ctx->Driver.CurrentExecPrimitive) {
case GL_POINTS:
assert(vb.vCount == 0);
select_point(v);
break;
case GL_LINES:
if (vb.vCount == 0)
{
vb.vCount = 1;
}
else
{
assert(vb.vCount == 1);
select_line(vb.vBuffer + 0, vb.vBuffer + 1);
vb.vCount = 0;
}
break;
case GL_LINE_STRIP:
if (vb.vCount == 0)
{
vb.vCount = 1;
}
else
{
assert(vb.vCount == 1);
select_line(vb.vBuffer + 0, vb.vBuffer + 1);
vb.vBuffer[0] = vb.vBuffer[1];
/* leave vb.vCount at 1 */
}
break;
case GL_LINE_LOOP:
if (vb.vCount == 0)
{
vb.vCount = 1;
vb.partialLineLoop = GL_FALSE;
}
else if (vb.vCount == 1)
{
select_line(vb.vBuffer + 0, vb.vBuffer + 1);
vb.partialLineLoop = GL_TRUE;
vb.vCount = 2;
}
else
{
assert(vb.vCount == 2);
vb.partialLineLoop = GL_FALSE;
select_line(vb.vBuffer + 1, vb.vBuffer + 2);
vb.vBuffer[1] = vb.vBuffer[2];
/* leave vb.vCount at 2 */
}
break;
case GL_TRIANGLES:
if (vb.vCount == 0 || vb.vCount == 1)
{
vb.vCount++;
}
else
{
assert(vb.vCount == 2);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
vb.vCount = 0;
}
break;
case GL_TRIANGLE_STRIP:
if (vb.vCount == 0 || vb.vCount == 1)
{
vb.vCount++;
}
else if (vb.vCount == 2)
{
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
vb.vCount = 3;
}
else
{
assert(vb.vCount == 3);
select_triangle(vb.vBuffer + 1, vb.vBuffer + 3, vb.vBuffer + 2);
vb.vBuffer[0] = vb.vBuffer[2];
vb.vBuffer[1] = vb.vBuffer[3];
vb.vCount = 2;
}
break;
case GL_TRIANGLE_FAN:
if (vb.vCount == 0 || vb.vCount == 1)
{
vb.vCount++;
}
else
{
assert(vb.vCount == 2);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
vb.vBuffer[1] = vb.vBuffer[2];
/* leave vb.vCount = 2 */
}
break;
case GL_QUADS:
if (vb.vCount < 3)
{
vb.vCount++;
}
else
{
assert(vb.vCount == 3);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 2, vb.vBuffer + 3);
vb.vCount = 0;
}
break;
case GL_QUAD_STRIP:
if (vb.vCount < 3)
{
vb.vCount++;
}
else
{
assert(vb.vCount == 3);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
select_triangle(vb.vBuffer + 1, vb.vBuffer + 3, vb.vBuffer + 2);
vb.vBuffer[0] = vb.vBuffer[2];
vb.vBuffer[1] = vb.vBuffer[3];
vb.vCount = 2;
}
break;
case GL_POLYGON:
switch (p->FrontMode) {
case GL_POINT:
assert(vb.vCount == 0);
select_point(v);
break;
case GL_LINE:
if (vb.vCount == 0)
{
vb.vCount = 1;
vb.partialLineLoop = GL_FALSE;
}
else if (vb.vCount == 1)
{
select_line(vb.vBuffer + 0, vb.vBuffer + 1);
vb.partialLineLoop = GL_TRUE;
vb.vCount = 2;
}
else
{
assert(vb.vCount == 2);
vb.partialLineLoop = GL_FALSE;
select_line(vb.vBuffer + 1, vb.vBuffer + 2);
vb.vBuffer[1] = vb.vBuffer[2];
/* leave vb.vCount at 2 */
}
break;
case GL_FILL:
/* draw as a tri-fan */
if (vb.vCount == 0 || vb.vCount == 1)
{
vb.vCount++;
}
else
{
assert(vb.vCount == 2);
select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2);
vb.vBuffer[1] = vb.vBuffer[2];
/* leave vb.vCount = 2 */
}
break;
default:
; /* impossible */
}
break;
default:
; /* outside begin/end -- no action required */
}
}
/**
* \brief Calls radeon_select_Vertex4f().
*/
static void radeon_select_Vertex2f(GLfloat x, GLfloat y)
{
radeon_select_Vertex4f(x, y, 0.0, 1.0);
}
/**
* \brief Calls radeon_select_Vertex4f().
*/
static void radeon_select_Vertex2fv(const GLfloat * v)
{
radeon_select_Vertex4f(v[0], v[1], 0.0, 1.0);
}
/**
* \brief Calls radeon_select_Vertex4f().
*/
static void radeon_select_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
{
radeon_select_Vertex4f(x, y, z, 1.0);
}
/**
* \brief Calls radeon_select_Vertex4f().
*/
static void radeon_select_Vertex3fv(const GLfloat * v)
{
radeon_select_Vertex4f(v[0], v[1], v[2], 1.0);
}
/**
* \brief Set current vertex color.
*
* \param r red color component.
* \param g gree color component.
* \param b blue color component.
* \param a alpha color component.
*
* Updates the GL context's current vertex color.
*/
static void radeon_select_Color4f( GLfloat r, GLfloat g,
GLfloat b, GLfloat a )
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
dest[0] = r;
dest[1] = g;
dest[2] = b;
dest[3] = a;
}
/**
* \brief Calls radeon_select_Color4f().
*/
static void radeon_select_Color4fv( const GLfloat *v )
{
radeon_select_Color4f( v[0], v[1], v[2], v[3] );
}
/**
* \brief Calls radeon_select_Color4f().
*/
static void radeon_select_Color3f( GLfloat r, GLfloat g, GLfloat b )
{
radeon_select_Color4f( r, g, b, 1.0 );
}
/**
* \brief Calls radeon_select_Color4f().
*/
static void radeon_select_Color3fv( const GLfloat *v )
{
radeon_select_Color4f( v[0], v[1], v[2], 1.0 );
}
/**
* \brief Set current vertex texture coordinates.
*
* \param s texture coordinate.
* \param t texture coordinate.
*
* Updates the GL context's current vertex texture coordinates.
*/
static __inline__ void radeon_select_TexCoord2f( GLfloat s, GLfloat t )
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
dest[0] = s;
dest[1] = t;
}
/**
* \brief Calls radeon_select_TexCoord2f().
*/
static void radeon_select_TexCoord2fv( const GLfloat *v )
{
radeon_select_TexCoord2f( v[0], v[1] );
}
/**
* \brief Process glBegin().
*
* \param mode primitive.
*/
static void radeon_select_Begin(GLenum mode)
{
GET_CURRENT_CONTEXT(ctx);
if (mode > GL_POLYGON) {
_mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
return;
}
if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
return;
}
ctx->Driver.CurrentExecPrimitive = mode;
vb.vCount = 0;
vb.lineReset = GL_TRUE;
vb.partialLineLoop = GL_FALSE;
}
/**
* \brief Process glEnd().
*/
static void radeon_select_End(void)
{
GET_CURRENT_CONTEXT(ctx);
if ( (ctx->Driver.CurrentExecPrimitive == GL_LINE_LOOP ||
(ctx->Driver.CurrentExecPrimitive == GL_POLYGON &&
ctx->Polygon.FrontMode == GL_LINE))
&& vb.vCount == 2 )
{
/* draw the last line segment */
if (vb.partialLineLoop)
select_line(vb.vBuffer + 1, vb.vBuffer + 0);
else
select_line(vb.vBuffer + 2, vb.vBuffer + 0);
}
ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
}
/**
* \brief Flush vertices.
*
* \param ctx GL context.
* \param flags not used.
*
* Nothing much to do here, besides marking the vertices as flushed, as we
* don't buffer anything.
*/
static void radeonSelectFlushVertices( GLcontext *ctx, GLuint flags )
{
ctx->Driver.NeedFlush = 0;
}
/**
* \brief Install the select callbacks.
*
* \param ctx GL context.
*
* Installs the glBegin()/glEnd() associated select callbacks into the glapi
* table.
*/
void radeon_select_Install( GLcontext *ctx )
{
struct _glapi_table *exec = ctx->Exec;
exec->Color3f = radeon_select_Color3f;
exec->Color3fv = radeon_select_Color3fv;
exec->Color4f = radeon_select_Color4f;
exec->Color4fv = radeon_select_Color4fv;
exec->TexCoord2f = radeon_select_TexCoord2f;
exec->TexCoord2fv = radeon_select_TexCoord2fv;
exec->Vertex2f = radeon_select_Vertex2f;
exec->Vertex2fv = radeon_select_Vertex2fv;
exec->Vertex3f = radeon_select_Vertex3f;
exec->Vertex3fv = radeon_select_Vertex3fv;
exec->Begin = radeon_select_Begin;
exec->End = radeon_select_End;
ctx->Driver.FlushVertices = radeonSelectFlushVertices;
}
/**
* \brief Set rasterization mode.
*
* \param ctx GL context.
* \param mode rasterization mode. Supports GL_RENDER or
*
* Calls either radeonVtxfmtInit() or radeon_select_Install() according \p mode
* is GL_RENDER or GL_SELECT.
*/
static void radeonRenderMode( GLcontext *ctx, GLenum mode )
{
switch (mode) {
case GL_RENDER:
radeonVtxfmtInit( ctx );
break;
case GL_SELECT:
radeon_select_Install( ctx );
break;
default:
break;
}
}
/**
* \brief Setup the GL context driver callbacks.
*
* \param ctx GL context.
*
* \sa Called by radeonCreateContext().
*/
void radeonInitSelect( GLcontext *ctx )
{
ctx->Driver.RenderMode = radeonRenderMode;
}
/*@}*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,912 @@
/**
* \file radeon_subset_vtx.c
* \brief Vertex buffering.
*
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
/*
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
* 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.
*
*/
/* $XFree86$ */
#include "glheader.h"
#include "imports.h"
#include "api_noop.h"
#include "context.h"
#include "mmath.h"
#include "mtypes.h"
#include "enums.h"
#include "glapi.h"
#include "colormac.h"
#include "state.h"
#include "radeon_context.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#include "radeon_subset.h"
/**
* \brief Union for vertex data.
*/
union vertex_dword {
float f; /**< \brief floating point value */
int i; /**< \brief integer point value */
};
/**
* \brief Maxium number of dwords per vertex.
*
* Defined as 10 to hold: \code xyzw rgba st \endcode
*/
#define MAX_VERTEX_DWORDS 10
/**
* \brief Global vertex buffer data.
*/
static struct vb_t {
/**
* \brief Notification mechanism.
*
* These are treated as a stack to allow us to do things like build quads in
* temporary storage and then emit them as triangles.
*/
struct {
GLint vertspace; /**< \brief free vertices count */
GLint initial_vertspace; /**< \brief total vertices count */
GLint *dmaptr; /**< \brief */
void (*notify)( void ); /**< \brief notification callback */
} stack[2];
/**
* \brief Storage for current vertex.
*/
union vertex_dword vertex[MAX_VERTEX_DWORDS];
/**
* \brief Temporary storage for quads, etc.
*/
union vertex_dword vertex_store[MAX_VERTEX_DWORDS * 4];
/**
* \name Color/texture
*
* Pointers to either vertex or ctx->Current.Attrib, depending on whether
* color/texture participates in the current vertex.
*/
/*@{*/
GLfloat *floatcolorptr; /**< \brief color */
GLfloat *texcoordptr; /**< \brief texture */
/*@}*/
/**
* \brief Pointer to the GL context.
*/
GLcontext *context;
/**
* \brief Active primitive.
*
* \note May differ from ctx->Driver.CurrentExecPrimitive.
*/
/*@{*/
GLenum prim; /**< \brief primitive */
GLuint vertex_format; /**< \brief vertex format */
GLint vertex_size; /**< \brief vertex size */
GLboolean recheck; /**< \brief set if it's needed to validate this information */
/*@}*/
} vb;
static void radeonFlushVertices( GLcontext *, GLuint );
/**
* \brief Primitive information table.
*/
static struct prims_t {
int start, /**< \brief vertex count for the starting primitive */
incr, /**< \brief vertex increment for a further primitive */
hwprim; /**< \brief hardware primitive */
} prims[10] = {
{ 1, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_POINT },
{ 2, 2, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE },
{ 2, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP },
{ 2, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP },
{ 3, 3, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST },
{ 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP },
{ 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN },
{ 4, 4, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST },
{ 4, 2, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP },
{ 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN },
};
/**
* \brief Finish the primitive in the vertex buffer.
*
* \param rmesa Radeon context.
*
* Truncates any redundant vertices off the end of the buffer, emit the
* remainging vertices and advances the current DMA region.
*/
static void finish_prim( radeonContextPtr rmesa )
{
GLuint prim_end = vb.stack[0].initial_vertspace - vb.stack[0].vertspace;
/* Too few vertices? (eg: 2 vertices for a triangles prim?)
*/
if (prim_end < prims[vb.prim].start)
return;
/* Drop redundant vertices off end of primitive. (eg: 5 vertices
* for triangles prim?)
*/
prim_end -= (prim_end - prims[vb.prim].start) % prims[vb.prim].incr;
radeonEmitVertexAOS( rmesa, vb.vertex_size, GET_START(&rmesa->dma.current) );
radeonEmitVbufPrim( rmesa, vb.vertex_format,
prims[vb.prim].hwprim | rmesa->tcl.tcl_flag,
prim_end );
rmesa->dma.current.ptr =
rmesa->dma.current.start += prim_end * vb.vertex_size * 4;
}
/**
* \brief Copy a vertex from the current DMA region
*
* \param rmesa Radeon context.
* \param n vertice index relative to the current DMA region.
* \param dst destination pointer.
*
* Used internally by copy_dma_verts().
*/
static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst )
{
GLuint i;
GLfloat *src = (GLfloat *)(rmesa->dma.current.address +
rmesa->dma.current.ptr +
n * vb.vertex_size * 4);
for (i = 0 ; i < vb.vertex_size; i++)
dst[i] = src[i];
}
/**
* \brief Copy last vertices from the current DMA buffer to resume in a new buffer.
*
* \param rmesa Radeon context.
* \param tmp destination buffer.
*
* Takes from the current DMA buffer the last vertices necessary to resume in a
* new buffer, according to the current primitive. Uses internally
* copy_vertex() for the vertex copying.
*
*/
static GLuint copy_dma_verts( radeonContextPtr rmesa,
GLfloat (*tmp)[MAX_VERTEX_DWORDS] )
{
GLuint ovf, i;
GLuint nr = vb.stack[0].initial_vertspace - vb.stack[0].vertspace;
switch( vb.prim )
{
case GL_POINTS:
return 0;
case GL_LINES:
ovf = nr&1;
for (i = 0 ; i < ovf ; i++)
copy_vertex( rmesa, nr-ovf+i, tmp[i] );
return i;
case GL_TRIANGLES:
ovf = nr%3;
for (i = 0 ; i < ovf ; i++)
copy_vertex( rmesa, nr-ovf+i, tmp[i] );
return i;
case GL_LINE_STRIP:
if (nr == 0)
return 0;
copy_vertex( rmesa, nr-1, tmp[0] );
return 1;
case GL_LINE_LOOP:
case GL_TRIANGLE_FAN:
case GL_POLYGON:
if (nr == 0)
return 0;
else if (nr == 1) {
copy_vertex( rmesa, 0, tmp[0] );
return 1;
} else {
copy_vertex( rmesa, 0, tmp[0] );
copy_vertex( rmesa, nr-1, tmp[1] );
return 2;
}
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
case GL_QUADS:
ovf = MIN2( nr-1, 2 );
for (i = 0 ; i < ovf ; i++)
copy_vertex( rmesa, nr-ovf+i, tmp[i] );
return i;
default:
return 0;
}
}
static void notify_wrap_buffer( void );
/**
* \brief Resets the vertex buffer notifycation mechanism.
*
* Fills in vb_t::stack with the values from the current DMA region in
* radeon_dma::current and sets the notification callback to
* notify_wrap_buffer().
*/
static void reset_notify( void )
{
radeonContextPtr rmesa = RADEON_CONTEXT( vb.context );
vb.stack[0].dmaptr = (int *)(rmesa->dma.current.address +
rmesa->dma.current.ptr);
vb.stack[0].vertspace = ((rmesa->dma.current.end - rmesa->dma.current.ptr) /
(vb.vertex_size * 4));
vb.stack[0].vertspace &= ~1; /* even numbers only -- avoid tristrip parity */
vb.stack[0].initial_vertspace = vb.stack[0].vertspace;
vb.stack[0].notify = notify_wrap_buffer;
}
/**
* \brief Full buffer notification callback.
*
* Makes a copy of the necessary vertices of the current buffer via
* copy_dma_verts(), gets and resets new buffer via radeon and reemits the
* saved vertices.
*/
static void notify_wrap_buffer( void )
{
GLcontext *ctx = vb.context;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLfloat tmp[3][MAX_VERTEX_DWORDS];
GLuint i, nrverts = 0;
/* Copy vertices out of dma:
*/
nrverts = copy_dma_verts( rmesa, tmp );
finish_prim( rmesa );
/* Get new buffer
*/
radeonRefillCurrentDmaRegion( rmesa );
/* Reset vertspace[0], dmaptr
*/
reset_notify();
/* Reemit saved vertices
*/
for (i = 0 ; i < nrverts; i++) {
memcpy( vb.stack[0].dmaptr, tmp[i], vb.vertex_size * 4 );
vb.stack[0].dmaptr += vb.vertex_size;
vb.stack[0].vertspace--;
}
}
static void notify_noop( void )
{
vb.stack[0].dmaptr = (int *)vb.vertex;
vb.stack[0].notify = notify_noop;
vb.stack[0].vertspace = 1;
}
/**
* \brief Pop the notification mechanism stack.
*
* Simply copy the second stack array element into the first.
*
* \sa vb_t::stack and push_notify().
*/
static void pop_notify( void )
{
vb.stack[0] = vb.stack[1];
}
/**
* \brief Push the notification mechanism stack.
*
* \param notify new notify callback for the stack head.
* \param space space available for vertices in \p store.
* \param store buffer where to store the vertices.
*
* Copy the second stack array element into the first and makes the stack head
* use the given resources.
*
* \sa vb_t::stack and pop_notify().
*/
static void push_notify( void (*notify)( void ), int space,
union vertex_dword *store )
{
vb.stack[1] = vb.stack[0];
vb.stack[0].notify = notify;
vb.stack[0].initial_vertspace = space;
vb.stack[0].vertspace = space;
vb.stack[0].dmaptr = (int *)store;
}
/**
* \brief Emit a stored vertex (in vb_t::vertex_store) to DMA.
*
* \param v vertex index.
*
* Adds the vertex into the current vertex buffer and calls the notification
* callback vb_t::notify().
*/
static void emit_vertex( int v )
{
int i, *tmp = (int *)vb.vertex_store + v * vb.vertex_size;
for (i = 0 ; i < vb.vertex_size ; i++)
*vb.stack[0].dmaptr++ = *tmp++;
if (--vb.stack[0].vertspace == 0)
vb.stack[0].notify();
}
/**
* \brief Emit a quad (in vb_t::vertex_store) to DMA as two triangles.
*
* \param v0 first vertex index.
* \param v1 second vertex index.
* \param v2 third vertex index.
* \param v3 fourth vertex index.
*
* Calls emit_vertex() to emit the triangles' vertices.
*/
static void emit_quad( int v0, int v1, int v2, int v3 )
{
emit_vertex( v0 ); emit_vertex( v1 ); emit_vertex( v3 );
emit_vertex( v1 ); emit_vertex( v2 ); emit_vertex( v3 );
}
/**
* \brief Every fourth vertex in a quad primitive, this is called to emit it.
*
* Pops the notification stack, calls emit_quad() and pushes the notification
* stack again, with itself and the vb_t::vertex_store to process another four
* vertices.
*/
static void notify_quad( void )
{
pop_notify();
emit_quad( 0, 1, 2, 3 );
push_notify( notify_quad, 4, vb.vertex_store );
}
static void notify_qstrip1( void );
/**
* \brief After the 4th vertex, emit either a quad or a flipped quad each two
* vertices.
*
* Pops the notification stack, calls emit_quad() with the flipped vertices and
* pushes the notification stack again, with notify_qstrip1() and the
* vb_t::vertex_store to process another two vertices.
*
* \sa notify_qstrip1().
*/
static void notify_qstrip0( void )
{
pop_notify();
emit_quad( 0, 1, 3, 2 );
push_notify( notify_qstrip1, 2, vb.vertex_store );
}
/**
* \brief After the 4th vertex, emit either a quad or a flipped quad each two
* vertices.
*
* Pops the notification stack, calls emit_quad() with the straight vertices
* and pushes the notification stack again, with notify_qstrip0() and the
* vb_t::vertex_store to process another two vertices.
*
* \sa notify_qstrip0().
*/
static void notify_qstrip1( void )
{
pop_notify();
emit_quad( 2, 3, 1, 0 );
push_notify( notify_qstrip0, 2, vb.vertex_store + 2*vb.vertex_size );
}
/**
* \brief Emit the saved vertex (but hang on to it for later).
*
* Continue processing this primitive as a linestrip.
*
* Pops the notification stack and calls emit_quad with the first vertex.
*/
static void notify_lineloop0( void )
{
pop_notify();
emit_vertex(0);
}
/**
* \brief Invalidate the current vertex format.
*
* \param ctx GL context.
*
* Sets the vb_t::recheck flag.
*/
void radeonVtxfmtInvalidate( GLcontext *ctx )
{
vb.recheck = GL_TRUE;
}
/**
* \brief Validate the vertex format from the context.
*
* \param ctx GL context.
*
* Signals a new primitive and determines the appropriate vertex format and
* size. Points vb_t::floatcolorptr and vb_t::texcoordptr to the curent vertex
* and sets them to the current color and texture attributes.
*
* Clears the vb_t::recheck flag on exit.
*/
static void radeonVtxfmtValidate( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
GLuint ind = (RADEON_CP_VC_FRMT_Z |
RADEON_CP_VC_FRMT_FPCOLOR |
RADEON_CP_VC_FRMT_FPALPHA);
if (ctx->Driver.NeedFlush)
ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
if (ctx->Texture.Unit[0]._ReallyEnabled)
ind |= RADEON_CP_VC_FRMT_ST0;
RADEON_NEWPRIM(rmesa);
vb.vertex_format = ind;
vb.vertex_size = 3;
/* Would prefer to use ubyte floats in the vertex:
*/
vb.floatcolorptr = &vb.vertex[vb.vertex_size].f;
vb.vertex_size += 4;
vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
if (ind & RADEON_CP_VC_FRMT_ST0) {
vb.texcoordptr = &vb.vertex[vb.vertex_size].f;
vb.vertex_size += 2;
vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0];
vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1];
}
else
vb.texcoordptr = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
vb.recheck = GL_FALSE;
ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
}
#define RESET_STIPPLE() do { \
RADEON_STATECHANGE( rmesa, lin ); \
radeonEmitState( rmesa ); \
} while (0)
#define AUTO_STIPPLE( mode ) do { \
RADEON_STATECHANGE( rmesa, lin ); \
if (mode) \
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \
RADEON_LINE_PATTERN_AUTO_RESET; \
else \
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \
~RADEON_LINE_PATTERN_AUTO_RESET; \
radeonEmitState( rmesa ); \
} while (0)
/**
* \brief Process glBegin().
*
* \param mode primitive.
*/
static void radeon_Begin( GLenum mode )
{
GLcontext *ctx = vb.context;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint se_cntl;
if (mode > GL_POLYGON) {
_mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
return;
}
if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
return;
}
if (ctx->NewState)
_mesa_update_state( ctx );
if (rmesa->NewGLState)
radeonValidateState( ctx );
if (vb.recheck)
radeonVtxfmtValidate( ctx );
/* Do we need to grab a new DMA region for the vertices?
*/
if (rmesa->dma.current.ptr + 12*vb.vertex_size*4 > rmesa->dma.current.end) {
RADEON_NEWPRIM( rmesa );
radeonRefillCurrentDmaRegion( rmesa );
}
reset_notify();
vb.prim = ctx->Driver.CurrentExecPrimitive = mode;
se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL] | RADEON_FLAT_SHADE_VTX_LAST;
if (ctx->Line.StippleFlag &&
(mode == GL_LINES ||
mode == GL_LINE_LOOP ||
mode == GL_LINE_STRIP))
RESET_STIPPLE();
switch( mode ) {
case GL_LINES:
if (ctx->Line.StippleFlag)
AUTO_STIPPLE( GL_TRUE );
break;
case GL_LINE_LOOP:
vb.prim = GL_LINE_STRIP;
push_notify( notify_lineloop0, 1, vb.vertex_store );
break;
case GL_QUADS:
vb.prim = GL_TRIANGLES;
push_notify( notify_quad, 4, vb.vertex_store );
break;
case GL_QUAD_STRIP:
if (ctx->_TriangleCaps & DD_FLATSHADE) {
vb.prim = GL_TRIANGLES;
push_notify( notify_qstrip0, 4, vb.vertex_store );
}
break;
case GL_POLYGON:
if (ctx->_TriangleCaps & DD_FLATSHADE)
se_cntl &= ~RADEON_FLAT_SHADE_VTX_LAST;
break;
default:
break;
}
if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) {
RADEON_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl;
}
}
/**
* \brief Process glEnd().
*
*/
static void radeon_End( void )
{
GLcontext *ctx = vb.context;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
return;
}
/* Need to finish a line loop?
*/
if (ctx->Driver.CurrentExecPrimitive == GL_LINE_LOOP)
emit_vertex( 0 );
/* Need to pop off quads/quadstrip/etc notification?
*/
if (vb.stack[0].notify != notify_wrap_buffer)
pop_notify();
finish_prim( rmesa );
if (ctx->Driver.CurrentExecPrimitive == GL_LINES && ctx->Line.StippleFlag)
AUTO_STIPPLE( GL_FALSE );
ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
notify_noop();
}
/**
* \brief Flush vertices.
*
* \param ctx GL context.
* \param flags flags.
*
* If FLUSH_UPDATE_CURRENT is et in \p flags then the current vertex attributes
* in the GL context is updated from vb_t::floatcolorptr and vb_t::texcoordptr.
*/
static void radeonFlushVertices( GLcontext *ctx, GLuint flags )
{
if (flags & FLUSH_UPDATE_CURRENT) {
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = vb.floatcolorptr[0];
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = vb.floatcolorptr[1];
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = vb.floatcolorptr[2];
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = vb.floatcolorptr[3];
if (vb.vertex_format & RADEON_CP_VC_FRMT_ST0) {
ctx->Current.Attrib[VERT_ATTRIB_TEX0][0] = vb.texcoordptr[0];
ctx->Current.Attrib[VERT_ATTRIB_TEX0][1] = vb.texcoordptr[1];
ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] = 0.0F;
ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] = 1.0F;
}
}
ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
}
/**
* \brief Set current vertex coordinates.
*
* \param x x vertex coordinate.
* \param y y vertex coordinate.
* \param z z vertex coordinate.
*
* Set the current vertex coordinates. If run out of space in this buffer call
* the notification callback.
*/
static __inline__ void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
{
int i;
*vb.stack[0].dmaptr++ = *(int *)&x;
*vb.stack[0].dmaptr++ = *(int *)&y;
*vb.stack[0].dmaptr++ = *(int *)&z;
for (i = 3; i < vb.vertex_size; i++)
*vb.stack[0].dmaptr++ = vb.vertex[i].i;
if (--vb.stack[0].vertspace == 0)
vb.stack[0].notify();
}
/**
* \brief Set current vertex color.
*
* \param r red color component.
* \param g gree color component.
* \param b blue color component.
* \param a alpha color component.
*
* Sets the current vertex color via vb_t::floatcolorptr.
*/
static __inline__ void radeon_Color4f( GLfloat r, GLfloat g,
GLfloat b, GLfloat a )
{
GLfloat *dest = vb.floatcolorptr;
dest[0] = r;
dest[1] = g;
dest[2] = b;
dest[3] = a;
}
/**
* \brief Set current vertex texture coordinates.
*
* \param s texture coordinate.
* \param t texture coordinate.
*
* Sets the current vertex color via vb_t::texcoordptr.
*/
static __inline__ void radeon_TexCoord2f( GLfloat s, GLfloat t )
{
GLfloat *dest = vb.texcoordptr;
dest[0] = s;
dest[1] = t;
}
/**
* Calls radeon_Vertex3f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Vertex3fv( const GLfloat *v )
{
radeon_Vertex3f( v[0], v[1], v[2] );
}
/**
* Calls radeon_Vertex3f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Vertex2f( GLfloat x, GLfloat y )
{
radeon_Vertex3f( x, y, 0 );
}
/**
* Calls radeon_Vertex3f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Vertex2fv( const GLfloat *v )
{
radeon_Vertex3f( v[0], v[1], 0 );
}
/**
* Calls radeon_Vertex3f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Color4fv( const GLfloat *v )
{
radeon_Color4f( v[0], v[1], v[2], v[3] );
}
/**
* Calls radeon_Color4f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Color3f( GLfloat r, GLfloat g, GLfloat b )
{
radeon_Color4f( r, g, b, 1.0 );
}
/**
* Calls radeon_Color4f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_Color3fv( const GLfloat *v )
{
radeon_Color4f( v[0], v[1], v[2], 1.0 );
}
/**
* Calls radeon_TexCoord2f(), which is expanded inline by the compiler to be
* efficient.
*/
static void radeon_TexCoord2fv( const GLfloat *v )
{
radeon_TexCoord2f( v[0], v[1] );
}
/**
* \brief Setup the GL context callbacks.
*
* \param ctx GL context.
*
* Setups the GL context callbacks and links _glapi_table entries related to
* the glBegin()/glEnd() pairs to the functions in this module.
*
* Called by radeonCreateContext() and radeonRenderMode().
*/
void radeonVtxfmtInit( GLcontext *ctx )
{
struct _glapi_table *exec = ctx->Exec;
exec->Color3f = radeon_Color3f;
exec->Color3fv = radeon_Color3fv;
exec->Color4f = radeon_Color4f;
exec->Color4fv = radeon_Color4fv;
exec->TexCoord2f = radeon_TexCoord2f;
exec->TexCoord2fv = radeon_TexCoord2fv;
exec->Vertex2f = radeon_Vertex2f;
exec->Vertex2fv = radeon_Vertex2fv;
exec->Vertex3f = radeon_Vertex3f;
exec->Vertex3fv = radeon_Vertex3fv;
exec->Begin = radeon_Begin;
exec->End = radeon_End;
vb.context = ctx;
ctx->Driver.FlushVertices = radeonFlushVertices;
ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
radeonVtxfmtValidate( ctx );
notify_noop();
}
/**
* No-op.
*/
void radeonVtxfmtUnbindContext( GLcontext *ctx )
{
}
/**
* No-op.
*/
void radeonVtxfmtMakeCurrent( GLcontext *ctx )
{
}
/**
* No-op.
*/
void radeonVtxfmtDestroy( GLcontext *ctx )
{
}
/**
* \brief Software rendering fallback.
*
* \param ctx GL context.
* \param bit fallback bitmask.
* \param mode enable or disable.
*
* Does nothing except display a warning message if \p mode is set.
*/
void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
{
if (mode)
fprintf(stderr, "Warning: hit nonexistant fallback path!\n");
}
/**
* \brief Software TCL fallback.
*
* \param ctx GL context.
* \param bit fallback bitmask.
* \param mode enable or disable.
*
* Does nothing except display a warning message if \p mode is set.
*/
void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
{
if (mode)
fprintf(stderr, "Warning: hit nonexistant fallback path!\n");
}
/**
* \brief Called by radeonPointsBitmap() to disable TCL.
*
* \param rmesa Radeon context.
* \param flag whether to enable or disable TCL.
*
* Updates radeon_tcl_info::tcl_flag.
*/
void radeonSubsetVtxEnableTCL( radeonContextPtr rmesa, GLboolean flag )
{
rmesa->tcl.tcl_flag = flag ? RADEON_CP_VC_CNTL_TCL_ENABLE : 0;
}

View File

@@ -593,13 +593,8 @@ static void ELT_FALLBACK( GLcontext *ctx,
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
#if RADEON_OLD_PACKETS
# define GET_CURRENT_VB_MAX_ELTS() \
((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 24)) / 2)
#else
# define GET_CURRENT_VB_MAX_ELTS() \
((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
#endif
#define GET_SUBSEQUENT_VB_MAX_ELTS() \
((RADEON_CMD_BUF_SZ - 1024) / 2)
@@ -623,7 +618,7 @@ do { \
\
radeonEmitVertexAOS( rmesa, \
rmesa->swtcl.vertex_size, \
(rmesa->radeonScreen->agp_buffer_offset + \
(rmesa->radeonScreen->agp_buffer_offset + \
rmesa->swtcl.indexed_verts.buf->buf->idx * \
RADEON_BUFFER_SIZE + \
rmesa->swtcl.indexed_verts.start)); \
@@ -1136,6 +1131,115 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
}
}
static void radeonWrapRunPipeline( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (0)
fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState);
/* Validate state:
*/
if (rmesa->NewGLState)
radeonValidateState( ctx );
if (tnl->vb.Material) {
TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
}
/* Run the pipeline.
*/
_tnl_run_pipeline( ctx );
if (tnl->vb.Material) {
TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
radeonUpdateMaterial( ctx ); /* not needed any more? */
}
}
static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
/* Can't generally do unfilled via tcl, but some good special
* cases work.
*/
TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
if (rmesa->TclFallback) {
radeonChooseRenderState( ctx );
radeonChooseVertexState( ctx );
}
}
extern const struct gl_pipeline_stage _radeon_render_stage;
extern const struct gl_pipeline_stage _radeon_tcl_stage;
static const struct gl_pipeline_stage *radeon_pipeline[] = {
/* Try and go straight to t&l
*/
&_radeon_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.
*/
&_radeon_render_stage,
&_tnl_render_stage, /* FALLBACK: */
0,
};
void radeonCreateTnlContext( GLcontext *ctx )
{
_ae_create_context( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
/* Install the customized pipeline:
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, radeon_pipeline );
/* Try and keep materials and vertices separate:
*/
_tnl_isolate_materials( ctx, GL_TRUE );
#if _HAVE_SWRAST
_swsetup_CreateContext( ctx );
#endif
/* Set maxlocksize (and hence vb size) small enough to avoid
* fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
* fit in a single dma buffer for indexed rendering of quad strips,
* etc.
*/
/* ctx->Const.MaxArrayLockSize = */
/* MIN2( ctx->Const.MaxArrayLockSize, */
/* RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); */
}
/**********************************************************************/
/* Initialization. */
@@ -1159,14 +1263,22 @@ void radeonInitSwtcl( GLcontext *ctx )
tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive;
tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple;
tnl->Driver.Render.BuildVertices = radeonBuildVertices;
tnl->Driver.NotifyMaterialChange = radeonUpdateMaterial;
tnl->Driver.RunPipeline = radeonWrapRunPipeline;
rmesa->swtcl.verts = (char *)ALIGN_MALLOC( size * 16 * 4, 32 );
rmesa->swtcl.RenderIndex = ~0;
rmesa->swtcl.render_primitive = GL_TRIANGLES;
rmesa->swtcl.hw_primitive = 0;
ctx->Driver.PolygonMode = radeonPolygonMode;
tnl->Driver.NotifyMaterialChange( ctx );
}
void radeonDestroySwtcl( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);

View File

@@ -38,7 +38,61 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "mtypes.h"
#include "swrast/swrast.h"
#include "radeon_context.h"
/* Flags for software fallback cases */
/* See correponding strings in radeon_swtcl.c */
#define RADEON_FALLBACK_TEXTURE 0x0001
#define RADEON_FALLBACK_DRAW_BUFFER 0x0002
#define RADEON_FALLBACK_STENCIL 0x0004
#define RADEON_FALLBACK_RENDER_MODE 0x0008
#define RADEON_FALLBACK_BLEND_EQ 0x0010
#define RADEON_FALLBACK_BLEND_FUNC 0x0020
#define RADEON_FALLBACK_DISABLE 0x0040
/* Use the templated vertex format:
*/
#define COLOR_IS_RGBA
#define TAG(x) radeon##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
typedef void (*radeon_tri_func)( radeonContextPtr,
radeonVertex *,
radeonVertex *,
radeonVertex * );
typedef void (*radeon_line_func)( radeonContextPtr,
radeonVertex *,
radeonVertex * );
typedef void (*radeon_point_func)( radeonContextPtr,
radeonVertex * );
/* radeon_swtcl.c
*/
struct radeon_swtcl_info {
GLuint SetupIndex;
GLuint SetupNewInputs;
GLuint RenderIndex;
GLuint vertex_size;
GLuint vertex_stride_shift;
GLuint vertex_format;
char *verts;
/* Fallback rasterization functions
*/
radeon_point_func draw_point;
radeon_line_func draw_line;
radeon_tri_func draw_tri;
GLuint hw_primitive;
GLenum render_primitive;
GLuint numverts;
struct radeon_dma_region indexed_verts;
};
extern void radeonInitSwtcl( GLcontext *ctx );
extern void radeonDestroySwtcl( GLcontext *ctx );

View File

@@ -563,3 +563,14 @@ void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
fprintf(stderr, "Warning: hit nonexistant fallback path!\n");
}
#endif
void radeonSubsetVtxEnableTCL( radeonContextPtr rmesa,
GLboolean flag )
{
if (flag)
rmesa->tcl.tcl_flag = RADEON_CP_VC_CNTL_TCL_ENABLE;
else
rmesa->tcl.tcl_flag = 0;
}

View File

@@ -36,8 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_TCL_H__
#define __RADEON_TCL_H__
#ifdef GLX_DIRECT_RENDERING
#include "radeon_context.h"
extern void radeonTclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim );
@@ -76,4 +74,3 @@ typedef void (*render_func)( GLcontext *ctx, GLuint start, GLuint count,
#endif
#endif
#endif

View File

@@ -241,6 +241,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
}
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565;
#if _HAVE_FULL_GL
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
@@ -292,6 +293,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
return &_mesa_texformat_al88;
#endif
case GL_INTENSITY:
case GL_INTENSITY4:
@@ -310,6 +312,40 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
}
static void radeonTexImage2D( 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 )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
/* fprintf(stderr, "%s\n", __FUNCTION__); */
if ( t ) {
radeonSwapOutTexObj( rmesa, t );
}
else {
t = radeonAllocTexObj( texObj );
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
}
texObj->DriverData = t;
}
/* Note, this will call radeonChooseTextureFormat */
_mesa_store_teximage2d(ctx, target, level, internalFormat,
width, height, border, format, type, pixels,
&ctx->Unpack, texObj, texImage);
t->dirty_images |= (1 << level);
}
#if _HAVE_FULL_GL
static void radeonTexImage1D( GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint border,
@@ -375,41 +411,6 @@ static void radeonTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
t->dirty_images |= (1 << level);
}
static void radeonTexImage2D( 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 )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
/* fprintf(stderr, "%s\n", __FUNCTION__); */
if ( t ) {
radeonSwapOutTexObj( rmesa, t );
}
else {
t = radeonAllocTexObj( texObj );
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
}
texObj->DriverData = t;
}
/* Note, this will call radeonChooseTextureFormat */
_mesa_store_teximage2d(ctx, target, level, internalFormat,
width, height, border, format, type, pixels,
&ctx->Unpack, texObj, texImage);
t->dirty_images |= (1 << level);
}
static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
@@ -443,7 +444,7 @@ static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
t->dirty_images |= (1 << level);
}
#endif
#define SCALED_FLOAT_TO_BYTE( x, scale ) \
@@ -474,6 +475,7 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target,
break;
}
#if _HAVE_FULL_GL
case GL_TEXTURE_LOD_BIAS_EXT: {
GLfloat bias;
GLuint b;
@@ -498,6 +500,7 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target,
}
break;
}
#endif
default:
return;
@@ -597,6 +600,7 @@ static void radeonDeleteTexture( GLcontext *ctx,
}
}
#if _HAVE_FULL_GL
static GLboolean radeonIsTextureResident( GLcontext *ctx,
struct gl_texture_object *texObj )
{
@@ -604,6 +608,7 @@ static GLboolean radeonIsTextureResident( GLcontext *ctx,
return ( t && t->memBlock );
}
#endif
static void radeonInitTextureObjects( GLcontext *ctx )
@@ -639,57 +644,40 @@ static void radeonInitTextureObjects( GLcontext *ctx )
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 radeonTexGen( GLcontext *ctx,
GLenum coord,
GLenum pname,
const GLfloat *params )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint unit = ctx->Texture.CurrentUnit;
rmesa->recheck_texgen[unit] = GL_TRUE;
}
void radeonInitTextureFuncs( GLcontext *ctx )
{
ctx->Driver.ChooseTextureFormat = radeonChooseTextureFormat;
ctx->Driver.TexImage1D = radeonTexImage1D;
ctx->Driver.TexImage2D = radeonTexImage2D;
#if _HAVE_FULL_GL
ctx->Driver.TexImage1D = radeonTexImage1D;
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
ctx->Driver.TexSubImage1D = radeonTexSubImage1D;
ctx->Driver.TexSubImage2D = radeonTexSubImage2D;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
ctx->Driver.IsTextureResident = radeonIsTextureResident;
#endif
#if _HAVE_SWRAST
/* XXX */
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;
#endif
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
ctx->Driver.BindTexture = radeonBindTexture;
ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */
ctx->Driver.DeleteTexture = radeonDeleteTexture;
ctx->Driver.IsTextureResident = radeonIsTextureResident;
ctx->Driver.PrioritizeTexture = NULL;
ctx->Driver.ActiveTexture = NULL;
ctx->Driver.UpdateTexturePalette = NULL;
ctx->Driver.TexEnv = radeonTexEnv;
ctx->Driver.TexParameter = radeonTexParameter;
ctx->Driver.TexGen = radeonTexGen;
radeonInitTextureObjects( ctx );
}

View File

@@ -37,7 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_TEX_H__
#define __RADEON_TEX_H__
#ifdef GLX_DIRECT_RENDERING
extern void radeonUpdateTextureState( GLcontext *ctx );
@@ -53,5 +52,4 @@ extern void radeonUpdateTexLRU( radeonContextPtr rmesa, radeonTexObjPtr t );
extern void radeonInitTextureFuncs( GLcontext *ctx );
#endif
#endif /* __RADEON_TEX_H__ */

View File

@@ -0,0 +1,256 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ */
/*
* Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
*
* 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
* VA LINUX SYSTEMS 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:
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "imports.h"
#include "api_arrayelt.h"
#include "mmath.h"
#include "enums.h"
#include "colormac.h"
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_vtxfmt.h"
static void set_texgen_matrix( radeonContextPtr rmesa,
GLuint unit,
GLfloat *s_plane,
GLfloat *t_plane )
{
static const GLfloat scale_identity[4] = { 1,1,1,1 };
if (!TEST_EQ_4V( s_plane, scale_identity) ||
!(TEST_EQ_4V( t_plane, scale_identity))) {
rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
}
/* Ignoring the Q texcoord for now.
*
* Returns GL_FALSE if fallback required.
*/
GLboolean radeonUpdateTexgen( GLcontext *ctx, GLuint unit )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
GLuint tmp = rmesa->TexGenEnabled;
rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
rmesa->TexGenNeedNormals[unit] = 0;
if (0)
fprintf(stderr, "%s unit %d cleared texgenEnabled %x\n", __FUNCTION__,
unit, rmesa->TexGenEnabled);
if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
/* Disabled, no fallback:
*/
rmesa->TexGenEnabled |=
(RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
return GL_TRUE;
}
else if (texUnit->TexGenEnabled & Q_BIT) {
/* Very easy to do this, in fact would remove a fallback case
* elsewhere, but I haven't done it yet... Fallback:
*/
fprintf(stderr, "fallback Q_BIT\n");
return GL_FALSE;
}
else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
texUnit->GenModeS != texUnit->GenModeT) {
/* Mixed modes, fallback:
*/
/* fprintf(stderr, "fallback mixed texgen\n"); */
return GL_FALSE;
}
else
rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
switch (texUnit->GenModeS) {
case GL_OBJECT_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
set_texgen_matrix( rmesa, unit,
texUnit->ObjectPlaneS,
texUnit->ObjectPlaneT);
break;
case GL_EYE_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
set_texgen_matrix( rmesa, unit,
texUnit->EyePlaneS,
texUnit->EyePlaneT);
break;
case GL_REFLECTION_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
break;
case GL_NORMAL_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
break;
case GL_SPHERE_MAP:
default:
/* Unsupported mode, fallback:
*/
/* fprintf(stderr, "fallback unsupported texgen\n"); */
return GL_FALSE;
}
if (tmp != rmesa->TexGenEnabled) {
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
/* fprintf(stderr, "%s unit %d texgenEnabled %x\n", __FUNCTION__, */
/* unit, rmesa->TexGenEnabled); */
return GL_TRUE;
}
void radeonUpdateTextureMatrix( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
int unit;
rmesa->TexMatEnabled = 0;
for (unit = 0 ; unit < 2; unit++) {
if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
}
else if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE|
RADEON_TEXMAT_0_ENABLE) << unit;
if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
/* Need to preconcatenate any active texgen
* obj/eyeplane matrices:
*/
_math_matrix_mul_matrix( &rmesa->tmpmat,
&rmesa->TexGenMatrix[unit],
ctx->TextureMatrixStack[unit].Top );
radeonUploadMatrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit );
}
else {
rmesa->TexMatEnabled |=
(RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
radeonUploadMatrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
TEXMAT_0+unit );
}
}
else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
radeonUploadMatrix( rmesa, rmesa->TexGenMatrix[unit].m,
TEXMAT_0+unit );
}
}
tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
(0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT));
if (tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE)
vs |= RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
else
vs |= RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
if (tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE)
vs |= RADEON_TCL_TEX_COMPUTED_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
else
vs |= RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
RADEON_STATECHANGE(rmesa, tcl);
rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
}
}
/* 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 radeonTexGen( GLcontext *ctx,
GLenum coord,
GLenum pname,
const GLfloat *params )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint unit = ctx->Texture.CurrentUnit;
rmesa->recheck_texgen[unit] = GL_TRUE;
}
void radeonInitTexTransform( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
_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 );
ctx->Driver.TexGen = radeonTexGen;
}

View File

@@ -66,9 +66,6 @@ void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
t->tObj->DriverData = NULL;
if ( rmesa ) {
/* Bump the performace counter */
rmesa->c_textureSwaps++;
if ( t == rmesa->state.texture.unit[0].texobj ) {
rmesa->state.texture.unit[0].texobj = NULL;
remove_from_list( &rmesa->hw.tex[0] );
@@ -95,9 +92,6 @@ void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
}
/* Bump the performace counter */
rmesa->c_textureSwaps++;
if ( t->memBlock ) {
mmFreeMem( t->memBlock );
t->memBlock = NULL;

View File

@@ -612,117 +612,6 @@ static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
};
/* GL_EXT_texture_env_combine support
*/
/* The color tables have combine functions for GL_SRC_COLOR,
* GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
*/
static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
{
{
RADEON_COLOR_ARG_A_T0_COLOR,
RADEON_COLOR_ARG_A_T1_COLOR,
RADEON_COLOR_ARG_A_T2_COLOR
},
{
RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
},
{
RADEON_COLOR_ARG_A_T0_ALPHA,
RADEON_COLOR_ARG_A_T1_ALPHA,
RADEON_COLOR_ARG_A_T2_ALPHA
},
{
RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
},
};
static GLuint radeon_tfactor_color[] =
{
RADEON_COLOR_ARG_A_TFACTOR_COLOR,
RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
};
static GLuint radeon_primary_color[] =
{
RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
};
static GLuint radeon_previous_color[] =
{
RADEON_COLOR_ARG_A_CURRENT_COLOR,
RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
RADEON_COLOR_ARG_A_CURRENT_ALPHA,
RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
};
/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
*/
static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
{
{
RADEON_ALPHA_ARG_A_T0_ALPHA,
RADEON_ALPHA_ARG_A_T1_ALPHA,
RADEON_ALPHA_ARG_A_T2_ALPHA
},
{
RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
},
};
static GLuint radeon_tfactor_alpha[] =
{
RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
};
static GLuint radeon_primary_alpha[] =
{
RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
};
static GLuint radeon_previous_alpha[] =
{
RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
};
/* Extract the arg from slot A, shift it into the correct argument slot
* and set the corresponding complement bit.
*/
#define RADEON_COLOR_ARG( n, arg ) \
do { \
color_combine |= \
((color_arg[n] & RADEON_COLOR_ARG_MASK) \
<< RADEON_COLOR_ARG_##arg##_SHIFT); \
color_combine |= \
((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
<< RADEON_COMP_ARG_##arg##_SHIFT); \
} while (0)
#define RADEON_ALPHA_ARG( n, arg ) \
do { \
alpha_combine |= \
((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
<< RADEON_ALPHA_ARG_##arg##_SHIFT); \
alpha_combine |= \
((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
<< RADEON_COMP_ARG_##arg##_SHIFT); \
} while (0)
/* ================================================================
@@ -736,8 +625,6 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
const struct gl_texture_object *tObj = texUnit->_Current;
const GLenum format = tObj->Image[tObj->BaseLevel]->Format;
GLuint color_combine, alpha_combine;
GLuint color_arg[3], alpha_arg[3];
GLuint i, numColorArgs = 0, numAlphaArgs = 0;
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
fprintf( stderr, "%s( %p, %d ) format=%s\n", __FUNCTION__,
@@ -840,6 +727,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
}
break;
#if _HAVE_FULL_GL
case GL_ADD:
switch ( format ) {
case GL_RGBA:
@@ -864,247 +752,10 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COMBINE_EXT:
/* Don't cache these results.
*/
rmesa->state.texture.unit[unit].format = 0;
rmesa->state.texture.unit[unit].envMode = 0;
/* Step 0:
* Calculate how many arguments we need to process.
*/
switch ( texUnit->CombineModeRGB ) {
case GL_REPLACE:
numColorArgs = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
case GL_SUBTRACT:
case GL_DOT3_RGB:
case GL_DOT3_RGBA:
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGBA_EXT:
numColorArgs = 2;
break;
case GL_INTERPOLATE:
numColorArgs = 3;
break;
default:
if (!radeonUpdateTextureEnvCombine(ctx, unit))
return GL_FALSE;
}
switch ( texUnit->CombineModeA ) {
case GL_REPLACE:
numAlphaArgs = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
case GL_SUBTRACT:
numAlphaArgs = 2;
break;
case GL_INTERPOLATE:
numAlphaArgs = 3;
break;
default:
return GL_FALSE;
}
/* Step 1:
* Extract the color and alpha combine function arguments.
*/
for ( i = 0 ; i < numColorArgs ; i++ ) {
const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
ASSERT(op >= 0);
ASSERT(op <= 3);
switch ( texUnit->CombineSourceRGB[i] ) {
case GL_TEXTURE:
color_arg[i] = radeon_texture_color[op][unit];
break;
case GL_CONSTANT:
color_arg[i] = radeon_tfactor_color[op];
break;
case GL_PRIMARY_COLOR:
color_arg[i] = radeon_primary_color[op];
break;
case GL_PREVIOUS:
color_arg[i] = radeon_previous_color[op];
break;
default:
return GL_FALSE;
}
}
for ( i = 0 ; i < numAlphaArgs ; i++ ) {
const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
ASSERT(op >= 0);
ASSERT(op <= 1);
switch ( texUnit->CombineSourceA[i] ) {
case GL_TEXTURE:
alpha_arg[i] = radeon_texture_alpha[op][unit];
break;
case GL_CONSTANT:
alpha_arg[i] = radeon_tfactor_alpha[op];
break;
case GL_PRIMARY_COLOR:
alpha_arg[i] = radeon_primary_alpha[op];
break;
case GL_PREVIOUS:
alpha_arg[i] = radeon_previous_alpha[op];
break;
default:
return GL_FALSE;
}
}
/* Step 2:
* Build up the color and alpha combine functions.
*/
switch ( texUnit->CombineModeRGB ) {
case GL_REPLACE:
color_combine = (RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, C );
break;
case GL_MODULATE:
color_combine = (RADEON_COLOR_ARG_C_ZERO |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, B );
break;
case GL_ADD:
color_combine = (RADEON_COLOR_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, C );
break;
case GL_ADD_SIGNED:
color_combine = (RADEON_COLOR_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADDSIGNED |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, C );
break;
case GL_SUBTRACT:
color_combine = (RADEON_COLOR_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_SUBTRACT |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, C );
break;
case GL_INTERPOLATE:
color_combine = (RADEON_BLEND_CTL_BLEND |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, B );
RADEON_COLOR_ARG( 1, A );
RADEON_COLOR_ARG( 2, C );
break;
case GL_DOT3_RGB:
case GL_DOT3_RGBA:
if ( texUnit->CombineScaleShiftRGB
!= (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) )
{
return GL_FALSE;
}
/* FALLTHROUGH */
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGBA_EXT:
color_combine = (RADEON_COLOR_ARG_C_ZERO |
RADEON_BLEND_CTL_DOT3 |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, B );
break;
default:
return GL_FALSE;
}
switch ( texUnit->CombineModeA ) {
case GL_REPLACE:
alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
RADEON_ALPHA_ARG_B_ZERO |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, C );
break;
case GL_MODULATE:
alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, B );
break;
case GL_ADD:
alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADD |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, C );
break;
case GL_ADD_SIGNED:
alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADDSIGNED |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, C );
break;
case GL_SUBTRACT:
alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_SUBTRACT |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, C );
break;
case GL_INTERPOLATE:
alpha_combine = (RADEON_BLEND_CTL_BLEND |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, B );
RADEON_ALPHA_ARG( 1, A );
RADEON_ALPHA_ARG( 2, C );
break;
default:
return GL_FALSE;
}
if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
|| (texUnit->CombineModeRGB == GL_DOT3_RGB_ARB) ) {
alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
}
/* Step 3:
* Apply the scale factor. The EXT version of the DOT3 extension does
* not support the scale factor, but the ARB version (and the version in
* OpenGL 1.3) does. The catch is that the Radeon only supports a 1X
* multiplier in hardware w/the ARB version.
*/
if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT &&
texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT &&
texUnit->CombineModeRGB != GL_DOT3_RGB &&
texUnit->CombineModeRGB != GL_DOT3_RGBA ) {
color_combine |= (texUnit->CombineScaleShiftRGB << RADEON_SCALE_SHIFT);
alpha_combine |= (texUnit->CombineScaleShiftA << RADEON_SCALE_SHIFT);
}
else
{
color_combine |= RADEON_SCALE_4X;
alpha_combine |= RADEON_SCALE_4X;
}
/* All done!
*/
break;
#endif
default:
return GL_FALSE;
@@ -1153,115 +804,6 @@ static void import_tex_obj_state( radeonContextPtr rmesa,
static void set_texgen_matrix( radeonContextPtr rmesa,
GLuint unit,
GLfloat *s_plane,
GLfloat *t_plane )
{
static const GLfloat scale_identity[4] = { 1,1,1,1 };
if (!TEST_EQ_4V( s_plane, scale_identity) ||
!(TEST_EQ_4V( t_plane, scale_identity))) {
rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
}
/* Ignoring the Q texcoord for now.
*
* Returns GL_FALSE if fallback required.
*/
static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
GLuint tmp = rmesa->TexGenEnabled;
rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
rmesa->TexGenNeedNormals[unit] = 0;
if (0)
fprintf(stderr, "%s unit %d cleared texgenEnabled %x\n", __FUNCTION__,
unit, rmesa->TexGenEnabled);
if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
/* Disabled, no fallback:
*/
rmesa->TexGenEnabled |=
(RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
return GL_TRUE;
}
else if (texUnit->TexGenEnabled & Q_BIT) {
/* Very easy to do this, in fact would remove a fallback case
* elsewhere, but I haven't done it yet... Fallback:
*/
fprintf(stderr, "fallback Q_BIT\n");
return GL_FALSE;
}
else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
texUnit->GenModeS != texUnit->GenModeT) {
/* Mixed modes, fallback:
*/
/* fprintf(stderr, "fallback mixed texgen\n"); */
return GL_FALSE;
}
else
rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
switch (texUnit->GenModeS) {
case GL_OBJECT_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
set_texgen_matrix( rmesa, unit,
texUnit->ObjectPlaneS,
texUnit->ObjectPlaneT);
break;
case GL_EYE_LINEAR:
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
set_texgen_matrix( rmesa, unit,
texUnit->EyePlaneS,
texUnit->EyePlaneT);
break;
case GL_REFLECTION_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
break;
case GL_NORMAL_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
break;
case GL_SPHERE_MAP:
default:
/* Unsupported mode, fallback:
*/
/* fprintf(stderr, "fallback unsupported texgen\n"); */
return GL_FALSE;
}
if (tmp != rmesa->TexGenEnabled) {
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
/* fprintf(stderr, "%s unit %d texgenEnabled %x\n", __FUNCTION__, */
/* unit, rmesa->TexGenEnabled); */
return GL_TRUE;
}
@@ -1322,13 +864,15 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
if (t->dirty_state & (1<<unit)) {
import_tex_obj_state( rmesa, unit, t );
}
#if _HAVE_TEXGEN
if (rmesa->recheck_texgen[unit]) {
GLboolean fallback = !radeon_validate_texgen( ctx, unit );
GLboolean fallback = !radeonUpdateTexgen( ctx, unit );
TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
rmesa->recheck_texgen[unit] = 0;
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
#endif
format = tObj->Image[tObj->BaseLevel]->Format;
if ( rmesa->state.texture.unit[unit].format != format ||
@@ -1367,13 +911,12 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
}
#if _HAVE_TEXGEN
if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
rmesa->recheck_texgen[unit] = GL_TRUE;
}
{
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
GLuint tmp = rmesa->TexGenEnabled;
@@ -1390,6 +933,8 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
}
#endif
}
return GL_TRUE;

View File

@@ -0,0 +1,84 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ */
/*
* Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
*
* 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
* VA LINUX SYSTEMS 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:
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "imports.h"
#include "api_arrayelt.h"
#include "mmath.h"
#include "enums.h"
#include "colormac.h"
#include "radeon_context.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_vtxfmt.h"
void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
{
GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
RADEON_STATECHANGE( rmesa, ucp[p] );
rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
}
void radeonUpdateClipPlanes( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint p;
for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
RADEON_STATECHANGE( rmesa, ucp[p] );
rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
}
}
}
void radeonInitUserClip( GLcontext *ctx )
{
int i;
ctx->Driver.ClipPlane = radeonClipPlane;
for (i = 0 ; i < 6; i++)
ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL );
}

View File

@@ -947,6 +947,11 @@ static void radeonFlushVertices( GLcontext *ctx, GLuint flags )
}
static void radeonRenderMode( GLcontext *ctx, GLenum mode )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
}
/* At this point, don't expect very many versions of each function to
* be generated, so not concerned about freeing them?
@@ -1055,6 +1060,8 @@ void radeonVtxfmtInit( GLcontext *ctx )
radeonInitCodegen( &rmesa->vb.codegen );
ctx->Driver.RenderMode = radeonRenderMode;
#if !_HAVE_SWTNL
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
radeonVtxfmtValidate( ctx );

View File

@@ -36,12 +36,111 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __RADEON_VTXFMT_H__
#define __RADEON_VTXFMT_H__
#ifdef GLX_DIRECT_RENDERING
#include "radeon_context.h"
#define RADEON_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;
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 dfn_generators {
struct dynfn *(*Vertex2f)( GLcontext *, int );
struct dynfn *(*Vertex2fv)( GLcontext *, int );
struct dynfn *(*Vertex3f)( GLcontext *, int );
struct dynfn *(*Vertex3fv)( GLcontext *, int );
struct dynfn *(*Color4ub)( GLcontext *, int );
struct dynfn *(*Color4ubv)( GLcontext *, int );
struct dynfn *(*Color3ub)( GLcontext *, int );
struct dynfn *(*Color3ubv)( GLcontext *, int );
struct dynfn *(*Color4f)( GLcontext *, int );
struct dynfn *(*Color4fv)( GLcontext *, int );
struct dynfn *(*Color3f)( GLcontext *, int );
struct dynfn *(*Color3fv)( GLcontext *, int );
struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int );
struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int );
struct dynfn *(*Normal3f)( GLcontext *, int );
struct dynfn *(*Normal3fv)( GLcontext *, int );
struct dynfn *(*TexCoord2f)( GLcontext *, int );
struct dynfn *(*TexCoord2fv)( GLcontext *, int );
struct dynfn *(*TexCoord1f)( GLcontext *, int );
struct dynfn *(*TexCoord1fv)( GLcontext *, int );
struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int );
struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int );
};
struct radeon_prim {
GLuint start;
GLuint end;
GLuint prim;
};
struct radeon_vbinfo {
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
GLuint primflags;
GLboolean enabled; /* RADEON_NO_VTXFMT//RADEON_NO_TCL env vars */
GLboolean installed;
GLboolean fell_back;
GLboolean recheck;
GLint initial_counter;
GLint nrverts;
GLuint vertex_format;
GLuint installed_vertex_format;
GLuint installed_color_3f_sz;
struct radeon_prim primlist[RADEON_MAX_PRIMS];
int nrprims;
struct dfn_lists dfn_cache;
struct dfn_generators codegen;
GLvertexformat vtxfmt;
};
extern struct radeon_vb vb;
@@ -125,4 +224,3 @@ struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int );
#endif
#endif

View File

@@ -37,7 +37,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "simple_list.h"
#include "radeon_vtxfmt.h"
#if defined(USE_SSE_ASM)
#if defined(USE_SSE_ASM) && _HAVE_CODEGEN
#include "X86/common_x86_asm.h"
/* Build specialized versions of the immediate calls on the fly for

View File

@@ -1,4 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.29 2002/10/12 01:38:07 martin Exp $ */
/**
* \file server/radeon.h
* \brief Radeon 2D driver data strucures.
*/
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -27,6 +31,8 @@
* DEALINGS IN THE SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.29 2002/10/12 01:38:07 martin Exp $ */
#ifndef _RADEON_H_
#define _RADEON_H_
@@ -58,6 +64,9 @@
#define PCI_CHIP_R200_Ql 0x516C
/**
* \brief Chip families.
*/
typedef enum {
CHIP_FAMILY_UNKNOW,
CHIP_FAMILY_LEGACY,
@@ -74,68 +83,89 @@ typedef enum {
CHIP_FAMILY_R300
} RADEONChipFamily;
typedef unsigned long memType;
/**
* \brief Radeon DDX driver private data.
*/
typedef struct {
int Chipset;
RADEONChipFamily ChipFamily;
int Chipset; /**< \brief Chipset number */
RADEONChipFamily ChipFamily; /**< \brief Chip family */
unsigned long LinearAddr; /* Frame buffer physical address */
unsigned long LinearAddr; /**< \brief Frame buffer physical address */
drmSize registerSize;
drmHandle registerHandle;
drmSize registerSize; /**< \brief MMIO register map size */
drmHandle registerHandle; /**< \brief MMIO register map handle */
drmSize agpSize;
drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
unsigned long agpOffset;
int agpMode;
/**
* \name AGP
*/
/*@{*/
drmSize agpSize; /**< \brief AGP map size */
drmHandle agpMemHandle; /**< \brief AGP map handle */
unsigned long agpOffset; /**< \brief AGP offset */
int agpMode; /**< \brief AGP mode */
int agpFastWrite;
/*@}*/
/* CP ring buffer data */
unsigned long ringStart; /* Offset into AGP space */
drmHandle ringHandle; /* Handle from drmAddMap */
drmSize ringMapSize; /* Size of map */
int ringSize; /* Size of ring (in MB) */
/**
* \name CP ring buffer data
*/
/*@{*/
unsigned long ringStart; /**< \brief Offset into AGP space */
drmHandle ringHandle; /**< \brief Handle from drmAddMap() */
drmSize ringMapSize; /**< \brief Size of map */
int ringSize; /**< \brief Size of ring (in MB) */
unsigned long ringReadOffset; /* Offset into AGP space */
drmHandle ringReadPtrHandle; /* Handle from drmAddMap */
drmSize ringReadMapSize; /* Size of map */
unsigned long ringReadOffset; /**< \brief Read offset into AGP space */
drmHandle ringReadPtrHandle;/**< \brief Handle from drmAddMap() */
drmSize ringReadMapSize; /**< \brief Size of map */
/*@}*/
/* CP vertex/indirect buffer data */
unsigned long bufStart; /* Offset into AGP space */
drmHandle bufHandle; /* Handle from drmAddMap */
drmSize bufMapSize; /* Size of map */
int bufSize; /* Size of buffers (in MB) */
int bufNumBufs; /* Number of buffers */
/**
* \name CP vertex/indirect buffer data
*/
/*@{*/
unsigned long bufStart; /**< \brief Offset into AGP space */
drmHandle bufHandle; /**< \brief Handle from drmAddMap() */
drmSize bufMapSize; /**< \brief Size of map */
int bufSize; /**< \brief Size of buffers (in MB) */
int bufNumBufs; /**< \brief Number of buffers */
/*@}*/
/* CP AGP Texture data */
unsigned long agpTexStart; /* Offset into AGP space */
drmHandle agpTexHandle; /* Handle from drmAddMap */
drmSize agpTexMapSize; /* Size of map */
int agpTexSize; /* Size of AGP tex space (in MB) */
/**
* \name CP AGP Texture data
*/
/*@{*/
unsigned long agpTexStart; /**< \brief Offset into AGP space */
drmHandle agpTexHandle; /**< \brief Handle from drmAddMap() */
drmSize agpTexMapSize; /**< \brief Size of map */
int agpTexSize; /**< \brief Size of AGP tex space (in MB) */
int log2AGPTexGran;
/*@}*/
int drmMinor;
int drmMinor; /**< \brief DRM device minor number */
int frontOffset;
int frontPitch;
int backOffset;
int backPitch;
int depthOffset;
int depthPitch;
int textureOffset;
int textureSize;
int log2TexGran;
int frontOffset; /**< \brief Front color buffer offset */
int frontPitch; /**< \brief Front color buffer pitch */
int backOffset; /**< \brief Back color buffer offset */
int backPitch; /**< \brief Back color buffer pitch */
int depthOffset; /**< \brief Depth buffer offset */
int depthPitch; /**< \brief Depth buffer pitch */
int textureOffset; /**< \brief Texture area offset */
int textureSize; /**< \brief Texture area size */
int log2TexGran; /**< \brief Texture granularity in base 2 log */
unsigned int frontPitchOffset;
unsigned int backPitchOffset;
unsigned int depthPitchOffset;
unsigned int frontPitchOffset;
unsigned int backPitchOffset;
unsigned int depthPitchOffset;
int irq;
unsigned int gen_int_cntl;
unsigned int crtc_offset_cntl;
int irq; /**< \brief IRQ number */
unsigned int gen_int_cntl;
unsigned int crtc_offset_cntl;
} RADEONInfoRec, *RADEONInfoPtr;

View File

@@ -1,5 +1,19 @@
/* radeon_common.h -- common header definitions for Radeon 2D/3D/DRM suite
/**
* \file server/radeon_common.h
* \brief Common header definitions for Radeon 2D/3D/DRM driver suite.
*
* \note Some of these structures are meant for backward compatability and
* aren't used by the subset driver.
*
* \author Gareth Hughes <gareth@valinux.com>
* \author Kevin E. Martin <martin@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*
* \author Converted to common header format by
* Jens Owen <jens@tungstengraphics.com>
*/
/*
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -22,19 +36,10 @@
* 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.
*
* Author:
* Gareth Hughes <gareth@valinux.com>
* Kevin E. Martin <martin@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*
* Converted to common header format:
* Jens Owen <jens@tungstengraphics.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h,v 1.6 2001/04/16 15:02:13 tsi Exp $
*
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h,v 1.6 2001/04/16 15:02:13 tsi Exp $ */
#ifndef _RADEON_COMMON_H_
#define _RADEON_COMMON_H_
@@ -85,33 +90,42 @@
#define RADEON_CLEAR_DEPTH 4
/**
* \brief DRM_RADEON_CP_INIT ioctl argument type.
*/
typedef struct {
enum {
DRM_RADEON_INIT_CP = 0x01,
DRM_RADEON_CLEANUP_CP = 0x02,
DRM_RADEON_INIT_R200_CP = 0x03
} func;
unsigned long sarea_priv_offset;
int is_pci;
int cp_mode;
int agp_size;
int ring_size;
int usec_timeout;
DRM_RADEON_INIT_CP = 0x01, /**< \brief initialize CP */
DRM_RADEON_CLEANUP_CP = 0x02, /**< \brief clean up CP */
DRM_RADEON_INIT_R200_CP = 0x03 /**< \brief initialize R200 CP */
} func; /**< \brief request */
unsigned long sarea_priv_offset; /**< \brief SAREA private offset */
int is_pci; /**< \brief is current card a PCI card? */
int cp_mode; /**< \brief CP mode */
int agp_size; /**< \brief AGP space size */
int ring_size; /**< \brief CP ring buffer size */
int usec_timeout; /**< \brief timeout for DRM operations in usecs */
unsigned int fb_bpp;
unsigned int front_offset, front_pitch;
unsigned int back_offset, back_pitch;
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
unsigned int fb_bpp;
unsigned int front_offset; /**< \brief front color buffer offset */
unsigned int front_pitch; /**< \brief front color buffer pitch */
unsigned int back_offset; /**< \brief back color buffer offset */
unsigned int back_pitch; /**< \brief back color buffer pitch*/
unsigned int depth_bpp; /**< \brief depth buffer bits-per-pixel */
unsigned int depth_offset; /**< \brief depth buffer offset */
unsigned int depth_pitch; /**< \brief depth buffer pitch */
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long ring_offset;
unsigned long ring_rptr_offset;
unsigned long buffers_offset;
unsigned long agp_textures_offset;
unsigned long fb_offset; /**< \brief framebuffer offset */
unsigned long mmio_offset; /**< \brief MMIO register offset */
unsigned long ring_offset; /**< \brief CP ring buffer offset */
unsigned long ring_rptr_offset; /**< \brief CP ring buffer read pointer offset */
unsigned long buffers_offset; /**< \brief vertex buffers offset */
unsigned long agp_textures_offset; /**< \brief AGP textures offset */
} drmRadeonInit;
/**
* \brief DRM_RADEON_CP_STOP ioctl argument type.
*/
typedef struct {
int flush;
int idle;
@@ -129,13 +143,17 @@ typedef union drmRadeonClearR {
unsigned int ui[5];
} drmRadeonClearRect;
/**
* \brief DRM_RADEON_CLEAR ioctl argument type.
*/
typedef struct drmRadeonClearT {
unsigned int flags;
unsigned int clear_color;
unsigned int clear_depth;
unsigned int color_mask;
unsigned int depth_mask; /* misnamed field: should be stencil */
drmRadeonClearRect *depth_boxes;
unsigned int flags; /**< \brief bitmask of the planes to clear */
unsigned int clear_color; /**< \brief color buffer clear value */
unsigned int clear_depth; /**< \brief depth buffer clear value */
unsigned int color_mask; /**< \brief color buffer clear mask */
unsigned int depth_mask; /**< \brief stencil buffer clear value
* \todo Misnamed field. */
drmRadeonClearRect *depth_boxes; /**< \brief depth buffer cliprects */
} drmRadeonClearType;
typedef struct drmRadeonFullscreenT {
@@ -145,10 +163,16 @@ typedef struct drmRadeonFullscreenT {
} func;
} drmRadeonFullscreenType;
/**
* \brief DRM_RADEON_STIPPLE ioctl argument type.
*/
typedef struct {
unsigned int *mask;
} drmRadeonStipple;
/**
* \brief Texture image for drmRadeonTexture.
*/
typedef struct {
unsigned int x;
unsigned int y;
@@ -157,18 +181,22 @@ typedef struct {
const void *data;
} drmRadeonTexImage;
/**
* \brief DRM_RADEON_TEXTURE ioctl argument type.
*/
typedef struct {
int offset;
int pitch;
int format;
int width; /* Texture image coordinates */
int height;
drmRadeonTexImage *image;
int offset; /**< \brief texture offset */
int pitch; /**< \brief texture pitch */
int format; /**< \brief pixel format */
int width; /**< \brief texture width */
int height; /**< \brief texture height */
drmRadeonTexImage *image; /**< \brief image */
} drmRadeonTexture;
#define RADEON_MAX_TEXTURE_UNITS 3
/* Layout matches drm_radeon_state_t in linux drm_radeon.h.
*/
typedef struct {
@@ -238,13 +266,16 @@ typedef struct {
unsigned int dirty;
} drmRadeonState;
/* 1.1 vertex ioctl. Used in compatibility modes.
/**
* \brief DRM 1.1 vertex ioctl.
*
* Used in compatibility modes.
*/
typedef struct {
int prim;
int idx; /* Index of vertex buffer */
int count; /* Number of vertices in buffer */
int discard; /* Client finished with buffer? */
int prim; /**< \brief Primitive number */
int idx; /**< \brief Index of vertex buffer */
int count; /**< \brief Number of vertices in buffer */
int discard; /**< \brief Client finished with buffer? */
} drmRadeonVertex;
typedef struct {
@@ -252,13 +283,13 @@ typedef struct {
unsigned int finish;
unsigned int prim:8;
unsigned int stateidx:8;
unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
unsigned int numverts:16; /**< overloaded as offset/64 for elt prims */
unsigned int vc_format;
} drmRadeonPrim;
typedef struct {
int idx; /* Index of vertex buffer */
int discard; /* Client finished with buffer? */
int idx; /**< \brief Index of vertex buffer */
int discard; /**< \brief Client finished with buffer? */
int nr_states;
drmRadeonState *state;
int nr_prims;
@@ -268,124 +299,156 @@ typedef struct {
#define RADEON_MAX_STATES 16
#define RADEON_MAX_PRIMS 64
/* Command buffer. Replace with true dma stream?
/**
* \brief Command buffer.
*
* \todo Replace with true DMA stream?
*/
typedef struct {
int bufsz;
char *buf;
int nbox;
drmClipRect *boxes;
int bufsz; /**< \brief buffer size */
char *buf; /**< \brief buffer */
int nbox; /**< \brief number of cliprects */
drmClipRect *boxes; /**< \brief cliprects */
} drmRadeonCmdBuffer;
/* New style per-packet identifiers for use in cmd_buffer ioctl with
* the RADEON_EMIT_PACKET command. Comments relate new packets to old
* state bits and the packet size:
/**
* \brief Per-packet identifiers for use with the ::RADEON_CMD_PACKET command
* in the DRM_RADEON_CMDBUF ioctl.
*
* \note Comments relate new packets to old state bits and the packet size.
*/
#define RADEON_EMIT_PP_MISC 0 /* context/7 */
#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/6 */
#define R200_EMIT_TFACTOR_0 30 /* tf/6 */
#define R200_EMIT_VTX_FMT_0 31 /* vtx/4 */
#define R200_EMIT_VAP_CTL 32 /* vap/1 */
#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
#define R200_EMIT_PP_CUBIC_FACES_0 61
#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
#define R200_EMIT_PP_CUBIC_FACES_1 63
#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
#define R200_EMIT_PP_CUBIC_FACES_2 65
#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
#define R200_EMIT_PP_CUBIC_FACES_3 67
#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
#define R200_EMIT_PP_CUBIC_FACES_4 69
#define R200_EMIT_PP_CUBIC_OFFSETS_4 70
#define R200_EMIT_PP_CUBIC_FACES_5 71
#define R200_EMIT_PP_CUBIC_OFFSETS_5 72
#define RADEON_MAX_STATE_PACKETS 73
enum drmRadeonCmdPkt {
RADEON_EMIT_PP_MISC = 0, /* context/7 */
RADEON_EMIT_PP_CNTL = 1, /* context/3 */
RADEON_EMIT_RB3D_COLORPITCH = 2, /* context/1 */
RADEON_EMIT_RE_LINE_PATTERN = 3, /* line/2 */
RADEON_EMIT_SE_LINE_WIDTH = 4, /* line/1 */
RADEON_EMIT_PP_LUM_MATRIX = 5, /* bumpmap/1 */
RADEON_EMIT_PP_ROT_MATRIX_0 = 6, /* bumpmap/2 */
RADEON_EMIT_RB3D_STENCILREFMASK = 7, /* masks/3 */
RADEON_EMIT_SE_VPORT_XSCALE = 8, /* viewport/6 */
RADEON_EMIT_SE_CNTL = 9, /* setup/2 */
RADEON_EMIT_SE_CNTL_STATUS = 10, /* setup/1 */
RADEON_EMIT_RE_MISC = 11, /* misc/1 */
RADEON_EMIT_PP_TXFILTER_0 = 12, /* tex0/6 */
RADEON_EMIT_PP_BORDER_COLOR_0 = 13, /* tex0/1 */
RADEON_EMIT_PP_TXFILTER_1 = 14, /* tex1/6 */
RADEON_EMIT_PP_BORDER_COLOR_1 = 15, /* tex1/1 */
RADEON_EMIT_PP_TXFILTER_2 = 16, /* tex2/6 */
RADEON_EMIT_PP_BORDER_COLOR_2 = 17, /* tex2/1 */
RADEON_EMIT_SE_ZBIAS_FACTOR = 18, /* zbias/2 */
RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT = 19, /* tcl/11 */
RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED = 20, /* material/17 */
R200_EMIT_PP_TXCBLEND_0 = 21, /* tex0/4 */
R200_EMIT_PP_TXCBLEND_1 = 22, /* tex1/4 */
R200_EMIT_PP_TXCBLEND_2 = 23, /* tex2/4 */
R200_EMIT_PP_TXCBLEND_3 = 24, /* tex3/4 */
R200_EMIT_PP_TXCBLEND_4 = 25, /* tex4/4 */
R200_EMIT_PP_TXCBLEND_5 = 26, /* tex5/4 */
R200_EMIT_PP_TXCBLEND_6 = 27, /* /4 */
R200_EMIT_PP_TXCBLEND_7 = 28, /* /4 */
R200_EMIT_TCL_LIGHT_MODEL_CTL_0 = 29, /* tcl/6 */
R200_EMIT_TFACTOR_0 = 30, /* tf/6 */
R200_EMIT_VTX_FMT_0 = 31, /* vtx/4 */
R200_EMIT_VAP_CTL = 32, /* vap/1 */
R200_EMIT_MATRIX_SELECT_0 = 33, /* msl/5 */
R200_EMIT_TEX_PROC_CTL_2 = 34, /* tcg/5 */
R200_EMIT_TCL_UCP_VERT_BLEND_CTL = 35, /* tcl/1 */
R200_EMIT_PP_TXFILTER_0 = 36, /* tex0/6 */
R200_EMIT_PP_TXFILTER_1 = 37, /* tex1/6 */
R200_EMIT_PP_TXFILTER_2 = 38, /* tex2/6 */
R200_EMIT_PP_TXFILTER_3 = 39, /* tex3/6 */
R200_EMIT_PP_TXFILTER_4 = 40, /* tex4/6 */
R200_EMIT_PP_TXFILTER_5 = 41, /* tex5/6 */
R200_EMIT_PP_TXOFFSET_0 = 42, /* tex0/1 */
R200_EMIT_PP_TXOFFSET_1 = 43, /* tex1/1 */
R200_EMIT_PP_TXOFFSET_2 = 44, /* tex2/1 */
R200_EMIT_PP_TXOFFSET_3 = 45, /* tex3/1 */
R200_EMIT_PP_TXOFFSET_4 = 46, /* tex4/1 */
R200_EMIT_PP_TXOFFSET_5 = 47, /* tex5/1 */
R200_EMIT_VTE_CNTL = 48, /* vte/1 */
R200_EMIT_OUTPUT_VTX_COMP_SEL = 49, /* vtx/1 */
R200_EMIT_PP_TAM_DEBUG3 = 50, /* tam/1 */
R200_EMIT_PP_CNTL_X = 51, /* cst/1 */
R200_EMIT_RB3D_DEPTHXY_OFFSET = 52, /* cst/1 */
R200_EMIT_RE_AUX_SCISSOR_CNTL = 53, /* cst/1 */
R200_EMIT_RE_SCISSOR_TL_0 = 54, /* cst/2 */
R200_EMIT_RE_SCISSOR_TL_1 = 55, /* cst/2 */
R200_EMIT_RE_SCISSOR_TL_2 = 56, /* cst/2 */
R200_EMIT_SE_VAP_CNTL_STATUS = 57, /* cst/1 */
R200_EMIT_SE_VTX_STATE_CNTL = 58, /* cst/1 */
R200_EMIT_RE_POINTSIZE = 59, /* cst/1 */
R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 = 60, /* cst/4 */
R200_EMIT_PP_CUBIC_FACES_0 = 61,
R200_EMIT_PP_CUBIC_OFFSETS_0 = 62,
R200_EMIT_PP_CUBIC_FACES_1 = 63,
R200_EMIT_PP_CUBIC_OFFSETS_1 = 64,
R200_EMIT_PP_CUBIC_FACES_2 = 65,
R200_EMIT_PP_CUBIC_OFFSETS_2 = 66,
R200_EMIT_PP_CUBIC_FACES_3 = 67,
R200_EMIT_PP_CUBIC_OFFSETS_3 = 68,
R200_EMIT_PP_CUBIC_FACES_4 = 69,
R200_EMIT_PP_CUBIC_OFFSETS_4 = 70,
R200_EMIT_PP_CUBIC_FACES_5 = 71,
R200_EMIT_PP_CUBIC_OFFSETS_5 = 72,
RADEON_MAX_STATE_PACKETS = 73
} ;
/* Commands understood by cmd_buffer ioctl. More can be added but
* obviously these can't be removed or changed:
/**
* \brief Command types understood by the DRM_RADEON_CMDBUF ioctl.
*
* More can be added but obviously these can't be removed or changed.
*
* \sa drmRadeonCmdHeader.
*/
#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
#define RADEON_CMD_SCALARS 2 /* emit scalar data */
#define RADEON_CMD_VECTORS 3 /* emit vector data */
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
#define RADEON_CMD_PACKET3 5 /* emit hw packet */
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
#define RADEON_CMD_SCALARS2 7 /* R200 stopgap */
#define RADEON_CMD_WAIT 8 /* synchronization */
enum drmRadeonCmdType {
RADEON_CMD_PACKET = 1, /**< \brief emit one of the ::drmRadeonCmdPkt register packets */
RADEON_CMD_SCALARS = 2, /**< \brief emit scalar data */
RADEON_CMD_VECTORS = 3, /**< \brief emit vector data */
RADEON_CMD_DMA_DISCARD = 4, /**< \brief discard current DMA buffer */
RADEON_CMD_PACKET3 = 5, /**< \brief emit hardware packet */
RADEON_CMD_PACKET3_CLIP = 6, /**< \brief emit hardware packet wrapped in cliprects */
RADEON_CMD_SCALARS2 = 7, /**< \brief R200 stopgap */
RADEON_CMD_WAIT = 8 /**< \brief synchronization */
} ;
/**
* \brief Commands understood by the DRM_RADEON_CMDBUF ioctl.
*
* \sa drmRadeonCmdType.
*/
typedef union {
/** \brief integer equivalent */
int i;
struct {
unsigned char cmd_type, pad0, pad1, pad2;
} header;
/** \brief emit a register packet */
struct {
unsigned char cmd_type, packet_id, pad0, pad1;
} packet;
/** \brief scalar data */
struct {
unsigned char cmd_type, offset, stride, count;
} scalars;
/** \brief vector data */
struct {
unsigned char cmd_type, offset, stride, count;
} vectors;
/** \brief discard current DMA buffer */
struct {
unsigned char cmd_type, buf_idx, pad0, pad1;
} dma;
/** \brief synchronization */
struct {
unsigned char cmd_type, flags, pad0, pad1;
} wait;
@@ -395,10 +458,12 @@ typedef union {
#define RADEON_WAIT_2D 0x1
#define RADEON_WAIT_3D 0x2
/**
* \brief DRM_RADEON_GETPARAM ioctl argument type.
*/
typedef struct drm_radeon_getparam {
int param;
int *value;
int param; /**< \brief parameter number */
int *value; /**< \brief parameter value */
} drmRadeonGetParam;
#define RADEON_PARAM_AGP_BUFFER_OFFSET 1
@@ -424,18 +489,29 @@ typedef struct drm_radeon_mem_free {
int region_offset;
} drmRadeonMemFree;
/**
* \brief DRM_RADEON_INIT_HEAP argument type.
*/
typedef struct drm_radeon_mem_init_heap {
int region;
int size;
int start;
int region; /**< \brief region type */
int size; /**< \brief region size */
int start; /**< \brief region start offset */
} drmRadeonMemInitHeap;
/* 1.6: Userspace can request & wait on irq's:
/**
* \brief DRM_RADEON_IRQ_EMIT ioctl argument type.
*
* New in DRM 1.6: userspace can request and wait on IRQ's.
*/
typedef struct drm_radeon_irq_emit {
int *irq_seq;
} drmRadeonIrqEmit;
/**
* \brief DRM_RADEON_IRQ_WAIT ioctl argument type.
*
* New in DRM 1.6: userspace can request and wait on IRQ's.
*/
typedef struct drm_radeon_irq_wait {
int irq_seq;
} drmRadeonIrqWait;

View File

@@ -1,3 +1,13 @@
/**
* \file server/radeon_dri.c
* \brief File to perform the device-specific initialization tasks typically
* done in the X server.
*
* Here they are converted to run in the client (or perhaps a standalone
* process), and to work with the frambe buffer device rather than the X
* server infrastructure.
*/
#include <stdio.h>
#include <errno.h>
@@ -10,17 +20,10 @@
#include "radeon_sarea.h"
#include "sarea.h"
#include <unistd.h>
/* File to perform the device-specfic initialization tasks typically
* done in the X server.
*
* Here they are converted to run in the client (or perhaps a
* standalone process), and to work with fbdev rather than the X
* server infrastructure.
*/
/* HACK - for now, put this here... */
/* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
#if defined(__alpha__)
@@ -32,7 +35,15 @@
#endif
/**
* \brief Wait for free FIFO entries.
*
* \param dpy display handle.
* \param entries number of free entries to wait.
*
* It polls the free entries from the chip until it reaches the requested value
* or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
*/
static void RADEONWaitForFifo( struct MiniGLXDisplayRec *dpy,
int entries )
{
@@ -54,6 +65,14 @@ static void RADEONWaitForFifo( struct MiniGLXDisplayRec *dpy,
exit(1);
}
/**
* \brief Read a PLL register.
*
* \param dpy display handle.
* \param addr PLL register index.
*
* \return value of the PLL register.
*/
static unsigned int RADEONINPLL( struct MiniGLXDisplayRec *dpy, int addr)
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
@@ -65,7 +84,13 @@ static unsigned int RADEONINPLL( struct MiniGLXDisplayRec *dpy, int addr)
return data;
}
/* Reset graphics card to known state */
/**
* \brief Reset graphics card to known state.
*
* \param dpy display handle.
*
* Resets the values of several Radeon registers.
*/
static void RADEONEngineReset( struct MiniGLXDisplayRec *dpy )
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
@@ -130,8 +155,17 @@ static void RADEONEngineReset( struct MiniGLXDisplayRec *dpy )
OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
}
static int RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
RADEONInfoPtr info )
/**
* \brief Restore the drawing engine.
*
* \param dpy display handle
* \param info driver private data.
*
* Resets the graphics card and sets initial values for several registers of
* the card's drawing engine.
*/
static void RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
RADEONInfoPtr info )
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
@@ -143,7 +177,7 @@ static int RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
switch (dpy->bpp) {
case 16: datatype = 4; break;
case 32: datatype = 6; break;
default: return 0;
default: return;
}
dp_gui_master_cntl =
@@ -182,7 +216,13 @@ static int RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
usleep(100);
}
/* Compute log base 2 of val */
/**
* \brief Compute base 2 logarithm.
*
* \param val value.
*
* \return base 2 logarithm of \p val.
*/
static int RADEONMinBits(int val)
{
int bits;
@@ -192,8 +232,17 @@ static int RADEONMinBits(int val)
return bits;
}
/* Initialize the AGP state. Request memory for use in AGP space, and
* initialize the Radeon registers to point to that memory.
/**
* \brief Initialize the AGP state
*
* \param dpy display handle.
* \param info driver private data.
*
* \return one on sucess, or zero on failure.
*
* Acquires and enables the AGP device. Reserves memory in the AGP space for
* the ring buffer, vertex buffers and textures. Initialize the Radeon
* registers to point to that memory and add client mappings.
*/
static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info)
{
@@ -241,7 +290,7 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info)
}
fprintf(stderr,
"[agp] %d kB allocated with handle 0x%08x\n",
info->agpSize*1024, info->agpMemHandle);
info->agpSize*1024, (unsigned)info->agpMemHandle);
if (drmAgpBind(dpy->drmFD,
info->agpMemHandle, info->agpOffset) < 0) {
@@ -317,8 +366,17 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info)
}
/* Initialize the kernel data structures */
/**
* \brief Initialize the kernel data structures and enable the CP engine.
*
* \param dpy display handle.
* \param info driver private data.
*
* \return non-zero on sucess, or zero on failure.
*
* This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
* all the parameters in a drmRadeonInit structure.
*/
static int RADEONDRIKernelInit(struct MiniGLXDisplayRec *dpy,
RADEONInfoPtr info)
{
@@ -363,6 +421,16 @@ static int RADEONDRIKernelInit(struct MiniGLXDisplayRec *dpy,
return ret >= 0;
}
/**
* \brief Initialize the AGP heap.
*
* \param dpy display handle.
* \param info driver private data.
*
* This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
* all the parameters in a drm_radeon_mem_init_heap structure.
*/
static void RADEONDRIAgpHeapInit(struct MiniGLXDisplayRec *dpy,
RADEONInfoPtr info)
{
@@ -384,8 +452,16 @@ static void RADEONDRIAgpHeapInit(struct MiniGLXDisplayRec *dpy,
}
}
/* Add a map for the vertex buffers that will be accessed by any
/**
* \brief Add a map for the vertex buffers that will be accessed by any
* DRI-based clients.
*
* \param dpy display handle.
* \param info driver private data.
*
* \return one on sucess, or zero on failure.
*
* Calls drmAddBufs() with the previously allocated vertex buffers.
*/
static int RADEONDRIBufInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
{
@@ -408,6 +484,15 @@ static int RADEONDRIBufInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
return 1;
}
/**
* \brief Install an IRQ handler.
*
* \param dpy display handle.
* \param info driver private data.
*
* Attemps to install an IRQ handler via drmCtlInstHandler(), falling back to
* IRQ-free operation on failure.
*/
static void RADEONDRIIrqInit(struct MiniGLXDisplayRec *dpy,
RADEONInfoPtr info)
{
@@ -434,11 +519,26 @@ static void RADEONDRIIrqInit(struct MiniGLXDisplayRec *dpy,
/* Called at the start of each server generation. */
/**
* Called at the start of each server generation.
*
* \param dpy display handle.
* \param info driver private data.
*
* \return non-zero on sucess, or zero on failure.
*
* Performs static frame buffer allocation. Opens the DRM device and add maps
* to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
* information. Creates a \e server context to grab the lock for the
* initialization ioctls and calls the other initliaztion functions in this
* file. Starts the CP engine via the DRM_RADEON_CP_START command.
*
* Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
* initialization.
*/
static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
{
RADEONDRIPtr pRADEONDRI;
int major, minor, patch;
drmVersionPtr version;
int err;
@@ -592,7 +692,6 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
+ RADEON_BUFFER_ALIGN)
& ~RADEON_BUFFER_ALIGN);
int l;
int scanlines;
info->frontOffset = 0;
info->frontPitch = dpy->virtualWidth;
@@ -755,7 +854,19 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
}
static void get_chipfamily_from_chipset( RADEONInfoPtr info )
/**
* \brief Get Radeon chip family from chipset number.
*
* \param driver private data.
*
* \return non-zero on sucess, or zero on failure.
*
* Called by __driInitFBDev() to set RADEONInfoRec::ChipFamily
* according to the value of RADEONInfoRec::Chipset. Fails if the
* chipset is unrecognized or not appropriate for this driver (ie. not
* an r100 style radeon)
*/
static int get_chipfamily_from_chipset( RADEONInfoPtr info )
{
switch (info->Chipset) {
case PCI_CHIP_RADEON_LY:
@@ -768,14 +879,6 @@ static void get_chipfamily_from_chipset( RADEONInfoPtr info )
info->ChipFamily = CHIP_FAMILY_VE;
break;
case PCI_CHIP_R200_QL:
case PCI_CHIP_R200_QN:
case PCI_CHIP_R200_QO:
case PCI_CHIP_R200_Ql:
/* case PCI_CHIP_R200_BB: */
info->ChipFamily = CHIP_FAMILY_R200;
break;
case PCI_CHIP_RV200_QW: /* RV200 desktop */
case PCI_CHIP_RV200_QX:
info->ChipFamily = CHIP_FAMILY_RV200;
@@ -786,39 +889,55 @@ static void get_chipfamily_from_chipset( RADEONInfoPtr info )
info->ChipFamily = CHIP_FAMILY_M7;
break;
/* case PCI_CHIP_RV250_Id: */
/* case PCI_CHIP_RV250_Ie: */
/* case PCI_CHIP_RV250_If: */
/* case PCI_CHIP_RV250_Ig: */
/* info->ChipFamily = CHIP_FAMILY_RV250; */
/* break; */
case PCI_CHIP_RADEON_QD:
case PCI_CHIP_RADEON_QE:
case PCI_CHIP_RADEON_QF:
case PCI_CHIP_RADEON_QG:
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
break;
case PCI_CHIP_R200_QL:
case PCI_CHIP_R200_QN:
case PCI_CHIP_R200_QO:
case PCI_CHIP_R200_Ql: /* r200 */
return 0;
case PCI_CHIP_RV250_Ld:
case PCI_CHIP_RV250_Le:
case PCI_CHIP_RV250_Lf:
case PCI_CHIP_RV250_Lg:
info->ChipFamily = CHIP_FAMILY_M9;
break;
case PCI_CHIP_RV250_Lg: /* m9 */
return 0;
case PCI_CHIP_R300_ND:
case PCI_CHIP_R300_NE:
case PCI_CHIP_R300_NF:
case PCI_CHIP_R300_NG:
info->ChipFamily = CHIP_FAMILY_R300;
break;
case PCI_CHIP_R300_NG: /* r300 */
return 0;
default:
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
return 0;
}
return 1;
}
/**
* Establish the set of visuals available for the display.
* Requires the ::__GLXvisualConfig data type.
* \brief Establish the set of visuals available for the display.
*
* \param dpy display handle.
* \param numConfigs will receive the number of supported visuals.
* \param configs will point to the list of supported visuals.
*
* \return one on sucess, or zero on failure.
*
* \note Requires the ::__GLXvisualConfig data type.
*
* Allocates a single visual and fills it with information according to the
* display bit depth. Supports only 16 and 32 bpp bit depths, aborting
* otherwise.
*/
static int __driInitScreenConfigs( struct MiniGLXDisplayRec *dpy,
int *numConfigs, __GLXvisualConfig **configs)
@@ -888,13 +1007,23 @@ static int __driInitScreenConfigs( struct MiniGLXDisplayRec *dpy,
return 1;
}
/**
* \brief Validate the fbdev mode.
*
* \param dpy display handle.
*
* \return one on success, or zero on failure.
*
* Saves some registers and returns 1.
*
* \sa __driValidateMode().
*/
static int __driValidateMode( struct MiniGLXDisplayRec *dpy )
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
RADEONInfoPtr info = dpy->driverInfo;
/* Save some regs here:
*/
info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
@@ -902,20 +1031,40 @@ static int __driValidateMode( struct MiniGLXDisplayRec *dpy )
}
/**
* \brief Examine mode returned by fbdev.
*
* \param dpy display handle.
*
* \return one on success, or zero on failure.
*
* Restores registers that fbdev has clobbered and returns 1.
*
* \sa __driValidateMode().
*/
static int __driPostValidateMode( struct MiniGLXDisplayRec *dpy )
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
RADEONInfoPtr info = dpy->driverInfo;
/* Restore registers that fbdev has clobbered.
*/
OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
return 1;
}
/*
/**
* \brief Initialize the framebuffer device mode
*
* \param dpy display handle.
*
* \return one on success, or zero on failure.
*
* Fills in \p info with some default values and some information from \p dpy
* and then calls RADEONScreenInit() for the screen initialization.
*
* Before exiting clears the framebuffer memomry accessing it directly.
*/
static int __driInitFBDev( struct MiniGLXDisplayRec *dpy )
{
@@ -944,7 +1093,11 @@ static int __driInitFBDev( struct MiniGLXDisplayRec *dpy )
info->ringSize = RADEON_DEFAULT_RING_SIZE;
info->Chipset = dpy->chipset;
get_chipfamily_from_chipset( info );
if (!get_chipfamily_from_chipset( info )) {
fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n");
return 0;
}
info->frontPitch = dpy->virtualWidth;
info->LinearAddr = dpy->FixedInfo.smem_start & 0xfc000000;
@@ -970,9 +1123,14 @@ static int __driInitFBDev( struct MiniGLXDisplayRec *dpy )
}
/* The screen is being closed, so clean up any state and free any
/**
* \brief The screen is being closed, so clean up any state and free any
* resources used by the DRI.
*
* \param dpy display handle.
*
* Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
* private data.
*/
static void __driHaltFBDev( struct MiniGLXDisplayRec *dpy )
{
@@ -986,7 +1144,11 @@ static void __driHaltFBDev( struct MiniGLXDisplayRec *dpy )
}
/**
* \brief Exported driver interface for Mini GLX.
*
* \sa MiniGLXDriverRec.
*/
struct MiniGLXDriverRec __driMiniGLXDriver = {
__driInitScreenConfigs,
__driValidateMode,
@@ -994,4 +1156,3 @@ struct MiniGLXDriverRec __driMiniGLXDriver = {
__driInitFBDev,
__driHaltFBDev
};

View File

@@ -1,4 +1,11 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h,v 1.3 2002/04/24 16:20:40 martin Exp $ */
/**
* \file server/radeon_dri.h
* \brief Radeon server-side structures.
*
* \author Kevin E. Martin <martin@xfree86.org>
* \author Rickard E. Faith <faith@valinux.com>
*/
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario,
* VA Linux Systems Inc., Fremont, California.
@@ -27,12 +34,7 @@
* DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Kevin E. Martin <martin@xfree86.org>
* Rickard E. Faith <faith@valinux.com>
*
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h,v 1.3 2002/04/24 16:20:40 martin Exp $ */
#ifndef _RADEON_DRI_
#define _RADEON_DRI_
@@ -52,42 +54,61 @@
#define RADEON_DEFAULT_CP_TIMEOUT 10000 /* usecs */
#define RADEON_BUFFER_ALIGN 0x00000fff
/**
* \brief Radeon DRI driver private data.
*/
typedef struct {
/* DRI screen private data */
int deviceID; /* PCI device ID */
int width; /* Width in pixels of display */
int height; /* Height in scanlines of display */
int depth; /* Depth of display (8, 15, 16, 24) */
int bpp; /* Bit depth of display (8, 16, 24, 32) */
/**
* \name DRI screen private data
*/
/*@{*/
int deviceID; /**< \brief PCI device ID */
int width; /**< \brief width in pixels of display */
int height; /**< \brief height in scanlines of display */
int depth; /**< \brief depth of display (8, 15, 16, 24) */
int bpp; /**< \brief bit depth of display (8, 16, 24, 32) */
int IsPCI; /* Current card is a PCI card */
int AGPMode;
int IsPCI; /**< \brief is current card a PCI card? */
int AGPMode; /**< \brief AGP mode */
int frontOffset; /* Start of front buffer */
int frontPitch;
int backOffset; /* Start of shared back buffer */
int backPitch;
int depthOffset; /* Start of shared depth buffer */
int depthPitch;
int textureOffset;/* Start of texture data in frame buffer */
int textureSize;
int log2TexGran;
int frontOffset; /**< \brief front buffer offset */
int frontPitch; /**< \brief front buffer pitch */
int backOffset; /**< \brief shared back buffer offset */
int backPitch; /**< \brief shared back buffer pitch */
int depthOffset; /**< \brief shared depth buffer offset */
int depthPitch; /**< \brief shared depth buffer pitch */
int textureOffset; /**< \brief start of texture data in frame buffer */
int textureSize; /**< \brief size of texture date */
int log2TexGran; /**< \brief log2 texture granularity */
/*@}*/
/* MMIO register data */
drmHandle registerHandle;
drmSize registerSize;
/**
* \name MMIO register data
*/
/*@{*/
drmHandle registerHandle; /**< \brief MMIO register map size */
drmSize registerSize; /**< \brief MMIO register map handle */
/*@}*/
/* CP in-memory status information */
drmHandle statusHandle;
drmSize statusSize;
/**
* \name CP in-memory status information
*/
/*@{*/
drmHandle statusHandle; /**< \brief status map handle */
drmSize statusSize; /**< \brief status map size */
/*@}*/
/* CP AGP Texture data */
drmHandle agpTexHandle;
drmSize agpTexMapSize;
int log2AGPTexGran;
int agpTexOffset;
unsigned int sarea_priv_offset;
/**
* \name CP AGP Texture data
*/
/*@{*/
drmHandle agpTexHandle; /**< \brief AGP texture area map handle */
drmSize agpTexMapSize; /**< \brief AGP texture area map size */
int log2AGPTexGran; /**< \brief AGP texture granularity in log base 2 */
int agpTexOffset; /**< \brief AGP texture area offset in AGP space */
/*@}*/
unsigned int sarea_priv_offset; /**< \brief offset of the private SAREA data*/
} RADEONDRIRec, *RADEONDRIPtr;
#endif

View File

@@ -1,4 +1,12 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */
/**
* \file server/radeon_macros.h
* \brief Macros for Radeon MMIO operation.
*
* \authors Kevin E. Martin <martin@xfree86.org>
* \authors Rickard E. Faith <faith@valinux.com>
* \authors Alan Hourihane <alanh@fairlite.demon.co.uk>
*/
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -27,25 +35,7 @@
* DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Kevin E. Martin <martin@xfree86.org>
* Rickard E. Faith <faith@valinux.com>
* Alan Hourihane <alanh@fairlite.demon.co.uk>
*
* References:
*
* !!!! FIXME !!!!
* RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
* Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
* 1999.
*
* !!!! FIXME !!!!
* RAGE 128 Software Development Manual (Technical Reference Manual P/N
* SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
*
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */
#ifndef _RADEON_MACROS_H_
#define _RADEON_MACROS_H_

View File

@@ -1,4 +1,24 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */
/**
* \file server/radeon_reg.h
* \brief Registers and register definitions for the Radeon.
*
* \authors Kevin E. Martin <martin@xfree86.org>
* \authors Rickard E. Faith <faith@valinux.com>
* \authors Alan Hourihane <alanh@fairlite.demon.co.uk>
*
* \par References
*
* - RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
* Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
* 1999.
* - RAGE 128 Software Development Manual (Technical Reference Manual P/N
* SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
*
* \note !!!! FIXME !!!! THIS FILE HAS BEEN CONVERTED FROM r128_reg.h
* AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT
* ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED!
*/
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -27,28 +47,7 @@
* DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Kevin E. Martin <martin@xfree86.org>
* Rickard E. Faith <faith@valinux.com>
* Alan Hourihane <alanh@fairlite.demon.co.uk>
*
* References:
*
* !!!! FIXME !!!!
* RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
* Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
* 1999.
*
* !!!! FIXME !!!!
* RAGE 128 Software Development Manual (Technical Reference Manual P/N
* SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
*
*/
/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h
* AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT
* ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */
#ifndef _RADEON_REG_H_
#define _RADEON_REG_H_

View File

@@ -1,4 +1,11 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.4 2002/04/24 16:20:41 martin Exp $ */
/**
* \file server/radeon_sarea.h
* \brief SAREA definition.
*
* \author Kevin E. Martin <martin@xfree86.org>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario,
* VA Linux Systems Inc., Fremont, California.
@@ -27,12 +34,7 @@
* DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Kevin E. Martin <martin@xfree86.org>
* Gareth Hughes <gareth@valinux.com>
*
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.4 2002/04/24 16:20:41 martin Exp $ */
#ifndef _RADEON_SAREA_H_
#define _RADEON_SAREA_H_
@@ -113,6 +115,10 @@
#endif /* __RADEON_SAREA_DEFINES__ */
/**
* \brief Color register format.
*/
typedef struct {
unsigned int red;
unsigned int green;
@@ -120,8 +126,15 @@ typedef struct {
unsigned int alpha;
} radeon_color_regs_t;
/**
* \brief Context registers.
*/
typedef struct {
/* Context state */
/**
* \name Context state
*/
/*@{*/
unsigned int pp_misc;
unsigned int pp_fog_color;
unsigned int re_solid_color;
@@ -136,44 +149,76 @@ typedef struct {
unsigned int re_width_height;
unsigned int rb3d_colorpitch;
unsigned int se_cntl;
/*@}*/
/* Vertex format state */
/**
* \name Vertex format state
*/
/*@{*/
unsigned int se_coord_fmt;
/*@}*/
/* Line state */
/**
* \name Line state
*/
/*@{*/
unsigned int re_line_pattern;
unsigned int re_line_state;
unsigned int se_line_width;
/*@}*/
/* Bumpmap state */
/**
* \name Bumpmap state
*/
/*@{*/
unsigned int pp_lum_matrix;
unsigned int pp_rot_matrix_0;
unsigned int pp_rot_matrix_1;
/*@}*/
/* Mask state */
/**
* \name Mask state
*/
/*@{*/
unsigned int rb3d_stencilrefmask;
unsigned int rb3d_ropcntl;
unsigned int rb3d_planemask;
/*@}*/
/* Viewport state */
/**
* \name Viewport state
*/
/*@{*/
unsigned int se_vport_xscale;
unsigned int se_vport_xoffset;
unsigned int se_vport_yscale;
unsigned int se_vport_yoffset;
unsigned int se_vport_zscale;
unsigned int se_vport_zoffset;
/*@}*/
/* Setup state */
/**
* \name Setup state
*/
/*@{*/
unsigned int se_cntl_status;
/*@}*/
/* Misc state */
/**
* \name Misc state
*/
/*@{*/
unsigned int re_top_left;
unsigned int re_misc;
/*@}*/
} radeon_context_regs_t;
/* Setup registers for each texture unit */
/**
* \brief Setup registers for each texture unit
*/
typedef struct {
unsigned int pp_txfilter;
unsigned int pp_txformat;
@@ -184,54 +229,82 @@ typedef struct {
unsigned int pp_border_color;
} radeon_texture_regs_t;
/**
* \brief Maintain an LRU of contiguous regions of texture space.
*
* If you think you own a region of texture memory, and it has an age different
* to the one you set, then you are mistaken and it has been stolen by another
* client. If global RADEONSAREAPriv::texAge hasn't changed, there is no need to walk the list.
*
* These regions can be used as a proxy for the fine-grained texture
* information of other clients - by maintaining them in the same LRU which is
* used to age their own textures, clients have an approximate LRU for the
* whole of global texture space, and can make informed decisions as to which
* areas to kick out. There is no need to choose whether to kick out your own
* texture or someone else's - simply eject them all in LRU order.
*
* \sa RADEONSAREAPriv::texList.
*/
typedef struct {
unsigned char next, prev; /* indices to form a circular LRU */
unsigned char in_use; /* owned by a client, or free? */
int age; /* tracked by clients to update local LRU's */
unsigned char next; /**< \brief indices to form a circular LRU */
unsigned char prev; /**< \brief indices to form a circular LRU */
unsigned char in_use; /**< \brief owned by a client, or free? */
int age; /**< \brief tracked by clients to update local LRU's */
} radeon_tex_region_t;
/**
* \brief Private SAREA definition
*
* The channel for communication of state information to the kernel
* on firing a vertex buffer.
*/
typedef struct {
/* The channel for communication of state information to the kernel
* on firing a vertex buffer.
*/
radeon_context_regs_t ContextState;
radeon_context_regs_t ContextState; /** \brief Context registers */
radeon_texture_regs_t TexState[RADEON_MAX_TEXTURE_UNITS];
unsigned int dirty;
unsigned int vertsize;
unsigned int vc_format;
/**< \brief Texture registers */
unsigned int dirty;
unsigned int vertsize; /**< \brief vertex size */
unsigned int vc_format; /**< \brief vertex format */
/* The current cliprects, or a subset thereof */
XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS];
unsigned int nbox;
/* Counters for throttling of rendering clients */
unsigned int last_frame;
unsigned int last_dispatch;
unsigned int last_clear;
/* Maintain an LRU of contiguous regions of texture space. If you
* think you own a region of texture memory, and it has an age
* different to the one you set, then you are mistaken and it has
* been stolen by another client. If global texAge hasn't changed,
* there is no need to walk the list.
/**
* \name Cliprects
*
* These regions can be used as a proxy for the fine-grained texture
* information of other clients - by maintaining them in the same
* lru which is used to age their own textures, clients have an
* approximate lru for the whole of global texture space, and can
* make informed decisions as to which areas to kick out. There is
* no need to choose whether to kick out your own texture or someone
* else's - simply eject them all in LRU order.
* The current cliprects, or a subset thereof.
*/
/* Last elt is sentinal */
radeon_tex_region_t texList[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
/* last time texture was uploaded */
int texAge[RADEON_NR_TEX_HEAPS];
/*@{*/
XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS];
/**< \brief cliprects */
unsigned int nbox; /**< \brief number of cliprects */
/*@}*/
int ctxOwner; /* last context to upload state */
int pfAllowPageFlip; /* set by the 2d driver, read by the client */
int pfCurrentPage; /* set by kernel, read by others */
int crtc2_base; /* for pageflipping with CloneMode */
/**
* \name Counters
*
* Counters for throttling rendering of clients.
*/
/*@{*/
unsigned int last_frame; /**< \brief last emmited frame */
unsigned int last_dispatch;
unsigned int last_clear; /**< \brief last emmited clear */
/*@}*/
/**
* \name LRU
*/
/*@{*/
/** \brief Texture regions.
* Last element is sentinal
*/
radeon_tex_region_t texList[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
/** \brief last time texture was uploaded */
int texAge[RADEON_NR_TEX_HEAPS];
/*@}*/
int ctxOwner; /**< \brief last context to upload state */
int pfAllowPageFlip; /**< \brief set by the 2d driver, read by the client */
int pfCurrentPage; /**< \brief set by kernel, read by others */
int crtc2_base; /**< \brief for pageflipping with CloneMode */
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: context.c,v 1.188.2.1.2.2 2003/01/10 21:57:41 brianp Exp $ */
/* $Id: context.c,v 1.188.2.1.2.3 2003/02/21 21:14:08 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -1883,7 +1883,7 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->SavePrefersFloat = GL_FALSE;
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
/* _mesa_init_exec_vtxfmt( ctx ); */
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
@@ -2253,8 +2253,6 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
if (MESA_VERBOSE)
_mesa_debug(newCtx, "_mesa_make_current2()\n");
fprintf(stderr, "%s\n", __FUNCTION__);
/* Check that the context's and framebuffer's visuals are compatible.
* We could do a lot more checking here but this'll catch obvious
* problems.

View File

@@ -1,4 +1,4 @@
/* $Id: feedback.c,v 1.27 2002/10/24 23:57:20 brianp Exp $ */
/* $Id: feedback.c,v 1.27.4.1 2003/02/21 21:14:15 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -167,7 +167,7 @@ _mesa_SelectBuffer( GLsizei size, GLuint *buffer )
return; /* KW: added return */
}
FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* why bother? */
FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
ctx->Select.Buffer = buffer;
ctx->Select.BufferSize = size;
ctx->Select.BufferCount = 0;

View File

@@ -1,4 +1,4 @@
/* $Id: state.c,v 1.97 2002/11/06 15:16:23 brianp Exp $ */
/* $Id: state.c,v 1.97.4.1 2003/02/21 21:14:18 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -77,9 +77,7 @@
static int
generic_noop(void)
{
#ifdef DEBUG
_mesa_problem(NULL, "User called no-op dispatch function");
#endif
_mesa_problem(NULL, "User called no-op dispatch function (not part of Mesa subset?)");
return 0;
}
@@ -116,422 +114,422 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
_mesa_loopback_init_api_table( exec, GL_TRUE );
/* load the dispatch slots we understand */
exec->Accum = _mesa_Accum;
/* exec->Accum = _mesa_Accum; */
exec->AlphaFunc = _mesa_AlphaFunc;
exec->Bitmap = _mesa_Bitmap;
exec->BlendFunc = _mesa_BlendFunc;
exec->CallList = _mesa_CallList;
exec->CallLists = _mesa_CallLists;
/* exec->CallList = _mesa_CallList; */
/* exec->CallLists = _mesa_CallLists; */
exec->Clear = _mesa_Clear;
exec->ClearAccum = _mesa_ClearAccum;
/* exec->ClearAccum = _mesa_ClearAccum; */
exec->ClearColor = _mesa_ClearColor;
exec->ClearDepth = _mesa_ClearDepth;
exec->ClearIndex = _mesa_ClearIndex;
/* exec->ClearDepth = _mesa_ClearDepth; */
/* exec->ClearIndex = _mesa_ClearIndex; */
exec->ClearStencil = _mesa_ClearStencil;
exec->ClipPlane = _mesa_ClipPlane;
/* exec->ClipPlane = _mesa_ClipPlane; */
exec->ColorMask = _mesa_ColorMask;
exec->ColorMaterial = _mesa_ColorMaterial;
exec->CopyPixels = _mesa_CopyPixels;
/* exec->ColorMaterial = _mesa_ColorMaterial; */
/* exec->CopyPixels = _mesa_CopyPixels; */
exec->CullFace = _mesa_CullFace;
exec->DeleteLists = _mesa_DeleteLists;
exec->DepthFunc = _mesa_DepthFunc;
exec->DepthMask = _mesa_DepthMask;
exec->DepthRange = _mesa_DepthRange;
/* exec->DeleteLists = _mesa_DeleteLists; */
/* exec->DepthFunc = _mesa_DepthFunc; */
/* exec->DepthMask = _mesa_DepthMask; */
/* exec->DepthRange = _mesa_DepthRange; */
exec->Disable = _mesa_Disable;
exec->DrawBuffer = _mesa_DrawBuffer;
exec->DrawPixels = _mesa_DrawPixels;
/* exec->DrawPixels = _mesa_DrawPixels; */
exec->Enable = _mesa_Enable;
exec->EndList = _mesa_EndList;
exec->FeedbackBuffer = _mesa_FeedbackBuffer;
/* exec->EndList = _mesa_EndList; */
/* exec->FeedbackBuffer = _mesa_FeedbackBuffer; */
exec->Finish = _mesa_Finish;
exec->Flush = _mesa_Flush;
exec->FogCoordPointerEXT = _mesa_FogCoordPointerEXT;
exec->Fogf = _mesa_Fogf;
exec->Fogfv = _mesa_Fogfv;
exec->Fogi = _mesa_Fogi;
exec->Fogiv = _mesa_Fogiv;
/* exec->FogCoordPointerEXT = _mesa_FogCoordPointerEXT; */
/* exec->Fogf = _mesa_Fogf; */
/* exec->Fogfv = _mesa_Fogfv; */
/* exec->Fogi = _mesa_Fogi; */
/* exec->Fogiv = _mesa_Fogiv; */
exec->FrontFace = _mesa_FrontFace;
exec->Frustum = _mesa_Frustum;
exec->GenLists = _mesa_GenLists;
/* exec->GenLists = _mesa_GenLists; */
exec->GetBooleanv = _mesa_GetBooleanv;
exec->GetClipPlane = _mesa_GetClipPlane;
exec->GetDoublev = _mesa_GetDoublev;
/* exec->GetClipPlane = _mesa_GetClipPlane; */
/* exec->GetDoublev = _mesa_GetDoublev; */
exec->GetError = _mesa_GetError;
exec->GetFloatv = _mesa_GetFloatv;
exec->GetIntegerv = _mesa_GetIntegerv;
exec->GetLightfv = _mesa_GetLightfv;
exec->GetLightiv = _mesa_GetLightiv;
exec->GetMapdv = _mesa_GetMapdv;
exec->GetMapfv = _mesa_GetMapfv;
exec->GetMapiv = _mesa_GetMapiv;
exec->GetMaterialfv = _mesa_GetMaterialfv;
exec->GetMaterialiv = _mesa_GetMaterialiv;
exec->GetPixelMapfv = _mesa_GetPixelMapfv;
exec->GetPixelMapuiv = _mesa_GetPixelMapuiv;
exec->GetPixelMapusv = _mesa_GetPixelMapusv;
exec->GetPolygonStipple = _mesa_GetPolygonStipple;
/* exec->GetLightfv = _mesa_GetLightfv; */
/* exec->GetLightiv = _mesa_GetLightiv; */
/* exec->GetMapdv = _mesa_GetMapdv; */
/* exec->GetMapfv = _mesa_GetMapfv; */
/* exec->GetMapiv = _mesa_GetMapiv; */
/* exec->GetMaterialfv = _mesa_GetMaterialfv; */
/* exec->GetMaterialiv = _mesa_GetMaterialiv; */
/* exec->GetPixelMapfv = _mesa_GetPixelMapfv; */
/* exec->GetPixelMapuiv = _mesa_GetPixelMapuiv; */
/* exec->GetPixelMapusv = _mesa_GetPixelMapusv; */
/* exec->GetPolygonStipple = _mesa_GetPolygonStipple; */
exec->GetString = _mesa_GetString;
exec->GetTexEnvfv = _mesa_GetTexEnvfv;
exec->GetTexEnviv = _mesa_GetTexEnviv;
exec->GetTexGendv = _mesa_GetTexGendv;
exec->GetTexGenfv = _mesa_GetTexGenfv;
exec->GetTexGeniv = _mesa_GetTexGeniv;
exec->GetTexImage = _mesa_GetTexImage;
/* exec->GetTexGendv = _mesa_GetTexGendv; */
/* exec->GetTexGenfv = _mesa_GetTexGenfv; */
/* exec->GetTexGeniv = _mesa_GetTexGeniv; */
/* exec->GetTexImage = _mesa_GetTexImage; */
exec->GetTexLevelParameterfv = _mesa_GetTexLevelParameterfv;
exec->GetTexLevelParameteriv = _mesa_GetTexLevelParameteriv;
exec->GetTexParameterfv = _mesa_GetTexParameterfv;
exec->GetTexParameteriv = _mesa_GetTexParameteriv;
exec->Hint = _mesa_Hint;
exec->IndexMask = _mesa_IndexMask;
/* exec->Hint = _mesa_Hint; */
/* exec->IndexMask = _mesa_IndexMask; */
exec->InitNames = _mesa_InitNames;
exec->IsEnabled = _mesa_IsEnabled;
exec->IsList = _mesa_IsList;
exec->LightModelf = _mesa_LightModelf;
exec->LightModelfv = _mesa_LightModelfv;
exec->LightModeli = _mesa_LightModeli;
exec->LightModeliv = _mesa_LightModeliv;
exec->Lightf = _mesa_Lightf;
exec->Lightfv = _mesa_Lightfv;
exec->Lighti = _mesa_Lighti;
exec->Lightiv = _mesa_Lightiv;
/* exec->IsEnabled = _mesa_IsEnabled; */
/* exec->IsList = _mesa_IsList; */
/* exec->LightModelf = _mesa_LightModelf; */
/* exec->LightModelfv = _mesa_LightModelfv; */
/* exec->LightModeli = _mesa_LightModeli; */
/* exec->LightModeliv = _mesa_LightModeliv; */
/* exec->Lightf = _mesa_Lightf; */
/* exec->Lightfv = _mesa_Lightfv; */
/* exec->Lighti = _mesa_Lighti; */
/* exec->Lightiv = _mesa_Lightiv; */
exec->LineStipple = _mesa_LineStipple;
exec->LineWidth = _mesa_LineWidth;
exec->ListBase = _mesa_ListBase;
/* exec->ListBase = _mesa_ListBase; */
exec->LoadIdentity = _mesa_LoadIdentity;
exec->LoadMatrixd = _mesa_LoadMatrixd;
/* exec->LoadMatrixd = _mesa_LoadMatrixd; */
exec->LoadMatrixf = _mesa_LoadMatrixf;
exec->LoadName = _mesa_LoadName;
exec->LogicOp = _mesa_LogicOp;
exec->Map1d = _mesa_Map1d;
exec->Map1f = _mesa_Map1f;
exec->Map2d = _mesa_Map2d;
exec->Map2f = _mesa_Map2f;
exec->MapGrid1d = _mesa_MapGrid1d;
exec->MapGrid1f = _mesa_MapGrid1f;
exec->MapGrid2d = _mesa_MapGrid2d;
exec->MapGrid2f = _mesa_MapGrid2f;
/* exec->Map1d = _mesa_Map1d; */
/* exec->Map1f = _mesa_Map1f; */
/* exec->Map2d = _mesa_Map2d; */
/* exec->Map2f = _mesa_Map2f; */
/* exec->MapGrid1d = _mesa_MapGrid1d; */
/* exec->MapGrid1f = _mesa_MapGrid1f; */
/* exec->MapGrid2d = _mesa_MapGrid2d; */
/* exec->MapGrid2f = _mesa_MapGrid2f; */
exec->MatrixMode = _mesa_MatrixMode;
exec->MultMatrixd = _mesa_MultMatrixd;
/* exec->MultMatrixd = _mesa_MultMatrixd; */
exec->MultMatrixf = _mesa_MultMatrixf;
exec->NewList = _mesa_NewList;
/* exec->NewList = _mesa_NewList; */
exec->Ortho = _mesa_Ortho;
exec->PassThrough = _mesa_PassThrough;
exec->PixelMapfv = _mesa_PixelMapfv;
exec->PixelMapuiv = _mesa_PixelMapuiv;
exec->PixelMapusv = _mesa_PixelMapusv;
exec->PixelStoref = _mesa_PixelStoref;
/* exec->PassThrough = _mesa_PassThrough; */
/* exec->PixelMapfv = _mesa_PixelMapfv; */
/* exec->PixelMapuiv = _mesa_PixelMapuiv; */
/* exec->PixelMapusv = _mesa_PixelMapusv; */
/* exec->PixelStoref = _mesa_PixelStoref; */
exec->PixelStorei = _mesa_PixelStorei;
exec->PixelTransferf = _mesa_PixelTransferf;
exec->PixelTransferi = _mesa_PixelTransferi;
exec->PixelZoom = _mesa_PixelZoom;
exec->PointSize = _mesa_PointSize;
exec->PolygonMode = _mesa_PolygonMode;
exec->PolygonOffset = _mesa_PolygonOffset;
exec->PolygonStipple = _mesa_PolygonStipple;
exec->PopAttrib = _mesa_PopAttrib;
/* exec->PixelTransferf = _mesa_PixelTransferf; */
/* exec->PixelTransferi = _mesa_PixelTransferi; */
/* exec->PixelZoom = _mesa_PixelZoom; */
/* exec->PointSize = _mesa_PointSize; */
/* exec->PolygonMode = _mesa_PolygonMode; */
/* exec->PolygonOffset = _mesa_PolygonOffset; */
/* exec->PolygonStipple = _mesa_PolygonStipple; */
/* exec->PopAttrib = _mesa_PopAttrib; */
exec->PopMatrix = _mesa_PopMatrix;
exec->PopName = _mesa_PopName;
exec->PushAttrib = _mesa_PushAttrib;
/* exec->PushAttrib = _mesa_PushAttrib; */
exec->PushMatrix = _mesa_PushMatrix;
exec->PushName = _mesa_PushName;
exec->RasterPos2d = _mesa_RasterPos2d;
exec->RasterPos2dv = _mesa_RasterPos2dv;
/* exec->RasterPos2d = _mesa_RasterPos2d; */
/* exec->RasterPos2dv = _mesa_RasterPos2dv; */
exec->RasterPos2f = _mesa_RasterPos2f;
exec->RasterPos2fv = _mesa_RasterPos2fv;
exec->RasterPos2i = _mesa_RasterPos2i;
exec->RasterPos2iv = _mesa_RasterPos2iv;
exec->RasterPos2s = _mesa_RasterPos2s;
exec->RasterPos2sv = _mesa_RasterPos2sv;
exec->RasterPos3d = _mesa_RasterPos3d;
exec->RasterPos3dv = _mesa_RasterPos3dv;
exec->RasterPos3f = _mesa_RasterPos3f;
exec->RasterPos3fv = _mesa_RasterPos3fv;
exec->RasterPos3i = _mesa_RasterPos3i;
exec->RasterPos3iv = _mesa_RasterPos3iv;
exec->RasterPos3s = _mesa_RasterPos3s;
exec->RasterPos3sv = _mesa_RasterPos3sv;
exec->RasterPos4d = _mesa_RasterPos4d;
exec->RasterPos4dv = _mesa_RasterPos4dv;
exec->RasterPos4f = _mesa_RasterPos4f;
exec->RasterPos4fv = _mesa_RasterPos4fv;
exec->RasterPos4i = _mesa_RasterPos4i;
exec->RasterPos4iv = _mesa_RasterPos4iv;
exec->RasterPos4s = _mesa_RasterPos4s;
exec->RasterPos4sv = _mesa_RasterPos4sv;
/* exec->RasterPos2s = _mesa_RasterPos2s; */
/* exec->RasterPos2sv = _mesa_RasterPos2sv; */
/* exec->RasterPos3d = _mesa_RasterPos3d; */
/* exec->RasterPos3dv = _mesa_RasterPos3dv; */
/* exec->RasterPos3f = _mesa_RasterPos3f; */
/* exec->RasterPos3fv = _mesa_RasterPos3fv; */
/* exec->RasterPos3i = _mesa_RasterPos3i; */
/* exec->RasterPos3iv = _mesa_RasterPos3iv; */
/* exec->RasterPos3s = _mesa_RasterPos3s; */
/* exec->RasterPos3sv = _mesa_RasterPos3sv; */
/* exec->RasterPos4d = _mesa_RasterPos4d; */
/* exec->RasterPos4dv = _mesa_RasterPos4dv; */
/* exec->RasterPos4f = _mesa_RasterPos4f; */
/* exec->RasterPos4fv = _mesa_RasterPos4fv; */
/* exec->RasterPos4i = _mesa_RasterPos4i; */
/* exec->RasterPos4iv = _mesa_RasterPos4iv; */
/* exec->RasterPos4s = _mesa_RasterPos4s; */
/* exec->RasterPos4sv = _mesa_RasterPos4sv; */
exec->ReadBuffer = _mesa_ReadBuffer;
exec->ReadPixels = _mesa_ReadPixels;
exec->RenderMode = _mesa_RenderMode;
exec->Rotated = _mesa_Rotated;
/* exec->Rotated = _mesa_Rotated; */
exec->Rotatef = _mesa_Rotatef;
exec->Scaled = _mesa_Scaled;
/* exec->Scaled = _mesa_Scaled; */
exec->Scalef = _mesa_Scalef;
exec->Scissor = _mesa_Scissor;
exec->SecondaryColorPointerEXT = _mesa_SecondaryColorPointerEXT;
/* exec->SecondaryColorPointerEXT = _mesa_SecondaryColorPointerEXT; */
exec->SelectBuffer = _mesa_SelectBuffer;
exec->ShadeModel = _mesa_ShadeModel;
exec->StencilFunc = _mesa_StencilFunc;
exec->StencilMask = _mesa_StencilMask;
exec->StencilOp = _mesa_StencilOp;
exec->TexEnvf = _mesa_TexEnvf;
/* exec->TexEnvf = _mesa_TexEnvf; */
exec->TexEnvfv = _mesa_TexEnvfv;
exec->TexEnvi = _mesa_TexEnvi;
exec->TexEnviv = _mesa_TexEnviv;
exec->TexGend = _mesa_TexGend;
exec->TexGendv = _mesa_TexGendv;
exec->TexGenf = _mesa_TexGenf;
exec->TexGenfv = _mesa_TexGenfv;
exec->TexGeni = _mesa_TexGeni;
exec->TexGeniv = _mesa_TexGeniv;
exec->TexImage1D = _mesa_TexImage1D;
/* exec->TexEnviv = _mesa_TexEnviv; */
/* exec->TexGend = _mesa_TexGend; */
/* exec->TexGendv = _mesa_TexGendv; */
/* exec->TexGenf = _mesa_TexGenf; */
/* exec->TexGenfv = _mesa_TexGenfv; */
/* exec->TexGeni = _mesa_TexGeni; */
/* exec->TexGeniv = _mesa_TexGeniv; */
/* exec->TexImage1D = _mesa_TexImage1D; */
exec->TexImage2D = _mesa_TexImage2D;
exec->TexParameterf = _mesa_TexParameterf;
exec->TexParameterfv = _mesa_TexParameterfv;
exec->TexParameteri = _mesa_TexParameteri;
exec->TexParameteriv = _mesa_TexParameteriv;
exec->Translated = _mesa_Translated;
/* exec->TexParameterf = _mesa_TexParameterf; */
/* exec->TexParameterfv = _mesa_TexParameterfv; */
exec->TexParameteri = _mesa_TexParameteri;
/* exec->TexParameteriv = _mesa_TexParameteriv; */
/* exec->Translated = _mesa_Translated; */
exec->Translatef = _mesa_Translatef;
exec->Viewport = _mesa_Viewport;
/* 1.1 */
exec->AreTexturesResident = _mesa_AreTexturesResident;
exec->AreTexturesResidentEXT = _mesa_AreTexturesResident;
/* exec->AreTexturesResident = _mesa_AreTexturesResident; */
/* exec->AreTexturesResidentEXT = _mesa_AreTexturesResident; */
exec->BindTexture = _mesa_BindTexture;
exec->ColorPointer = _mesa_ColorPointer;
exec->CopyTexImage1D = _mesa_CopyTexImage1D;
exec->CopyTexImage2D = _mesa_CopyTexImage2D;
exec->CopyTexSubImage1D = _mesa_CopyTexSubImage1D;
exec->CopyTexSubImage2D = _mesa_CopyTexSubImage2D;
/* exec->ColorPointer = _mesa_ColorPointer; */
/* exec->CopyTexImage1D = _mesa_CopyTexImage1D; */
/* exec->CopyTexImage2D = _mesa_CopyTexImage2D; */
/* exec->CopyTexSubImage1D = _mesa_CopyTexSubImage1D; */
/* exec->CopyTexSubImage2D = _mesa_CopyTexSubImage2D; */
exec->DeleteTextures = _mesa_DeleteTextures;
exec->DisableClientState = _mesa_DisableClientState;
exec->EdgeFlagPointer = _mesa_EdgeFlagPointer;
exec->EnableClientState = _mesa_EnableClientState;
/* exec->DisableClientState = _mesa_DisableClientState; */
/* exec->EdgeFlagPointer = _mesa_EdgeFlagPointer; */
/* exec->EnableClientState = _mesa_EnableClientState; */
exec->GenTextures = _mesa_GenTextures;
exec->GenTexturesEXT = _mesa_GenTextures;
exec->GetPointerv = _mesa_GetPointerv;
exec->IndexPointer = _mesa_IndexPointer;
exec->InterleavedArrays = _mesa_InterleavedArrays;
exec->IsTexture = _mesa_IsTexture;
exec->IsTextureEXT = _mesa_IsTexture;
exec->NormalPointer = _mesa_NormalPointer;
exec->PopClientAttrib = _mesa_PopClientAttrib;
exec->PrioritizeTextures = _mesa_PrioritizeTextures;
exec->PushClientAttrib = _mesa_PushClientAttrib;
exec->TexCoordPointer = _mesa_TexCoordPointer;
exec->TexSubImage1D = _mesa_TexSubImage1D;
exec->TexSubImage2D = _mesa_TexSubImage2D;
exec->VertexPointer = _mesa_VertexPointer;
/* exec->GenTexturesEXT = _mesa_GenTextures; */
/* exec->GetPointerv = _mesa_GetPointerv; */
/* exec->IndexPointer = _mesa_IndexPointer; */
/* exec->InterleavedArrays = _mesa_InterleavedArrays; */
/* exec->IsTexture = _mesa_IsTexture; */
/* exec->IsTextureEXT = _mesa_IsTexture; */
/* exec->NormalPointer = _mesa_NormalPointer; */
/* exec->PopClientAttrib = _mesa_PopClientAttrib; */
/* exec->PrioritizeTextures = _mesa_PrioritizeTextures; */
/* exec->PushClientAttrib = _mesa_PushClientAttrib; */
/* exec->TexCoordPointer = _mesa_TexCoordPointer; */
/* exec->TexSubImage1D = _mesa_TexSubImage1D; */
/* exec->TexSubImage2D = _mesa_TexSubImage2D; */
/* exec->VertexPointer = _mesa_VertexPointer; */
/* 1.2 */
exec->CopyTexSubImage3D = _mesa_CopyTexSubImage3D;
exec->TexImage3D = _mesa_TexImage3D;
exec->TexSubImage3D = _mesa_TexSubImage3D;
/* exec->CopyTexSubImage3D = _mesa_CopyTexSubImage3D; */
/* exec->TexImage3D = _mesa_TexImage3D; */
/* exec->TexSubImage3D = _mesa_TexSubImage3D; */
/* OpenGL 1.2 GL_ARB_imaging */
exec->BlendColor = _mesa_BlendColor;
exec->BlendEquation = _mesa_BlendEquation;
exec->ColorSubTable = _mesa_ColorSubTable;
exec->ColorTable = _mesa_ColorTable;
exec->ColorTableParameterfv = _mesa_ColorTableParameterfv;
exec->ColorTableParameteriv = _mesa_ColorTableParameteriv;
exec->ConvolutionFilter1D = _mesa_ConvolutionFilter1D;
exec->ConvolutionFilter2D = _mesa_ConvolutionFilter2D;
exec->ConvolutionParameterf = _mesa_ConvolutionParameterf;
exec->ConvolutionParameterfv = _mesa_ConvolutionParameterfv;
exec->ConvolutionParameteri = _mesa_ConvolutionParameteri;
exec->ConvolutionParameteriv = _mesa_ConvolutionParameteriv;
exec->CopyColorSubTable = _mesa_CopyColorSubTable;
exec->CopyColorTable = _mesa_CopyColorTable;
exec->CopyConvolutionFilter1D = _mesa_CopyConvolutionFilter1D;
exec->CopyConvolutionFilter2D = _mesa_CopyConvolutionFilter2D;
exec->GetColorTable = _mesa_GetColorTable;
exec->GetColorTableEXT = _mesa_GetColorTable;
exec->GetColorTableParameterfv = _mesa_GetColorTableParameterfv;
exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv;
exec->GetColorTableParameteriv = _mesa_GetColorTableParameteriv;
exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv;
exec->GetConvolutionFilter = _mesa_GetConvolutionFilter;
exec->GetConvolutionFilterEXT = _mesa_GetConvolutionFilter;
exec->GetConvolutionParameterfv = _mesa_GetConvolutionParameterfv;
exec->GetConvolutionParameterfvEXT = _mesa_GetConvolutionParameterfv;
exec->GetConvolutionParameteriv = _mesa_GetConvolutionParameteriv;
exec->GetConvolutionParameterivEXT = _mesa_GetConvolutionParameteriv;
exec->GetHistogram = _mesa_GetHistogram;
exec->GetHistogramEXT = _mesa_GetHistogram;
exec->GetHistogramParameterfv = _mesa_GetHistogramParameterfv;
exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv;
exec->GetHistogramParameteriv = _mesa_GetHistogramParameteriv;
exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv;
exec->GetMinmax = _mesa_GetMinmax;
exec->GetMinmaxEXT = _mesa_GetMinmax;
exec->GetMinmaxParameterfv = _mesa_GetMinmaxParameterfv;
exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv;
exec->GetMinmaxParameteriv = _mesa_GetMinmaxParameteriv;
exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv;
exec->GetSeparableFilter = _mesa_GetSeparableFilter;
exec->GetSeparableFilterEXT = _mesa_GetSeparableFilter;
exec->Histogram = _mesa_Histogram;
exec->Minmax = _mesa_Minmax;
exec->ResetHistogram = _mesa_ResetHistogram;
exec->ResetMinmax = _mesa_ResetMinmax;
exec->SeparableFilter2D = _mesa_SeparableFilter2D;
/* exec->BlendColor = _mesa_BlendColor; */
/* exec->BlendEquation = _mesa_BlendEquation; */
/* exec->ColorSubTable = _mesa_ColorSubTable; */
/* exec->ColorTable = _mesa_ColorTable; */
/* exec->ColorTableParameterfv = _mesa_ColorTableParameterfv; */
/* exec->ColorTableParameteriv = _mesa_ColorTableParameteriv; */
/* exec->ConvolutionFilter1D = _mesa_ConvolutionFilter1D; */
/* exec->ConvolutionFilter2D = _mesa_ConvolutionFilter2D; */
/* exec->ConvolutionParameterf = _mesa_ConvolutionParameterf; */
/* exec->ConvolutionParameterfv = _mesa_ConvolutionParameterfv; */
/* exec->ConvolutionParameteri = _mesa_ConvolutionParameteri; */
/* exec->ConvolutionParameteriv = _mesa_ConvolutionParameteriv; */
/* exec->CopyColorSubTable = _mesa_CopyColorSubTable; */
/* exec->CopyColorTable = _mesa_CopyColorTable; */
/* exec->CopyConvolutionFilter1D = _mesa_CopyConvolutionFilter1D; */
/* exec->CopyConvolutionFilter2D = _mesa_CopyConvolutionFilter2D; */
/* exec->GetColorTable = _mesa_GetColorTable; */
/* exec->GetColorTableEXT = _mesa_GetColorTable; */
/* exec->GetColorTableParameterfv = _mesa_GetColorTableParameterfv; */
/* exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv; */
/* exec->GetColorTableParameteriv = _mesa_GetColorTableParameteriv; */
/* exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv; */
/* exec->GetConvolutionFilter = _mesa_GetConvolutionFilter; */
/* exec->GetConvolutionFilterEXT = _mesa_GetConvolutionFilter; */
/* exec->GetConvolutionParameterfv = _mesa_GetConvolutionParameterfv; */
/* exec->GetConvolutionParameterfvEXT = _mesa_GetConvolutionParameterfv; */
/* exec->GetConvolutionParameteriv = _mesa_GetConvolutionParameteriv; */
/* exec->GetConvolutionParameterivEXT = _mesa_GetConvolutionParameteriv; */
/* exec->GetHistogram = _mesa_GetHistogram; */
/* exec->GetHistogramEXT = _mesa_GetHistogram; */
/* exec->GetHistogramParameterfv = _mesa_GetHistogramParameterfv; */
/* exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv; */
/* exec->GetHistogramParameteriv = _mesa_GetHistogramParameteriv; */
/* exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv; */
/* exec->GetMinmax = _mesa_GetMinmax; */
/* exec->GetMinmaxEXT = _mesa_GetMinmax; */
/* exec->GetMinmaxParameterfv = _mesa_GetMinmaxParameterfv; */
/* exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv; */
/* exec->GetMinmaxParameteriv = _mesa_GetMinmaxParameteriv; */
/* exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv; */
/* exec->GetSeparableFilter = _mesa_GetSeparableFilter; */
/* exec->GetSeparableFilterEXT = _mesa_GetSeparableFilter; */
/* exec->Histogram = _mesa_Histogram; */
/* exec->Minmax = _mesa_Minmax; */
/* exec->ResetHistogram = _mesa_ResetHistogram; */
/* exec->ResetMinmax = _mesa_ResetMinmax; */
/* exec->SeparableFilter2D = _mesa_SeparableFilter2D; */
/* 2. GL_EXT_blend_color */
#if 0
exec->BlendColorEXT = _mesa_BlendColorEXT;
/* exec->BlendColorEXT = _mesa_BlendColorEXT; */
#endif
/* 3. GL_EXT_polygon_offset */
exec->PolygonOffsetEXT = _mesa_PolygonOffsetEXT;
/* exec->PolygonOffsetEXT = _mesa_PolygonOffsetEXT; */
/* 6. GL_EXT_texture3d */
#if 0
exec->CopyTexSubImage3DEXT = _mesa_CopyTexSubImage3D;
exec->TexImage3DEXT = _mesa_TexImage3DEXT;
exec->TexSubImage3DEXT = _mesa_TexSubImage3D;
/* exec->CopyTexSubImage3DEXT = _mesa_CopyTexSubImage3D; */
/* exec->TexImage3DEXT = _mesa_TexImage3DEXT; */
/* exec->TexSubImage3DEXT = _mesa_TexSubImage3D; */
#endif
/* 11. GL_EXT_histogram */
exec->GetHistogramEXT = _mesa_GetHistogram;
exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv;
exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv;
exec->GetMinmaxEXT = _mesa_GetMinmax;
exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv;
exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv;
/* exec->GetHistogramEXT = _mesa_GetHistogram; */
/* exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv; */
/* exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv; */
/* exec->GetMinmaxEXT = _mesa_GetMinmax; */
/* exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv; */
/* exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv; */
/* ?. GL_SGIX_pixel_texture */
exec->PixelTexGenSGIX = _mesa_PixelTexGenSGIX;
/* exec->PixelTexGenSGIX = _mesa_PixelTexGenSGIX; */
/* 15. GL_SGIS_pixel_texture */
exec->PixelTexGenParameteriSGIS = _mesa_PixelTexGenParameteriSGIS;
exec->PixelTexGenParameterivSGIS = _mesa_PixelTexGenParameterivSGIS;
exec->PixelTexGenParameterfSGIS = _mesa_PixelTexGenParameterfSGIS;
exec->PixelTexGenParameterfvSGIS = _mesa_PixelTexGenParameterfvSGIS;
exec->GetPixelTexGenParameterivSGIS = _mesa_GetPixelTexGenParameterivSGIS;
exec->GetPixelTexGenParameterfvSGIS = _mesa_GetPixelTexGenParameterfvSGIS;
/* exec->PixelTexGenParameteriSGIS = _mesa_PixelTexGenParameteriSGIS; */
/* exec->PixelTexGenParameterivSGIS = _mesa_PixelTexGenParameterivSGIS; */
/* exec->PixelTexGenParameterfSGIS = _mesa_PixelTexGenParameterfSGIS; */
/* exec->PixelTexGenParameterfvSGIS = _mesa_PixelTexGenParameterfvSGIS; */
/* exec->GetPixelTexGenParameterivSGIS = _mesa_GetPixelTexGenParameterivSGIS; */
/* exec->GetPixelTexGenParameterfvSGIS = _mesa_GetPixelTexGenParameterfvSGIS; */
/* 30. GL_EXT_vertex_array */
exec->ColorPointerEXT = _mesa_ColorPointerEXT;
exec->EdgeFlagPointerEXT = _mesa_EdgeFlagPointerEXT;
exec->IndexPointerEXT = _mesa_IndexPointerEXT;
exec->NormalPointerEXT = _mesa_NormalPointerEXT;
exec->TexCoordPointerEXT = _mesa_TexCoordPointerEXT;
exec->VertexPointerEXT = _mesa_VertexPointerEXT;
/* exec->ColorPointerEXT = _mesa_ColorPointerEXT; */
/* exec->EdgeFlagPointerEXT = _mesa_EdgeFlagPointerEXT; */
/* exec->IndexPointerEXT = _mesa_IndexPointerEXT; */
/* exec->NormalPointerEXT = _mesa_NormalPointerEXT; */
/* exec->TexCoordPointerEXT = _mesa_TexCoordPointerEXT; */
/* exec->VertexPointerEXT = _mesa_VertexPointerEXT; */
/* 37. GL_EXT_blend_minmax */
#if 0
exec->BlendEquationEXT = _mesa_BlendEquationEXT;
/* exec->BlendEquationEXT = _mesa_BlendEquationEXT; */
#endif
/* 54. GL_EXT_point_parameters */
exec->PointParameterfEXT = _mesa_PointParameterfEXT;
exec->PointParameterfvEXT = _mesa_PointParameterfvEXT;
/* exec->PointParameterfEXT = _mesa_PointParameterfEXT; */
/* exec->PointParameterfvEXT = _mesa_PointParameterfvEXT; */
/* 78. GL_EXT_paletted_texture */
#if 0
exec->ColorTableEXT = _mesa_ColorTableEXT;
exec->ColorSubTableEXT = _mesa_ColorSubTableEXT;
/* exec->ColorTableEXT = _mesa_ColorTableEXT; */
/* exec->ColorSubTableEXT = _mesa_ColorSubTableEXT; */
#endif
exec->GetColorTableEXT = _mesa_GetColorTable;
exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv;
exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv;
/* exec->GetColorTableEXT = _mesa_GetColorTable; */
/* exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv; */
/* exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv; */
/* 97. GL_EXT_compiled_vertex_array */
exec->LockArraysEXT = _mesa_LockArraysEXT;
exec->UnlockArraysEXT = _mesa_UnlockArraysEXT;
/* exec->LockArraysEXT = _mesa_LockArraysEXT; */
/* exec->UnlockArraysEXT = _mesa_UnlockArraysEXT; */
/* 148. GL_EXT_multi_draw_arrays */
exec->MultiDrawArraysEXT = _mesa_MultiDrawArraysEXT;
exec->MultiDrawElementsEXT = _mesa_MultiDrawElementsEXT;
/* exec->MultiDrawArraysEXT = _mesa_MultiDrawArraysEXT; */
/* exec->MultiDrawElementsEXT = _mesa_MultiDrawElementsEXT; */
/* 173. GL_INGR_blend_func_separate */
exec->BlendFuncSeparateEXT = _mesa_BlendFuncSeparateEXT;
/* exec->BlendFuncSeparateEXT = _mesa_BlendFuncSeparateEXT; */
/* 196. GL_MESA_resize_buffers */
exec->ResizeBuffersMESA = _mesa_ResizeBuffersMESA;
/* exec->ResizeBuffersMESA = _mesa_ResizeBuffersMESA; */
/* 197. GL_MESA_window_pos */
exec->WindowPos2dMESA = _mesa_WindowPos2dMESA;
exec->WindowPos2dvMESA = _mesa_WindowPos2dvMESA;
exec->WindowPos2fMESA = _mesa_WindowPos2fMESA;
exec->WindowPos2fvMESA = _mesa_WindowPos2fvMESA;
exec->WindowPos2iMESA = _mesa_WindowPos2iMESA;
exec->WindowPos2ivMESA = _mesa_WindowPos2ivMESA;
exec->WindowPos2sMESA = _mesa_WindowPos2sMESA;
exec->WindowPos2svMESA = _mesa_WindowPos2svMESA;
exec->WindowPos3dMESA = _mesa_WindowPos3dMESA;
exec->WindowPos3dvMESA = _mesa_WindowPos3dvMESA;
exec->WindowPos3fMESA = _mesa_WindowPos3fMESA;
exec->WindowPos3fvMESA = _mesa_WindowPos3fvMESA;
exec->WindowPos3iMESA = _mesa_WindowPos3iMESA;
exec->WindowPos3ivMESA = _mesa_WindowPos3ivMESA;
exec->WindowPos3sMESA = _mesa_WindowPos3sMESA;
exec->WindowPos3svMESA = _mesa_WindowPos3svMESA;
exec->WindowPos4dMESA = _mesa_WindowPos4dMESA;
exec->WindowPos4dvMESA = _mesa_WindowPos4dvMESA;
exec->WindowPos4fMESA = _mesa_WindowPos4fMESA;
exec->WindowPos4fvMESA = _mesa_WindowPos4fvMESA;
exec->WindowPos4iMESA = _mesa_WindowPos4iMESA;
exec->WindowPos4ivMESA = _mesa_WindowPos4ivMESA;
exec->WindowPos4sMESA = _mesa_WindowPos4sMESA;
exec->WindowPos4svMESA = _mesa_WindowPos4svMESA;
/* exec->WindowPos2dMESA = _mesa_WindowPos2dMESA; */
/* exec->WindowPos2dvMESA = _mesa_WindowPos2dvMESA; */
/* exec->WindowPos2fMESA = _mesa_WindowPos2fMESA; */
/* exec->WindowPos2fvMESA = _mesa_WindowPos2fvMESA; */
/* exec->WindowPos2iMESA = _mesa_WindowPos2iMESA; */
/* exec->WindowPos2ivMESA = _mesa_WindowPos2ivMESA; */
/* exec->WindowPos2sMESA = _mesa_WindowPos2sMESA; */
/* exec->WindowPos2svMESA = _mesa_WindowPos2svMESA; */
/* exec->WindowPos3dMESA = _mesa_WindowPos3dMESA; */
/* exec->WindowPos3dvMESA = _mesa_WindowPos3dvMESA; */
/* exec->WindowPos3fMESA = _mesa_WindowPos3fMESA; */
/* exec->WindowPos3fvMESA = _mesa_WindowPos3fvMESA; */
/* exec->WindowPos3iMESA = _mesa_WindowPos3iMESA; */
/* exec->WindowPos3ivMESA = _mesa_WindowPos3ivMESA; */
/* exec->WindowPos3sMESA = _mesa_WindowPos3sMESA; */
/* exec->WindowPos3svMESA = _mesa_WindowPos3svMESA; */
/* exec->WindowPos4dMESA = _mesa_WindowPos4dMESA; */
/* exec->WindowPos4dvMESA = _mesa_WindowPos4dvMESA; */
/* exec->WindowPos4fMESA = _mesa_WindowPos4fMESA; */
/* exec->WindowPos4fvMESA = _mesa_WindowPos4fvMESA; */
/* exec->WindowPos4iMESA = _mesa_WindowPos4iMESA; */
/* exec->WindowPos4ivMESA = _mesa_WindowPos4ivMESA; */
/* exec->WindowPos4sMESA = _mesa_WindowPos4sMESA; */
/* exec->WindowPos4svMESA = _mesa_WindowPos4svMESA; */
/* 233. GL_NV_vertex_program */
#if FEATURE_NV_vertex_program
exec->BindProgramNV = _mesa_BindProgramNV;
exec->DeleteProgramsNV = _mesa_DeleteProgramsNV;
exec->ExecuteProgramNV = _mesa_ExecuteProgramNV;
exec->GenProgramsNV = _mesa_GenProgramsNV;
exec->AreProgramsResidentNV = _mesa_AreProgramsResidentNV;
exec->RequestResidentProgramsNV = _mesa_RequestResidentProgramsNV;
exec->GetProgramParameterfvNV = _mesa_GetProgramParameterfvNV;
exec->GetProgramParameterdvNV = _mesa_GetProgramParameterdvNV;
exec->GetProgramivNV = _mesa_GetProgramivNV;
exec->GetProgramStringNV = _mesa_GetProgramStringNV;
exec->GetTrackMatrixivNV = _mesa_GetTrackMatrixivNV;
exec->GetVertexAttribdvNV = _mesa_GetVertexAttribdvNV;
exec->GetVertexAttribfvNV = _mesa_GetVertexAttribfvNV;
exec->GetVertexAttribivNV = _mesa_GetVertexAttribivNV;
exec->GetVertexAttribPointervNV = _mesa_GetVertexAttribPointervNV;
exec->IsProgramNV = _mesa_IsProgramNV;
exec->LoadProgramNV = _mesa_LoadProgramNV;
exec->ProgramParameter4dNV = _mesa_ProgramParameter4dNV;
exec->ProgramParameter4dvNV = _mesa_ProgramParameter4dvNV;
exec->ProgramParameter4fNV = _mesa_ProgramParameter4fNV;
exec->ProgramParameter4fvNV = _mesa_ProgramParameter4fvNV;
exec->ProgramParameters4dvNV = _mesa_ProgramParameters4dvNV;
exec->ProgramParameters4fvNV = _mesa_ProgramParameters4fvNV;
exec->TrackMatrixNV = _mesa_TrackMatrixNV;
exec->VertexAttribPointerNV = _mesa_VertexAttribPointerNV;
/* exec->BindProgramNV = _mesa_BindProgramNV; */
/* exec->DeleteProgramsNV = _mesa_DeleteProgramsNV; */
/* exec->ExecuteProgramNV = _mesa_ExecuteProgramNV; */
/* exec->GenProgramsNV = _mesa_GenProgramsNV; */
/* exec->AreProgramsResidentNV = _mesa_AreProgramsResidentNV; */
/* exec->RequestResidentProgramsNV = _mesa_RequestResidentProgramsNV; */
/* exec->GetProgramParameterfvNV = _mesa_GetProgramParameterfvNV; */
/* exec->GetProgramParameterdvNV = _mesa_GetProgramParameterdvNV; */
/* exec->GetProgramivNV = _mesa_GetProgramivNV; */
/* exec->GetProgramStringNV = _mesa_GetProgramStringNV; */
/* exec->GetTrackMatrixivNV = _mesa_GetTrackMatrixivNV; */
/* exec->GetVertexAttribdvNV = _mesa_GetVertexAttribdvNV; */
/* exec->GetVertexAttribfvNV = _mesa_GetVertexAttribfvNV; */
/* exec->GetVertexAttribivNV = _mesa_GetVertexAttribivNV; */
/* exec->GetVertexAttribPointervNV = _mesa_GetVertexAttribPointervNV; */
/* exec->IsProgramNV = _mesa_IsProgramNV; */
/* exec->LoadProgramNV = _mesa_LoadProgramNV; */
/* exec->ProgramParameter4dNV = _mesa_ProgramParameter4dNV; */
/* exec->ProgramParameter4dvNV = _mesa_ProgramParameter4dvNV; */
/* exec->ProgramParameter4fNV = _mesa_ProgramParameter4fNV; */
/* exec->ProgramParameter4fvNV = _mesa_ProgramParameter4fvNV; */
/* exec->ProgramParameters4dvNV = _mesa_ProgramParameters4dvNV; */
/* exec->ProgramParameters4fvNV = _mesa_ProgramParameters4fvNV; */
/* exec->TrackMatrixNV = _mesa_TrackMatrixNV; */
/* exec->VertexAttribPointerNV = _mesa_VertexAttribPointerNV; */
#endif
/* 262. GL_NV_point_sprite */
exec->PointParameteriNV = _mesa_PointParameteriNV;
exec->PointParameterivNV = _mesa_PointParameterivNV;
/* exec->PointParameteriNV = _mesa_PointParameteriNV; */
/* exec->PointParameterivNV = _mesa_PointParameterivNV; */
/* 268. GL_EXT_stencil_two_side */
exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT;
/* exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT; */
/* ARB 1. GL_ARB_multitexture */
exec->ActiveTextureARB = _mesa_ActiveTextureARB;
exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB;
/* exec->ActiveTextureARB = _mesa_ActiveTextureARB; */
/* exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB; */
/* ARB 3. GL_ARB_transpose_matrix */
exec->LoadTransposeMatrixdARB = _mesa_LoadTransposeMatrixdARB;
exec->LoadTransposeMatrixfARB = _mesa_LoadTransposeMatrixfARB;
exec->MultTransposeMatrixdARB = _mesa_MultTransposeMatrixdARB;
exec->MultTransposeMatrixfARB = _mesa_MultTransposeMatrixfARB;
/* exec->LoadTransposeMatrixdARB = _mesa_LoadTransposeMatrixdARB; */
/* exec->LoadTransposeMatrixfARB = _mesa_LoadTransposeMatrixfARB; */
/* exec->MultTransposeMatrixdARB = _mesa_MultTransposeMatrixdARB; */
/* exec->MultTransposeMatrixfARB = _mesa_MultTransposeMatrixfARB; */
/* ARB 5. GL_ARB_multisample */
exec->SampleCoverageARB = _mesa_SampleCoverageARB;
/* exec->SampleCoverageARB = _mesa_SampleCoverageARB; */
/* ARB 12. GL_ARB_texture_compression */
exec->CompressedTexImage3DARB = _mesa_CompressedTexImage3DARB;
exec->CompressedTexImage2DARB = _mesa_CompressedTexImage2DARB;
exec->CompressedTexImage1DARB = _mesa_CompressedTexImage1DARB;
exec->CompressedTexSubImage3DARB = _mesa_CompressedTexSubImage3DARB;
exec->CompressedTexSubImage2DARB = _mesa_CompressedTexSubImage2DARB;
exec->CompressedTexSubImage1DARB = _mesa_CompressedTexSubImage1DARB;
exec->GetCompressedTexImageARB = _mesa_GetCompressedTexImageARB;
/* exec->CompressedTexImage3DARB = _mesa_CompressedTexImage3DARB; */
/* exec->CompressedTexImage2DARB = _mesa_CompressedTexImage2DARB; */
/* exec->CompressedTexImage1DARB = _mesa_CompressedTexImage1DARB; */
/* exec->CompressedTexSubImage3DARB = _mesa_CompressedTexSubImage3DARB; */
/* exec->CompressedTexSubImage2DARB = _mesa_CompressedTexSubImage2DARB; */
/* exec->CompressedTexSubImage1DARB = _mesa_CompressedTexSubImage1DARB; */
/* exec->GetCompressedTexImageARB = _mesa_GetCompressedTexImageARB; */
/* ARB 14. GL_ARB_point_parameters */
/* reuse EXT_point_parameters functions */

View File

@@ -56,11 +56,10 @@
#include "miniglxP.h" /* XID, etc */
typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; /**< \brief Alias for __DRIdisplayPrivateRec */
typedef struct __DRIscreenPrivateRec __DRIscreenPrivate; /**< \brief Alias for __DRIscreenPrivateRec */
typedef struct __DRIcontextPrivateRec __DRIcontextPrivate; /**< \brief Alias for __DRIcontextPrivateRec */
typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; /**< \brief Alias for __DRIdrawablePrivateRec */
/**

View File

@@ -12,7 +12,7 @@ clientDriverName=radeon_dri.so
# The pci bus id of the video card. Find this with scanpci, lspci or
# look in /proc/pci.
pciBusID=PCI:1:0:0
pciBusID=PCI:3:0:0
# Virtual screen dimensions. Can reduce this to save videocard memory
# at the expense of maximum window size available.

View File

@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* $Id: miniglx.c,v 1.1.4.45 2003/01/20 15:01:39 brianp Exp $ */
/* $Id: miniglx.c,v 1.1.4.46 2003/02/21 21:14:31 keithw Exp $ */
/**
@@ -44,9 +44,10 @@
* interface is a subset of the GLX interface, plus a minimal set of Xlib-like
* functions.
*
* Programs written to the Mini GLX specification should run unchanged on
* systems with the X Window System and the GLX extension. The intention is to
* allow flexibility for prototyping and testing.
* Programs written to the Mini GLX specification should run unchanged
* on systems with the X Window System and the GLX extension (after
* recompilation). The intention is to allow flexibility for
* prototyping and testing.
*
* The files in the src/miniglx/ directory are compiled to build the
* libGL.so library. This is the library which applications link with.