Compare commits

...

122 Commits

Author SHA1 Message Date
Keith Whitwell
3e713fe38c Use correct condition for subsetting 2003-05-02 17:33:28 +00:00
Keith Whitwell
b975fcadfa mprotect sarea when focus lost 2003-05-02 17:32:24 +00:00
Keith Whitwell
f92291e02e mprotect sarea until focus gained 2003-05-02 17:31:42 +00:00
Keith Whitwell
15ebff0419 Remove isosurf target 2003-05-02 09:50:09 +00:00
Jose Fonseca
69db632a9d Move the Doxygen configuration files into the usual places and integrate with the build system. 2003-05-01 23:32:54 +00:00
Jose Fonseca
6c446ebaa1 Final fixes to the AGPGART and RADEONFB modules' documentation. 2003-05-01 14:06:15 +00:00
Keith Whitwell
62299f69fd Use mprotect() to protect the sarea when not in focus. 2003-05-01 13:02:33 +00:00
Keith Whitwell
b899261af6 Animate by default 2003-05-01 06:54:21 +00:00
Jose Fonseca
58cc2c6f33 Final documentation to the AGPGART module. 2003-05-01 00:56:11 +00:00
Jose Fonseca
88acbfbe18 Final documentation for the radeon fb module. 2003-04-30 14:05:04 +00:00
Keith Whitwell
a1c5c82860 Remove debug printfs, Use XCheckMaskEvent 2003-04-30 09:48:06 +00:00
Keith Whitwell
7001513cfc Remove debug printfs 2003-04-30 09:47:16 +00:00
Jose Fonseca
df0afe92d2 More documentation. 2003-04-29 23:46:53 +00:00
Keith Whitwell
04b5c5e96b New files 2003-04-29 21:53:10 +00:00
Keith Whitwell
63abbdc48f Add -autostart option 2003-04-29 09:41:01 +00:00
Keith Whitwell
daae83a437 Remove bogus assert 2003-04-29 09:36:10 +00:00
Keith Whitwell
939d5e3c55 Minor fixes 2003-04-29 08:21:44 +00:00
Keith Whitwell
f1a7d632d5 Shortcircuit ioctl if no focus 2003-04-29 08:21:08 +00:00
Keith Whitwell
d31591ea15 Protect some swrast-specific code in MakeCurrent 2003-04-29 08:20:39 +00:00
Keith Whitwell
687e8a0c08 Partial documentation of this file. 2003-04-28 13:21:10 +00:00
Keith Whitwell
c205240b38 Don't map agp tex mem, shortcircuit some more ops when not in focus 2003-04-28 12:06:24 +00:00
Keith Whitwell
b31d1f7987 Downgrade assert in __miniglx_Select()
Don't fail if client closes & reopens display.
2003-04-28 11:30:14 +00:00
Keith Whitwell
109fb8b726 Remove some more unused code 2003-04-28 10:16:32 +00:00
Keith Whitwell
fccc2a6f1a Slim down radeonfb.c 2003-04-28 10:14:56 +00:00
Keith Whitwell
1b2344de26 Don't try to lock hardware or issue ioctls if not the 'focus' app. 2003-04-27 17:03:41 +00:00
Keith Whitwell
cb9213080f - Set O_NONBLOCK on socket fds
- Don't try to get hw lock if already held (on vt switch)
2003-04-27 17:02:20 +00:00
Keith Whitwell
6160683739 prevent spurious texture uploads 2003-04-27 16:48:07 +00:00
Keith Whitwell
17d3134ec0 Force multiple applications to play nicer with each other. 2003-04-27 16:09:11 +00:00
Keith Whitwell
39c81446d6 Don't register a focus notify callback 2003-04-27 15:32:53 +00:00
Keith Whitwell
fe49aaed64 Only register radeonVtxfmtNotifyFocus for the subsetted driver 2003-04-27 15:32:24 +00:00
Keith Whitwell
ec0c259d0d Fix vertex copying calcs for tris, quads 2003-04-27 14:42:55 +00:00
Keith Whitwell
24a598b5af For subsetted driver, when client is unmapped, unmap our dma buffers. 2003-04-27 14:21:21 +00:00
Keith Whitwell
5e2bc7d1c0 Remove XFree86 tags.
Add 'notifyFocus' mechanism for drivers that want to shut down to some
extent when client apps aren't mapped.
2003-04-27 14:20:00 +00:00
Keith Whitwell
1f9c75b3e5 Fix problems not reloading textures after regaining lock 2003-04-27 12:34:14 +00:00
Keith Whitwell
942fdd126c Correct rm for clean 2003-04-27 12:21:03 +00:00
Keith Whitwell
f68f1de398 dri_driver_context.diff patch from Denis Oliver Kropp 2003-04-26 21:17:43 +00:00
Jose Fonseca
de615c98d7 Big chunk of the AGP module documentation. 2003-04-26 15:49:34 +00:00
Keith Whitwell
d45e01eb19 Call handle_fd_events in map/unmap window to flush write queue (should probably
loop until the queue really is flushed).

Do a better job with umask
2003-04-25 23:09:01 +00:00
Keith Whitwell
6d3615b857 Restore more registers after regaining vt. 2003-04-25 15:21:11 +00:00
Keith Whitwell
4afaba45f9 Get vt switching working properly. 2003-04-25 14:03:50 +00:00
Keith Whitwell
29eac4de82 get client & server processes working properly 2003-04-25 11:22:34 +00:00
Keith Whitwell
ee4b2f22b8 Test swapping focus between two or more apps 2003-04-25 09:37:29 +00:00
Keith Whitwell
545df254e8 mga driver ported over by Denis Oliver Kropp 2003-04-24 22:33:53 +00:00
Keith Whitwell
0bb460f417 Fix errors with queuing & dequing events. Add lots of debug too. 2003-04-22 14:29:53 +00:00
Keith Whitwell
ac565d7e04 Another sample server which also echos stdin to stdout
(not very useful, but demonstrates __miniglx_Select()...)
2003-04-17 15:47:46 +00:00
Keith Whitwell
3af10745d6 Add support for root-permission 'server' process and non-root clients
which share a single VT (but are still fullscreen)
2003-04-17 15:46:41 +00:00
Alan Hourihane
f1f331ef4d add definition for FB_ACCEL_ATI_RADEON 2003-04-17 11:25:39 +00:00
Alan Hourihane
ca81dd07b7 fix some warnings 2003-04-17 11:05:39 +00:00
Alan Hourihane
8dbdb74d8a radeonfb updates from PPC folks
fixes DVI problems and lots of others too, but also adds support for
newer hardware.
2003-04-17 00:18:04 +00:00
Keith Whitwell
1b3edffdd1 A simple "server" processes to manage a single cliprect between
multiple fullscreen clients.
2003-04-16 09:34:56 +00:00
Keith Whitwell
12ee43bd7c Fix some warnings 2003-04-16 09:29:53 +00:00
Alan Hourihane
1303475d38 a 768x1024 mode 2003-04-15 13:46:28 +00:00
Keith Whitwell
56d99c8cdb first version of event communications code 2003-04-15 11:01:27 +00:00
Keith Whitwell
f29b41f2ed Update r200 Makefile 2003-04-15 09:47:37 +00:00
Keith Whitwell
89d52a0de4 add subsetted isosurf 2003-04-07 22:27:52 +00:00
Keith Whitwell
b6fb04a81d subsetted isosurf 2003-04-07 22:27:23 +00:00
Keith Whitwell
7d55e9abf6 More 2.5.x files for documentation purposes only 2003-04-07 11:31:25 +00:00
Keith Whitwell
1ac609a7df Import of some 2.5.x agpgart files - will be documented but not built as a part of this branch. 2003-04-07 11:29:07 +00:00
Keith Whitwell
00affe74c1 Fix vertex copying bug (Andreas S.) 2003-03-25 12:27:21 +00:00
Keith Whitwell
f221b8df75 Comment out debug 2003-03-24 19:00:16 +00:00
Keith Whitwell
45bd335b1c add glViewport calls 2003-03-24 18:46:57 +00:00
Keith Whitwell
6127672e26 Fix rastpos issue in rotated mode 2003-03-24 18:23:32 +00:00
Keith Whitwell
bb3752a434 Further VT switch prototype hacks 2003-03-24 15:49:13 +00:00
Keith Whitwell
56c896a2b8 Some hacks to make prototype VT switching facilities less prone to lockups. 2003-03-24 15:41:32 +00:00
Keith Whitwell
afc72872be Use new XEvent facilities 2003-03-24 15:40:34 +00:00
Keith Whitwell
e511f40795 Set UNPACK_ROW_LENGTH to properly display bitmap fonts. 2003-03-24 15:39:59 +00:00
Jose Fonseca
a53f53ece3 Avoid the mixing of double-colon rules in the Makefiles. 2003-03-24 10:38:30 +00:00
Jose Fonseca
24812b3eaa Enable the full Mesa documentation. 2003-03-24 00:46:36 +00:00
Jose Fonseca
42e0f2ec95 Make a small reference to the distiction between the full and subset documentation start inital pages. 2003-03-23 23:29:05 +00:00
Jose Fonseca
e4fcab7a35 Final documentation fixes and enhancements. 2003-03-23 23:22:47 +00:00
Jose Fonseca
cd6d79a82c Last bits of documentation. Review still pending. 2003-03-23 14:58:08 +00:00
Jose Fonseca
a428744286 More documentation. 2003-03-23 03:51:34 +00:00
Jose Fonseca
ccc6ef28ca More missing files. 2003-03-23 03:48:43 +00:00
Jose Fonseca
3100749dd0 Tweaks to the doxygen configuration files 2003-03-22 16:51:37 +00:00
Jose Fonseca
980e98d324 More documentation. 2003-03-22 16:49:58 +00:00
Keith Whitwell
2204d5bb46 Don't override ctx->Exec->Viewport as there seem to be dependencies
on this being _mesa_Viewport().
2003-03-22 16:19:58 +00:00
Keith Whitwell
67d3c57c46 Tarball build fixes 2003-03-22 14:36:49 +00:00
Keith Whitwell
9e24ff7a0a Remove non-subset fn calls 2003-03-22 14:35:24 +00:00
Keith Whitwell
e014d794f2 Rotate mode 2003-03-22 12:52:29 +00:00
Keith Whitwell
a9bd5a6860 Bring makefile into line with others 2003-03-22 09:29:19 +00:00
Keith Whitwell
94643c4780 Add clean:: target 2003-03-22 08:48:47 +00:00
Keith Whitwell
993502aebc Subset demos 2003-03-22 08:46:22 +00:00
Keith Whitwell
932e26e8f4 Add RotateMode option 2003-03-22 08:45:57 +00:00
Keith Whitwell
54f4c8d1a3 Rotate mode 2003-03-22 08:44:11 +00:00
Keith Whitwell
277d7a2a85 RotateMode changes 2003-03-22 08:43:26 +00:00
Keith Whitwell
0a98671051 Subset demos, link GLU explicitly 2003-03-22 08:41:06 +00:00
Keith Whitwell
a47745e9fd Link GLU explicitly.
Subsetize some more demos.
2003-03-22 08:40:35 +00:00
Keith Whitwell
69ce6b7db0 A cutdown version of Gareth's GLU implementation to get some more demos
working with the subsetted GL.
2003-03-21 13:02:06 +00:00
Keith Whitwell
5d3ab07110 remove old glprocs.h 2003-03-21 11:38:52 +00:00
Keith Whitwell
1613d48989 Build fixes for full driver.
Cope with new location of generated glapi files.
2003-03-21 11:35:14 +00:00
Keith Whitwell
5a610a1974 do screen clear in locked region 2003-03-21 11:33:24 +00:00
Keith Whitwell
afb339bf75 Don't use non-subset functions 2003-03-21 11:32:55 +00:00
Keith Whitwell
16ca6f8e93 Subsetted spec file 2003-03-21 11:20:22 +00:00
Jose Fonseca
41b5963f8d More documentation. 2003-03-20 19:38:39 +00:00
Jose Fonseca
99199c0ece Add a few missing headers to the doxygen input sources. 2003-03-20 19:37:36 +00:00
Keith Whitwell
368d95a7dc Update raster position early to make sure its always done. 2003-03-20 14:44:49 +00:00
Jose Fonseca
0218da1433 Documentation. 2003-03-20 12:56:57 +00:00
Keith Whitwell
6cb2411250 Distribute initialization, cleanup and state-update tasks to the files
where that data is managed.  Thus, the light attribute state is
initialized in light.c, and update_lighting() moves there too.
2003-03-20 09:19:50 +00:00
Jose Fonseca
0d3a504b94 Documentation. 2003-03-19 15:43:14 +00:00
Jose Fonseca
bde16645ca Seperate the subset documentation from the full implementation. 2003-03-19 14:48:17 +00:00
Keith Whitwell
301f7e4408 subsetting 2003-03-18 08:55:20 +00:00
Keith Whitwell
173441d1a6 Further subsetting 2003-03-17 21:22:49 +00:00
Keith Whitwell
64b3e2fa16 Incremental subsetting 2003-03-17 17:03:46 +00:00
Keith Whitwell
6919c50029 Subsetted versions of enable.c and pixel.c 2003-03-17 16:07:21 +00:00
Keith Whitwell
a8512f7dda Continue with subset_texture.c, get some demos working 2003-03-17 15:18:16 +00:00
Jose Fonseca
70217c70be More documentation. 2003-03-16 00:27:12 +00:00
Keith Whitwell
9d4857a816 Very fragile support for VT switching between multiple running apps.
Not safe to use as there is no exclusion from fbdev hw actions at vt switch
time.
2003-03-13 17:13:34 +00:00
Keith Whitwell
3f00e34097 Merge from trunk to bring in GL_ATI_texture_env_combine3 tokens (Jon Smirl) 2003-03-11 10:32:22 +00:00
Keith Whitwell
3e48e6fce4 Add r200 chipids (Jon Smirl) -- for real this time 2003-03-11 10:26:57 +00:00
Keith Whitwell
d1fa9af224 Ugh. Back out bogus commit. 2003-03-11 10:25:28 +00:00
Keith Whitwell
c20d946424 Add r200 chipids (Jon Smirl) 2003-03-11 10:23:45 +00:00
Brian Paul
ff6068b217 merge from 5.0.1 branch 2003-03-10 14:10:46 +00:00
Keith Whitwell
ed1b6e98e2 r200 driver, brought over by Jon Smirl 2003-03-10 11:23:04 +00:00
Keith Whitwell
b52901eb89 Add r200 chipids (Jon Smirl) 2003-03-10 11:07:05 +00:00
Keith Whitwell
cff70d16aa Add FEATURE_texgen (Jon Smirl) 2003-03-10 11:02:14 +00:00
Jose Fonseca
bafbdcb703 Doxygen documentation additions and fixes 2003-03-09 10:52:20 +00:00
Keith Whitwell
50d1c2c921 Define FEATURE_userclip, the first of many? 2003-03-05 14:27:33 +00:00
Keith Whitwell
a1fd12ab84 Remove most of the math module 2003-03-05 14:22:21 +00:00
Keith Whitwell
360bec8a6f Start subsetting core mesa 2003-03-05 14:04:18 +00:00
Keith Whitwell
6440630d79 Use vertex2f instead of 2i 2003-03-05 14:02:44 +00:00
Keith Whitwell
02a6f4b56a Fix modules needed for subset build 2003-03-05 13:16:20 +00:00
Keith Whitwell
f828410458 new file 2003-03-05 13:04:43 +00:00
274 changed files with 63464 additions and 13071 deletions

View File

@@ -1,7 +1,9 @@
*.tag
array_cache
core
core_subset
math
math_subset
miniglx
radeon_subset
swrast

View File

@@ -6,4 +6,5 @@ See http://www.doxygen.org/ for more info.
Either run 'make' (Unix) or 'doxy.bat' (Windows) to run doxygen
and generate souce code documentation.
Then, load doxy/core/index.html into your web browser.
Then, load either doxy/core/index.html or doxy/core_subset/index.html into
your web browser.

1054
doxygen/agpgart.doxy Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -55,7 +55,7 @@ INPUT = ../src/
FILE_PATTERNS = *.c *.h
RECURSIVE = NO
EXCLUDE = ../src/glapitemp.h ../src/glapioffsets.h
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = subset_*
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
@@ -132,13 +132,13 @@ GENERATE_AUTOGEN_DEF = NO
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH = ../include/
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
PREDEFINED = _HAVE_FULL_GL=1
EXPAND_AS_DEFINED = _glthread_DECLARE_STATIC_MUTEX
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
@@ -148,8 +148,7 @@ TAGFILES = tnl_dd.tag=../tnl_dd \
math.tag=../math \
swrast.tag=../swrast \
swrast_setup.tag=../swrast_setup \
tnl.tag=../tnl \
miniglx.tag=../miniglx
tnl.tag=../tnl
GENERATE_TAGFILE = core.tag
ALLEXTERNALS = NO
PERL_PATH =

226
doxygen/core_subset.doxy Normal file
View File

@@ -0,0 +1,226 @@
# Doxyfile 0.1
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "Mesa Core"
PROJECT_NUMBER =
OUTPUT_DIRECTORY =
OUTPUT_LANGUAGE = English
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
INTERNAL_DOCS = YES
STRIP_CODE_COMMENTS = YES
CASE_SENSE_NAMES = YES
SHORT_NAMES = NO
HIDE_SCOPE_NAMES = NO
VERBATIM_HEADERS = YES
SHOW_INCLUDE_FILES = YES
JAVADOC_AUTOBRIEF = NO
INHERIT_DOCS = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 8
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
ALIASES =
ENABLED_SECTIONS = subset
MAX_INITIALIZER_LINES = 30
OPTIMIZE_OUTPUT_FOR_C = NO
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_FORMAT =
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../src/
FILE_PATTERNS = \
accum.h \
attrib.h \
blend.[ch] \
buffers.[ch] \
dd.h \
debug.h \
depth.h \
dlist.h \
context.[ch] \
config.h \
colormac.h \
colortab.h \
enable.h \
enums.h \
eval.h \
extensions.h \
feedback.[ch] \
fog.h \
get.h \
glheader.h \
glthread.h \
hash.[ch] \
hint.h \
histogram.h \
image.[ch] \
imports.[ch] \
lines.[ch] \
light.h \
matrix.[ch] \
macros.h \
mmath.h \
mtypes.h \
pixel.h \
points.[ch] \
polygon.[ch] \
rastpos.[ch] \
simple_list.h \
state.[ch] \
stencil.[ch] \
subset_*.c \
texformat.h \
teximage.h \
texstate.h \
texstore.h \
texobj.[ch] \
texutil_tmp.h \
varray.h
RECURSIVE = NO
EXCLUDE =
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = core_subset
HTML_HEADER = header_subset.html
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT =
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT =
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT =
MAN_EXTENSION =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH = ../include/
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
TAGFILES = \
math_subset.tag=../math_subset \
miniglx.tag=../miniglx
GENERATE_TAGFILE = core_subset.tag
ALLEXTERNALS = NO
PERL_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
TEMPLATE_RELATIONS = YES
HIDE_UNDOC_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
CGI_NAME =
CGI_URL =
DOC_URL =
DOC_ABSPATH =
BIN_ABSPATH =
EXT_DOC_PATHS =

View File

@@ -3,12 +3,10 @@
</head>
<body><center>
<a href="../core/index.html">Mesa Core</a>&nbsp;
<a href="../miniglx/index.html">MiniGLX</a>&nbsp;
<a href="../array_cache/index.html">array_cache</a>&nbsp;
<a href="../math/index.html">math</a>&nbsp;
<a href="../swrast/index.html">swrast</a>&nbsp;
<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>
</center>

View File

@@ -0,0 +1,9 @@
<html><head><title>Mesa Source Code Documentation</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head>
<body><center>
<a href="../core_subset/index.html">Mesa Core</a>&nbsp;
<a href="../math_subset/index.html">math</a>&nbsp;
<a href="../miniglx/index.html">MiniGLX</a>&nbsp;
<a href="../radeon_subset/index.html">radeon_subset</a>&nbsp;
</center>

View File

@@ -1,11 +1,12 @@
default:
default: subset
full:
doxygen tnl_dd.doxy
doxygen array_cache.doxy
doxygen math.doxy
doxygen swrast.doxy
doxygen swrast_setup.doxy
doxygen tnl.doxy
doxygen miniglx.doxy
doxygen core.doxy
echo "Building again, to resolve tags"
doxygen tnl_dd.doxy
@@ -14,11 +15,33 @@ default:
doxygen swrast.doxy
doxygen swrast_setup.doxy
doxygen tnl.doxy
doxygen core.doxy
subset:
doxygen core_subset.doxy
doxygen math_subset.doxy
doxygen miniglx.doxy
echo "Building again, to resolve tags"
doxygen core_subset.doxy
doxygen math_subset.doxy
doxygen miniglx.doxy
doxygen radeon_subset.doxy
doxygen radeonfb.doxy
doxygen radeondrm.doxy
doxygen agpgart.doxy
clean:
rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx radeon_subset
rm -rf \
array_cache \
core \
core_subset \
math \
math_subset \
swrast \
swrast_setup \
tnl_dd \
tnl \
miniglx \
radeon_subset
rm -rf *.tag

177
doxygen/math_subset.doxy Normal file
View File

@@ -0,0 +1,177 @@
# Doxyfile 0.1
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "Mesa math module"
PROJECT_NUMBER =
OUTPUT_DIRECTORY = .
OUTPUT_LANGUAGE = English
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
INTERNAL_DOCS = NO
STRIP_CODE_COMMENTS = YES
CASE_SENSE_NAMES = YES
SHORT_NAMES = NO
HIDE_SCOPE_NAMES = NO
VERBATIM_HEADERS = YES
SHOW_INCLUDE_FILES = YES
JAVADOC_AUTOBRIEF = NO
INHERIT_DOCS = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 8
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
ALIASES =
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
OPTIMIZE_OUTPUT_FOR_C = YES
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_FORMAT =
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../src/math/
FILE_PATTERNS = m_matrix.[ch]
RECURSIVE = NO
EXCLUDE =
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = math_subset
HTML_HEADER = header_subset.html
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT =
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT =
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT =
MAN_EXTENSION =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
TAGFILES = core_subset.tag=../core_subset
GENERATE_TAGFILE = math_subset.tag
ALLEXTERNALS = NO
PERL_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
TEMPLATE_RELATIONS = YES
HIDE_UNDOC_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
CGI_NAME =
CGI_URL =
DOC_URL =
DOC_ABSPATH =
BIN_ABSPATH =
EXT_DOC_PATHS =

View File

@@ -80,7 +80,7 @@ IGNORE_PREFIX =
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = miniglx
HTML_HEADER = header.html
HTML_HEADER = header_subset.html
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
@@ -143,14 +143,9 @@ SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
TAGFILES = core.tag=../core \
tnl_dd.tag=../tnl_dd \
array_cache.tag=../array_cache \
math.tag=../math \
swrast.tag=../swrast \
swrast_setup.tag=../swrast_setup \
tnl.tag=../tnl \
array_cache.tag=array_cache
TAGFILES = \
core_subset.tag=../core_subset \
math_subset.tag=../math_subset
GENERATE_TAGFILE = miniglx.tag
ALLEXTERNALS = NO
PERL_PATH =

View File

@@ -103,7 +103,7 @@ IGNORE_PREFIX =
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = radeon_subset
HTML_HEADER = header.html
HTML_HEADER = header_subset.html
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
@@ -166,15 +166,10 @@ SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
TAGFILES = core.tag=../core \
tnl_dd.tag=../tnl_dd \
array_cache.tag=../array_cache \
math.tag=../math \
swrast.tag=../swrast \
swrast_setup.tag=../swrast_setup \
tnl.tag=../tnl \
miniglx.tag=../miniglx \
array_cache.tag=array_cache
TAGFILES = \
core_subset.tag=../core_subset \
math_subset.tag=../math_subset \
miniglx.tag=../miniglx
GENERATE_TAGFILE = radeon_subset.tag
ALLEXTERNALS = NO
PERL_PATH =

1058
doxygen/radeondrm.doxy Normal file

File diff suppressed because it is too large Load Diff

1051
doxygen/radeonfb.doxy Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
/* $Id: gl.h,v 1.72 2002/10/17 19:39:31 kschultz Exp $ */
/*
* Mesa 3-D graphics library
* Version: 4.1
* Version: 5.0.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -2646,6 +2645,13 @@ GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid
#endif /* GL_APPLE_ycbcr_422 */
#ifndef GL_ATI_texture_env_combine3
#define GL_ATI_texture_env_combine3 1
#define GL_MODULATE_ADD_ATI 0x8744
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
#define GL_MODULATE_SUBTRACT_ATI 0x8746
#endif
/**********************************************************************
* Begin system-specific stuff

View File

@@ -2423,6 +2423,11 @@ extern "C" {
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
#endif
#ifndef GL_ATI_texture_env_combine3
#define GL_MODULATE_ADD_ATI 0x8744
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
#define GL_MODULATE_SUBTRACT_ATI 0x8746
#endif
/*************************************************************/
@@ -5016,6 +5021,9 @@ GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum);
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
#endif
#ifndef GL_ATI_texture_env_combine3
#define GL_ATI_texture_env_combine3 1
#endif
#ifdef __cplusplus
}

View File

@@ -14,12 +14,12 @@ PROGS = gears \
# make executable from .c file:
.c: $(LIB_DEP)
gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lm -o $@
gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lGLU -lm -o $@
default: $(PROGS)
clean:
-rm *.o *~
-rm -f *.o *~ $(PROGS)

View File

@@ -1,4 +1,4 @@
/* $Id: bounce.c,v 1.3.8.1 2003/02/23 19:25:07 keithw Exp $ */
/* $Id: bounce.c,v 1.3.8.2 2003/03/22 08:40:35 keithw Exp $ */
/*
* Bouncing ball demo.
@@ -115,15 +115,15 @@ draw(void)
glColor3f(0, 1, 1);
glBegin(GL_LINES);
for (i = -5; i <= 5; i++) {
glVertex2i(i, -5);
glVertex2i(i, 5);
glVertex2f(i, -5);
glVertex2f(i, 5);
}
for (i = -5; i <= 5; i++) {
glVertex2i(-5, i);
glVertex2i(5, i);
glVertex2f(-5, i);
glVertex2f(5, i);
}
for (i = -5; i <= 5; i++) {
glVertex2i(i, -5);
glVertex2f(i, -5);
glVertex2f(i * 1.15, -5.9);
}
glVertex2f(-5.3, -5.35);

View File

@@ -1,4 +1,4 @@
/* $Id: isosurf.c,v 1.15.4.1 2003/02/23 21:04:25 keithw Exp $ */
/* $Id: isosurf.c,v 1.15.4.3 2003/04/07 22:27:23 keithw Exp $ */
/*
* Display an isosurface of 3-D wind speed volume.
@@ -37,52 +37,21 @@
#define GL_GLEXT_LEGACY
#include "GL/glut.h"
#include "readtex.c" /* I know, this is a hack. KW: me too. */
#include "readtex.c"
#define TEXTURE_FILE "../images/reflect.rgb"
#define LIT 0x00000001
#define UNLIT 0x00000002
#define REFLECT 0x00000004
#define POINT_FILTER 0x00000008
#define LINEAR_FILTER 0x00000010
#define GLVERTEX 0x00000020
#define DRAW_ELTS 0x00000040
#define DRAW_ARRAYS 0x00000080
#define ARRAY_ELT 0x00000100
#define LOCKED 0x00000200
#define UNLOCKED 0x00000400
#define IMMEDIATE 0x00000800
#define DISPLAYLIST 0x00001000
#define SHADE_SMOOTH 0x00002000
#define SHADE_FLAT 0x00004000
#define TRIANGLES 0x00008000
#define STRIPS 0x00010000
#define POINTS 0x00020000
#define USER_CLIP 0x00040000
#define NO_USER_CLIP 0x00080000
#define MATERIALS 0x00100000
#define NO_MATERIALS 0x00200000
#define FOG 0x00400000
#define NO_FOG 0x00800000
#define QUIT 0x01000000
#define GLINFO 0x02000000
#define STIPPLE 0x04000000
#define NO_STIPPLE 0x08000000
#define POLYGON_FILL 0x10000000
#define POLYGON_LINE 0x20000000
#define LIGHT_MASK (LIT|UNLIT|REFLECT)
#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT)
#define DLIST_MASK (IMMEDIATE|DISPLAYLIST)
#define LOCK_MASK (LOCKED|UNLOCKED)
#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
#define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
#define FOG_MASK (FOG|NO_FOG)
#define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
#define POLYGON_MASK (POLYGON_FILL|POLYGON_LINE)
#define MAXVERTS 10000
static GLint maxverts = MAXVERTS;
@@ -147,27 +116,6 @@ static void read_surface( char *filename )
static void print_flags( const char *msg, GLuint flags )
{
fprintf(stderr,
"%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
msg, flags,
(flags & GLVERTEX) ? "glVertex, " : "",
(flags & DRAW_ARRAYS) ? "glDrawArrays, " : "",
(flags & DRAW_ELTS) ? "glDrawElements, " : "",
(flags & ARRAY_ELT) ? "glArrayElement, " : "",
(flags & LOCKED) ? "locked arrays, " : "",
(flags & TRIANGLES) ? "GL_TRIANGLES, " : "",
(flags & STRIPS) ? "GL_TRIANGLE_STRIP, " : "",
(flags & POINTS) ? "GL_POINTS, " : "",
(flags & DISPLAYLIST) ? "as a displaylist, " : "",
(flags & LIT) ? "lit, " : "",
(flags & UNLIT) ? "unlit, " : "",
(flags & REFLECT) ? "reflect, " : "",
(flags & SHADE_FLAT) ? "flat-shaded, " : "",
(flags & USER_CLIP) ? "user_clip, " : "",
(flags & MATERIALS) ? "materials, " : "",
(flags & FOG) ? "fog, " : "",
(flags & STIPPLE) ? "stipple, " : "",
(flags & POLYGON_LINE) ? "polygon mode line, " : "");
}
@@ -372,134 +320,19 @@ static void draw_surface( unsigned int with_state )
{
GLint i, j;
if (with_state & DISPLAYLIST) {
if ((with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK|MATERIAL_MASK)) !=
dlist_state) {
/*
*/
fprintf(stderr, "rebuilding displaylist\n");
if (dlist_state)
glDeleteLists( surf1, 1 );
switch (with_state & (PRIMITIVE_MASK)) {
dlist_state = with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK|
MATERIAL_MASK);
surf1 = glGenLists(1);
glNewList(surf1, GL_COMPILE);
draw_surface( dlist_state );
glEndList();
}
glCallList( surf1 );
return;
}
switch (with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
#ifdef GL_EXT_vertex_array
case (DRAW_ELTS|TRIANGLES):
if (with_state & MATERIALS) {
for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
GLuint nr = MIN(num_tri_verts-i, 600);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
}
} else {
glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
tri_indices );
}
break;
case (DRAW_ARRAYS|TRIANGLES):
glDrawArraysEXT( GL_TRIANGLES, 0, (numverts-2)*3 );
break;
case (ARRAY_ELT|TRIANGLES):
if (with_state & MATERIALS) {
for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
GLuint nr = MIN(num_tri_verts-i, 600);
GLuint k;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
glBegin( GL_TRIANGLES );
for (k = 0 ; k < nr ; k++)
glArrayElement( tri_indices[i+k] );
glEnd();
}
} else {
glBegin( GL_TRIANGLES );
for (i = 0 ; i < num_tri_verts ; i++)
glArrayElement( tri_indices[i] );
glEnd();
}
break;
/* Uses the original arrays (including duplicate elements):
*/
case (DRAW_ARRAYS|STRIPS):
glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
break;
case (DRAW_ELTS|STRIPS):
glDrawElements( GL_TRIANGLE_STRIP, numverts,
GL_UNSIGNED_INT, strip_indices );
break;
/* Uses the original arrays (including duplicate elements):
*/
case (ARRAY_ELT|STRIPS):
glBegin( GL_TRIANGLE_STRIP );
for (i = 0 ; i < numverts ; i++)
glArrayElement( i );
glEnd();
break;
case (DRAW_ARRAYS|POINTS):
glDrawArraysEXT( GL_POINTS, 0, numuniq );
break;
case (DRAW_ELTS|POINTS):
/* can use numuniq with strip_indices as strip_indices[i] == i.
*/
glDrawElements( GL_POINTS, numuniq,
GL_UNSIGNED_INT, strip_indices );
break;
case (ARRAY_ELT|POINTS):
/* just emit each unique element once:
*/
glBegin( GL_POINTS );
for (i = 0 ; i < numuniq ; i++)
glArrayElement( i );
glEnd();
break;
#endif
case (GLVERTEX|TRIANGLES):
if (with_state & MATERIALS) {
for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
GLuint nr = MIN(num_tri_verts-i, 600);
GLuint k;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
glBegin( GL_TRIANGLES );
for (k = 0 ; k < nr ; k++) {
glColor3fv( &compressed_data[tri_indices[i+k]][3] );
glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
}
glEnd();
}
} else {
case (0|TRIANGLES):
glBegin( GL_TRIANGLES );
for (i = 0 ; i < num_tri_verts ; i++) {
glColor3fv( &compressed_data[tri_indices[i]][3] );
glVertex3fv( &compressed_data[tri_indices[i]][0] );
}
glEnd();
}
break;
case (GLVERTEX|POINTS):
case (0|POINTS):
/* Renders all points, but not in strip order... Shouldn't be a
* problem, but people may be confused as to why points are so
* much faster in this demo... And why cva doesn't help them...
@@ -512,7 +345,7 @@ static void draw_surface( unsigned int with_state )
glEnd();
break;
case (GLVERTEX|STRIPS):
case (0|STRIPS):
glBegin( GL_TRIANGLE_STRIP );
for (i=0;i<numverts;i++) {
glColor3fv( &data[i][0] );
@@ -523,7 +356,7 @@ static void draw_surface( unsigned int with_state )
default:
fprintf(stderr, "unimplemented mode %x...\n",
(with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK)));
(with_state & (PRIMITIVE_MASK)));
break;
}
}
@@ -636,39 +469,6 @@ static void ModeMenu(int m)
return;
}
if (CHANGED(state, m, FILTER_MASK)) {
UPDATE(state, m, FILTER_MASK);
if (m & LINEAR_FILTER) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
}
if (CHANGED(state, m, LIGHT_MASK)) {
UPDATE(state, m, LIGHT_MASK);
if (m & LIT) {
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
}
else if (m & UNLIT) {
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
}
else if (m & REFLECT) {
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_2D);
}
}
if (CHANGED(state, m, SHADE_MASK)) {
UPDATE(state, m, SHADE_MASK);
if (m & SHADE_SMOOTH)
@@ -678,77 +478,12 @@ static void ModeMenu(int m)
}
if (CHANGED(state, m, CLIP_MASK)) {
UPDATE(state, m, CLIP_MASK);
if (m & USER_CLIP) {
glEnable(GL_CLIP_PLANE0);
} else {
glDisable(GL_CLIP_PLANE0);
}
if (m & (PRIMITIVE_MASK)) {
UPDATE(state, m, (PRIMITIVE_MASK));
}
if (CHANGED(state, m, FOG_MASK)) {
UPDATE(state, m, FOG_MASK);
if (m & FOG) {
glEnable(GL_FOG);
}
else {
glDisable(GL_FOG);
}
}
if (CHANGED(state, m, STIPPLE_MASK)) {
UPDATE(state, m, STIPPLE_MASK);
if (m & STIPPLE) {
glEnable(GL_POLYGON_STIPPLE);
}
else {
glDisable(GL_POLYGON_STIPPLE);
}
}
if (CHANGED(state, m, POLYGON_MASK)) {
UPDATE(state, m, POLYGON_MASK);
if (m & POLYGON_FILL) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
}
#ifdef GL_EXT_vertex_array
if (CHANGED(state, m, (LOCK_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
{
if (m & (PRIMITIVE_MASK)) {
UPDATE(state, m, (PRIMITIVE_MASK));
}
if (m & (RENDER_STYLE_MASK)) {
UPDATE(state, m, (RENDER_STYLE_MASK));
}
if (m & LOCK_MASK) {
UPDATE(state, m, (LOCK_MASK));
}
print_flags("primitive", state & PRIMITIVE_MASK);
print_flags("render style", state & RENDER_STYLE_MASK);
}
#endif
if (m & DLIST_MASK) {
UPDATE(state, m, DLIST_MASK);
}
if (m & MATERIAL_MASK) {
UPDATE(state, m, MATERIAL_MASK);
}
print_flags("new flags", state);
glutPostRedisplay();
}
@@ -805,24 +540,17 @@ static void Init(int argc, char *argv[])
expand_arrays();
make_tri_indices();
if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
printf("Error: couldn't load texture image\n");
exit(1);
}
/* if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { */
/* printf("Error: couldn't load texture image\n"); */
/* exit(1); */
/* } */
}
}
ModeMenu(SHADE_SMOOTH|
UNLIT|
POINT_FILTER|
NO_USER_CLIP|
NO_MATERIALS|
NO_FOG|
NO_STIPPLE|
IMMEDIATE|
STRIPS|
UNLOCKED|
GLVERTEX);
TRIANGLES|
0);
if (PrintInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
@@ -848,30 +576,9 @@ static void Key( unsigned char key, int x, int y )
switch (key) {
case 27:
exit(0);
case 'f':
ModeMenu((state ^ FOG_MASK) & FOG_MASK);
break;
case 's':
ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
break;
case 't':
ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
break;
case 'l':
ModeMenu((state ^ LIGHT_MASK) & (LIT|UNLIT));
break;
case 'm':
ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
break;
case 'c':
ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
break;
case 'v':
ModeMenu((LOCKED|IMMEDIATE|DRAW_ELTS|TRIANGLES) & allowed);
break;
case 'V':
ModeMenu(UNLOCKED|IMMEDIATE|GLVERTEX|STRIPS);
break;
case 'b':
Benchmark(5.0, 0);
break;
@@ -888,24 +595,6 @@ static void Key( unsigned char key, int x, int y )
set_matrix();
glutPostRedisplay();
break;
case '-':
case '_':
plane[3] += 2.0;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClipPlane(GL_CLIP_PLANE0, plane);
set_matrix();
glutPostRedisplay();
break;
case '+':
case '=':
plane[3] -= 2.0;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClipPlane(GL_CLIP_PLANE0, plane);
set_matrix();
glutPostRedisplay();
break;
case ' ':
Init(0,0);
break;
@@ -999,16 +688,6 @@ int main(int argc, char **argv)
/* Make sure server supports the vertex array extension */
extensions = (char *) glGetString( GL_EXTENSIONS );
if (!strstr( extensions, "GL_EXT_vertex_array" ))
{
printf("Vertex arrays not supported by this renderer\n");
allowed &= ~(LOCKED|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT);
}
else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
{
printf("Compiled vertex arrays not supported by this renderer\n");
allowed &= ~LOCKED;
}
Init(argc, argv);
ModeMenu(arg_mode);
@@ -1016,43 +695,15 @@ int main(int argc, char **argv)
glutCreateMenu(ModeMenu);
glutAddMenuEntry("GL info", GLINFO);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Lit", LIT);
glutAddMenuEntry("Unlit", UNLIT);
glutAddMenuEntry("Reflect", REFLECT);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Smooth", SHADE_SMOOTH);
glutAddMenuEntry("Flat", SHADE_FLAT);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Fog", FOG);
glutAddMenuEntry("No Fog", NO_FOG);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Stipple", STIPPLE);
glutAddMenuEntry("No Stipple", NO_STIPPLE);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL);
glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Point Filtered", POINT_FILTER);
glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
glutAddMenuEntry("", 0);
glutAddMenuEntry("GL_TRIANGLES", TRIANGLES);
glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS);
glutAddMenuEntry("GL_POINTS", POINTS);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Displaylist", DISPLAYLIST);
glutAddMenuEntry("Immediate", IMMEDIATE);
glutAddMenuEntry("", 0);
if (allowed & LOCKED) {
glutAddMenuEntry("Locked Arrays (CVA)", LOCKED);
glutAddMenuEntry("Unlocked Arrays", UNLOCKED);
glutAddMenuEntry("", 0);
}
glutAddMenuEntry("glVertex", GLVERTEX);
if (allowed & DRAW_ARRAYS) {
glutAddMenuEntry("glDrawElements", DRAW_ELTS);
glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS);
glutAddMenuEntry("glArrayElement", ARRAY_ELT);
}
glutAddMenuEntry("", 0);
glutAddMenuEntry("Quit", QUIT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
@@ -1062,9 +713,9 @@ int main(int argc, char **argv)
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Display);
/* Benchmark(5,0); */
/* Benchmark(5,0); */
/* Benchmark(5,0); */
Benchmark(5,0);
Benchmark(5,0);
Benchmark(5,0);
glutMainLoop();
return 0;
}

View File

@@ -680,18 +680,13 @@ loadpic(void)
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA,
GL_UNSIGNED_BYTE,
(GLvoid *) (&terrainpic[0][0])))) {
fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
exit(-1);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_RGBA, 256, 256, GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid *) terrainpic);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

View File

@@ -1,4 +1,4 @@
/* $Id: texobj.c,v 1.6.6.1 2003/02/23 19:25:07 keithw Exp $ */
/* $Id: texobj.c,v 1.6.6.2 2003/03/22 08:40:35 keithw Exp $ */
/*
* Example of using the 1.1 texture object functions.
@@ -50,7 +50,7 @@ static void draw( void )
#endif
}
else {
glCallList( TexObj[0] );
/* glCallList( TexObj[0] ); */
}
glBegin( GL_POLYGON );
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
@@ -70,7 +70,7 @@ static void draw( void )
#endif
}
else {
glCallList( TexObj[1] );
/* glCallList( TexObj[1] ); */
}
glBegin( GL_POLYGON );
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
@@ -166,8 +166,8 @@ static void init( void )
#endif
}
else {
TexObj[0] = glGenLists(2);
TexObj[1] = TexObj[0]+1;
/* TexObj[0] = glGenLists(2); */
/* TexObj[1] = TexObj[0]+1; */
}
/* setup first texture object */
@@ -178,7 +178,7 @@ static void init( void )
#endif
}
else {
glNewList( TexObj[0], GL_COMPILE );
/* glNewList( TexObj[0], GL_COMPILE ); */
}
/* red on white */
for (i=0;i<height;i++) {
@@ -201,7 +201,7 @@ static void init( void )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
if (!UseObj) {
glEndList();
/* glEndList(); */
}
/* end of texture object */
@@ -214,7 +214,7 @@ static void init( void )
/* assert(!glIsTexture(TexObj[1] + 999)); */
}
else {
glNewList( TexObj[1], GL_COMPILE );
/* glNewList( TexObj[1], GL_COMPILE ); */
}
/* green on blue */
for (i=0;i<height;i++) {
@@ -235,7 +235,7 @@ static void init( void )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
if (!UseObj) {
glEndList();
/* glEndList(); */
}
/* end texture object */

View File

@@ -17,12 +17,14 @@ PROGS = prim \
# make executable from .c file:
.c: $(LIB_DEP)
gcc -I../include -g $< -L../lib -lglut -lGL -lm -o $@
gcc -I../include -g $< -L../lib -lglut -lGL -lGLU -lm -o $@
default: $(PROGS)
clean:
-rm *.o *~
clean: clean_here
clean_here:
rm -f *.o *~ $(PROGS)

View File

@@ -62,7 +62,7 @@ static void Init(void)
GLint i;
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearIndex(0.0);
/* glClearIndex(0.0); */
if (!rgb) {
for (i = 0; i < 16; i++) {
@@ -71,7 +71,7 @@ static void Init(void)
}
}
glPolygonStipple(stippleBits);
/* glPolygonStipple(stippleBits); */
antiAlias = GL_FALSE;
stipple = GL_FALSE;
@@ -135,11 +135,11 @@ static void Draw(void)
}
glBegin(GL_TRIANGLES);
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexi(ci1);
glColor3fv(RGBMap[COLOR_BLUE]);
glVertex3f( 0.9, -0.9, -30.0);
glVertex3f( 0.9, 0.9, -30.0);
glVertex3f(-0.9, 0.0, -30.0);
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexi(ci2);
glColor3fv(RGBMap[COLOR_GREEN]);
glVertex3f(-0.9, -0.9, -40.0);
glVertex3f(-0.9, 0.9, -40.0);
glVertex3f( 0.9, 0.0, -25.0);

View File

@@ -141,7 +141,7 @@ static void Draw(void)
for (i = 0; i < 360; i += 5) {
glRotatef(5.0, 0,0,1);
(rgb) ? glColor3f(1.0, 1.0, 0.0) : glIndexi(ci);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3fv(pntA);
glVertex3fv(pntB);
@@ -199,7 +199,7 @@ int main(int argc, char **argv)
glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
windType = GLUT_RGB;
windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(windType);

View File

@@ -153,9 +153,9 @@ static void Draw(void)
/* glPointSize(size); */
if (mode) {
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED);
glColor3f(1.0, 0.0, 0.0);
} else {
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_RED);
glColor3f(1.0, 0.0, 0.0);
}
glBegin(GL_POINTS);
glVertex3fv(point);

View File

@@ -126,18 +126,18 @@ static void Point(void)
glBegin(GL_POINTS);
SetColor(COLOR_WHITE);
glVertex2i(0, 0);
glVertex2f(0, 0);
for (i = 1; i < 8; i++) {
GLint j = i * 2;
SetColor(COLOR_BLACK+i);
glVertex2i(-j, -j);
glVertex2i(-j, 0);
glVertex2i(-j, j);
glVertex2i(0, j);
glVertex2i(j, j);
glVertex2i(j, 0);
glVertex2i(j, -j);
glVertex2i(0, -j);
glVertex2f(-j, -j);
glVertex2f(-j, 0);
glVertex2f(-j, j);
glVertex2f(0, j);
glVertex2f(j, j);
glVertex2f(j, 0);
glVertex2f(j, -j);
glVertex2f(0, -j);
}
glEnd();
}
@@ -152,8 +152,8 @@ static void Lines(void)
for (i = 1; i < 8; i++) {
SetColor(COLOR_BLACK+i);
glBegin(GL_LINES);
glVertex2i(-boxW/4, -boxH/4);
glVertex2i(boxW/4, boxH/4);
glVertex2f(-boxW/4, -boxH/4);
glVertex2f(boxW/4, boxH/4);
glEnd();
glTranslatef(4, 0, 0);
}
@@ -161,7 +161,7 @@ static void Lines(void)
glPopMatrix();
glBegin(GL_LINES);
glVertex2i(0, 0);
glVertex2f(0, 0);
glEnd();
}
@@ -180,7 +180,7 @@ static void LineStrip(void)
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2i(0, 0);
glVertex2f(0, 0);
glEnd();
}
@@ -218,11 +218,11 @@ static void LineLoop(void)
SetColor(COLOR_GREEN);
glBegin(GL_POINTS);
glVertex2i(0, 0);
glVertex2f(0, 0);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2i(0, 0);
glVertex2f(0, 0);
glEnd();
}
@@ -231,16 +231,16 @@ static void Bitmap(void)
glBegin(GL_LINES);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/2, 0);
glVertex2i(boxW/2, 0);
glVertex2i(0, -boxH/2);
glVertex2i(0, boxH/2);
glVertex2f(-boxW/2, 0);
glVertex2f(boxW/2, 0);
glVertex2f(0, -boxH/2);
glVertex2f(0, boxH/2);
SetColor(COLOR_RED);
glVertex2i(0, -3);
glVertex2i(0, -3+OPENGL_HEIGHT);
glVertex2f(0, -3);
glVertex2f(0, -3+OPENGL_HEIGHT);
SetColor(COLOR_BLUE);
glVertex2i(0, -3);
glVertex2i(OPENGL_WIDTH, -3);
glVertex2f(0, -3);
glVertex2f(OPENGL_WIDTH, -3);
glEnd();
SetColor(COLOR_GREEN);
@@ -257,23 +257,23 @@ static void Triangles(void)
glBegin(GL_TRIANGLES);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, -boxH/4);
glVertex2f(-boxW/4, -boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/8, -boxH/16);
glVertex2f(-boxW/8, -boxH/16);
SetColor(COLOR_BLUE);
glVertex2i(boxW/8, -boxH/16);
glVertex2f(boxW/8, -boxH/16);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, boxH/4);
glVertex2f(-boxW/4, boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/8, boxH/16);
glVertex2f(-boxW/8, boxH/16);
SetColor(COLOR_BLUE);
glVertex2i(boxW/8, boxH/16);
glVertex2f(boxW/8, boxH/16);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2i(0, 0);
glVertex2i(-100, 100);
glVertex2f(0, 0);
glVertex2f(-100, 100);
glEnd();
}
@@ -282,28 +282,28 @@ static void TriangleStrip(void)
glBegin(GL_TRIANGLE_STRIP);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, -boxH/4);
glVertex2f(-boxW/4, -boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/4, boxH/4);
glVertex2f(-boxW/4, boxH/4);
SetColor(COLOR_BLUE);
glVertex2i(0, -boxH/4);
glVertex2f(0, -boxH/4);
SetColor(COLOR_WHITE);
glVertex2i(0, boxH/4);
glVertex2f(0, boxH/4);
SetColor(COLOR_CYAN);
glVertex2i(boxW/4, -boxH/4);
glVertex2f(boxW/4, -boxH/4);
SetColor(COLOR_YELLOW);
glVertex2i(boxW/4, boxH/4);
glVertex2f(boxW/4, boxH/4);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(0, 0);
glVertex2i(-100, 100);
glVertex2f(0, 0);
glVertex2f(-100, 100);
glEnd();
}
static void TriangleFan(void)
{
GLint vx[8][2];
GLfloat vx[8][2];
GLint x0, y0, x1, y1, x2, y2, x3, y3;
GLint i;
@@ -327,16 +327,16 @@ static void TriangleFan(void)
glBegin(GL_TRIANGLE_FAN);
SetColor(COLOR_WHITE);
glVertex2i(0, 0);
glVertex2f(0, 0);
for (i = 0; i < 8; i++) {
SetColor(COLOR_WHITE-i);
glVertex2iv(vx[i]);
glVertex2fv(vx[i]);
}
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex2i(0, 0);
glVertex2i(-100, 100);
glVertex2f(0, 0);
glVertex2f(-100, 100);
glEnd();
}
@@ -349,7 +349,7 @@ static void Rect(void)
static void PolygonFunc(void)
{
GLint vx[8][2];
GLfloat vx[8][2];
GLint x0, y0, x1, y1, x2, y2, x3, y3;
GLint i;
@@ -374,13 +374,13 @@ static void PolygonFunc(void)
glBegin(GL_POLYGON);
for (i = 0; i < 8; i++) {
SetColor(COLOR_WHITE-i);
glVertex2iv(vx[i]);
glVertex2fv(vx[i]);
}
glEnd();
glBegin(GL_POLYGON);
glVertex2i(0, 0);
glVertex2i(100, 100);
glVertex2f(0, 0);
glVertex2f(100, 100);
glEnd();
}
@@ -389,28 +389,28 @@ static void Quads(void)
glBegin(GL_QUADS);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, -boxH/4);
glVertex2f(-boxW/4, -boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/8, -boxH/16);
glVertex2f(-boxW/8, -boxH/16);
SetColor(COLOR_BLUE);
glVertex2i(boxW/8, -boxH/16);
glVertex2f(boxW/8, -boxH/16);
SetColor(COLOR_WHITE);
glVertex2i(boxW/4, -boxH/4);
glVertex2f(boxW/4, -boxH/4);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, boxH/4);
glVertex2f(-boxW/4, boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/8, boxH/16);
glVertex2f(-boxW/8, boxH/16);
SetColor(COLOR_BLUE);
glVertex2i(boxW/8, boxH/16);
glVertex2f(boxW/8, boxH/16);
SetColor(COLOR_WHITE);
glVertex2i(boxW/4, boxH/4);
glVertex2f(boxW/4, boxH/4);
glEnd();
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(100, 100);
glVertex2i(-100, 100);
glVertex2f(0, 0);
glVertex2f(100, 100);
glVertex2f(-100, 100);
glEnd();
}
@@ -419,29 +419,30 @@ static void QuadStrip(void)
glBegin(GL_QUAD_STRIP);
SetColor(COLOR_GREEN);
glVertex2i(-boxW/4, -boxH/4);
glVertex2f(-boxW/4, -boxH/4);
SetColor(COLOR_RED);
glVertex2i(-boxW/4, boxH/4);
glVertex2f(-boxW/4, boxH/4);
SetColor(COLOR_BLUE);
glVertex2i(0, -boxH/4);
glVertex2f(0, -boxH/4);
SetColor(COLOR_WHITE);
glVertex2i(0, boxH/4);
glVertex2f(0, boxH/4);
SetColor(COLOR_CYAN);
glVertex2i(boxW/4, -boxH/4);
glVertex2f(boxW/4, -boxH/4);
SetColor(COLOR_YELLOW);
glVertex2i(boxW/4, boxH/4);
glVertex2f(boxW/4, boxH/4);
glEnd();
glBegin(GL_QUAD_STRIP);
glVertex2i(0, 0);
glVertex2i(100, 100);
glVertex2i(-100, 100);
glVertex2f(0, 0);
glVertex2f(100, 100);
glVertex2f(-100, 100);
glEnd();
}
static void Draw(void)
{
fprintf(stderr, "%s\n", __FUNCTION__);
glViewport(0, 0, windW, windH);
glDisable(GL_SCISSOR_TEST);

View File

@@ -255,7 +255,6 @@ static void Key(unsigned char key, int x, int y)
void Draw(void)
{
MoveStars();
ShowStars();
if (nitro > 0) {

View File

@@ -26,8 +26,8 @@ static void SetColor(int c)
{
if (glutGet(GLUT_WINDOW_RGBA))
glColor3fv(RGBMap[c]);
else
glIndexf(c);
/* else */
/* glIndexf(c); */
}
static void InitMap(void)

View File

@@ -278,11 +278,11 @@ static void Draw(void)
EndPrim();
if (showVerticies) {
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
glColor3fv(RGBMap[COLOR_RED]);
/* glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2); */
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
glColor3fv(RGBMap[COLOR_GREEN]);
/* glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2); */
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
glColor3fv(RGBMap[COLOR_BLUE]);
/* glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2); */
}
@@ -314,11 +314,11 @@ static void Draw(void)
SetColor(COLOR_RED);
BeginPrim();
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
glColor3fv(RGBMap[COLOR_RED]);
glVertex3fv(p0);
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
glColor3fv(RGBMap[COLOR_GREEN]);
glVertex3fv(p1);
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
glColor3fv(RGBMap[COLOR_BLUE]);
glVertex3fv(p2);
EndPrim();

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: manytex.c,v 1.4 2002/10/18 17:47:36 kschultz Exp $ */
/* $Id: manytex.c,v 1.4.4.1 2003/03/22 08:46:22 keithw Exp $ */
/*
* test handling of many texture maps
@@ -191,8 +191,8 @@ static void Init( void )
glBindTexture(GL_TEXTURE_2D, TextureID[i]);
if (i < LowPriorityCount)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
/* if (i < LowPriorityCount) */
/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); */
if (RandomSize) {
#if 0

View File

@@ -79,6 +79,8 @@ MakeWindow(Display * dpy, unsigned int width, unsigned int height)
/* Bind the rendering context and window */
glXMakeCurrent(dpy, win, ctx);
glViewport(0, 0, width, height);
return win;
}

View File

@@ -1,4 +1,4 @@
/* $Id: miniglxtest.c,v 1.1.4.7 2003/02/21 22:18:24 keithw Exp $ */
/* $Id: miniglxtest.c,v 1.1.4.9 2003/03/24 18:46:57 keithw Exp $ */
/*
* Test the mini GLX interface.
@@ -122,6 +122,8 @@ static Window make_rgb_db_window( Display *dpy,
glXMakeCurrent( dpy, win, ctx );
glViewport(0, 0, width, height);
return win;
}
@@ -161,7 +163,6 @@ int foo( )
XMapWindow( dpy, win );
#if !USE_MINI_GLX
{
XEvent e;
while (1) {
@@ -171,8 +172,6 @@ int foo( )
}
}
}
#endif
event_loop( dpy, win );

112
progs/tests/sample_server.c Normal file
View File

@@ -0,0 +1,112 @@
/* $Id: sample_server.c,v 1.1.2.2 2003/04/17 15:47:46 keithw Exp $ */
/*
* Sample server that just keeps first available window mapped.
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/miniglx.h>
struct client {
struct client *next;
Window windowid;
int mappable;
};
struct client *clients = 0, *mapped_client = 0;
static struct client *find_client( Window id )
{
struct client *c;
for (c = clients ; c ; c = c->next)
if (c->windowid == id)
return c;
return 0;
}
int main( int argc, char *argv[] )
{
Display *dpy;
XEvent ev;
dpy = __miniglx_StartServer(NULL);
if (!dpy) {
fprintf(stderr, "Error: __miniglx_StartServer failed\n");
return 1;
}
while (XNextEvent( dpy, &ev )) {
struct client *c;
switch (ev.type) {
case MapRequest:
fprintf(stderr, "MapRequest\n");
c = find_client(ev.xmaprequest.window);
if (!c) break;
c->mappable = True;
break;
case UnmapNotify:
fprintf(stderr, "UnmapNotify\n");
c = find_client(ev.xunmap.window);
if (!c) break;
c->mappable = False;
if (c == mapped_client)
mapped_client = 0;
break;
case CreateNotify:
fprintf(stderr, "CreateNotify\n");
c = malloc(sizeof(*c));
c->next = clients;
c->windowid = ev.xcreatewindow.window;
c->mappable = False;
clients = c;
break;
case DestroyNotify:
fprintf(stderr, "DestroyNotify\n");
c = find_client(ev.xdestroywindow.window);
if (!c) break;
if (c == clients)
clients = c->next;
else {
struct client *t;
for (t = clients ; t->next != c ; t = t->next)
;
t->next = c->next;
}
if (c == mapped_client)
mapped_client = 0;
free(c);
break;
default:
break;
}
/* Search for first mappable client if none already mapped.
*/
if (!mapped_client) {
for (c = clients ; c ; c = c->next) {
if (c->mappable) {
XMapWindow( dpy, c->windowid );
mapped_client = c;
break;
}
}
}
}
XCloseDisplay( dpy );
return 0;
}

View File

@@ -0,0 +1,227 @@
/* $Id: sample_server2.c,v 1.1.2.4 2003/04/29 09:41:01 keithw Exp $ */
/*
* Sample server that just keeps first available window mapped.
*
* It also reads and echos anything that happens on stdin as an
* example of tracking events from sources other than miniglx clients.
*
* It reads & writes without blocking, so that eg. piping a lot of
* text to stdin and then hitting 'ctrl-S' on the output stream won't
* cause it to stop handling miniglx events.
*
* See select_tut in the linux manual pages for a good overview of the
* select(2) system call.
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/miniglx.h>
#include <errno.h>
#include <assert.h>
struct client {
struct client *next;
Window windowid;
int mappable;
};
struct client *clients = 0, *mapped_client = 0;
#define BUFSZ 4096
char rbuf[BUFSZ];
int rbuf_count;
static struct client *find_client( Window id )
{
struct client *c;
for (c = clients ; c ; c = c->next)
if (c->windowid == id)
return c;
return 0;
}
int main( int argc, char *argv[] )
{
Display *dpy;
XEvent ev;
int autostart = 0;
if (argc == 2 && strcmp(argv[1], "-autostart") == 0)
autostart = 1;
dpy = __miniglx_StartServer(NULL);
if (!dpy) {
fprintf(stderr, "Error: __miniglx_StartServer failed\n");
return 1;
}
/* How is vt switching communicated through the XNextEvent interface?
*/
while (1) {
int r, n;
struct timeval tv;
fd_set rfds, wfds;
int bored = 0;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
if (rbuf_count) {
FD_SET( 1, &wfds ); /* notify when we can write out buffer */
n = 1;
}
else {
FD_SET( 0, &rfds ); /* else notify when new data to read */
n = 0;
}
/* __miniglx_Select waits until any of these file groups becomes
* readable/writable/etc (like regular select), until timeout
* expires (like regular select), until a signal is received
* (like regular select) or until an event is available for
* XCheckMaskEvent().
*/
r = __miniglx_Select( dpy, n+1, &rfds, &wfds, 0, &tv );
/* This can happen if select() is interrupted by a signal:
*/
if (r < 0 && errno != EINTR && errno != EAGAIN) {
perror ("select()");
exit (1);
}
if (tv.tv_sec == 0 && tv.tv_usec == 0)
bored = 1;
/* Check and handle events on our local file descriptors
*/
if (FD_ISSET( 0, &rfds )) {
/* Something on stdin */
assert(rbuf_count == 0);
r = read(0, rbuf, BUFSZ);
if (r < 1) {
perror("read");
abort();
}
rbuf_count = r;
}
if (FD_ISSET( 1, &wfds )) {
/* Can write to stdout */
assert(rbuf_count > 0);
r = write(1, rbuf, rbuf_count);
if (r < 1) {
perror("write");
abort();
}
rbuf_count -= r;
if (rbuf_count)
memmove(rbuf + r, rbuf, rbuf_count);
}
/* Check and handle events generated by miniglx:
*/
while (XCheckMaskEvent( dpy, ~0, &ev )) {
struct client *c;
bored = 0;
fprintf(stderr, "Received event %d\n", ev.type);
switch (ev.type) {
case CreateNotify:
fprintf(stderr, "CreateNotify -- new client\n");
c = malloc(sizeof(*c));
c->next = clients;
c->windowid = ev.xcreatewindow.window;
c->mappable = False;
clients = c;
break;
case DestroyNotify:
fprintf(stderr, "DestroyNotify\n");
c = find_client(ev.xdestroywindow.window);
if (!c) break;
if (c == clients)
clients = c->next;
else {
struct client *t;
for (t = clients ; t->next != c ; t = t->next)
;
t->next = c->next;
}
if (c == mapped_client)
mapped_client = 0;
free(c);
break;
case MapRequest:
fprintf(stderr, "MapRequest\n");
c = find_client(ev.xmaprequest.window);
if (!c) break;
c->mappable = True;
break;
case UnmapNotify:
fprintf(stderr, "UnmapNotify\n");
c = find_client(ev.xunmap.window);
if (!c) break;
c->mappable = False;
if (c == mapped_client)
mapped_client = 0;
break;
default:
break;
}
}
/* Search for first mappable client if none already mapped.
*/
if (!mapped_client) {
struct client *c;
for (c = clients ; c ; c = c->next) {
if (c->mappable) {
XMapWindow( dpy, c->windowid );
mapped_client = c;
break;
}
}
if (!clients && autostart) {
system("nohup ./texline &");
system("nohup ./manytex &");
}
}
else if (bored) {
struct client *c;
/* bored of mapped client now, let's try & find another one */
for (c = mapped_client->next ; c && !c->mappable ; c = c->next)
;
if (!c)
for (c = clients ; c && !c->mappable ; c = c->next)
;
if (c && c != mapped_client) {
XUnmapWindow( dpy, mapped_client->windowid );
XMapWindow( dpy, c->windowid );
mapped_client = c;
}
else
fprintf(stderr, "I'm bored!\n");
}
}
XCloseDisplay( dpy );
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $Id: texline.c,v 1.4 2002/08/17 00:30:36 brianp Exp $ */
/* $Id: texline.c,v 1.4.6.2 2003/05/01 06:54:21 keithw Exp $ */
/*
* Test textured lines.
@@ -17,7 +17,7 @@
#define TEXTURE_FILE "../images/girl.rgb"
static GLboolean Antialias = GL_FALSE;
static GLboolean Animate = GL_FALSE;
static GLboolean Animate = GL_TRUE;
static GLint Texture = 1;
static GLboolean Stipple = GL_FALSE;
static GLfloat LineWidth = 1.0;
@@ -59,7 +59,7 @@ static void Display( void )
y = t * 2.0 - 1.0;
if (!Texture)
glColor3f(1, 0, 1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s);
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s); */
glTexCoord2f(s, t);
glVertex2f(x, y);
}
@@ -73,12 +73,12 @@ static void Display( void )
if (!Texture)
glColor3f(1, 0, 1);
glTexCoord2f(t, 0.0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t);
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t); */
glVertex2f(x, -1.0);
if (!Texture)
glColor3f(0, 1, 0);
glTexCoord2f(t, 1.0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t);
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t); */
glVertex2f(x, 1.0);
}
glEnd();
@@ -127,22 +127,22 @@ static void Key( unsigned char key, int x, int y )
if (Texture > 2)
Texture = 0;
if (Texture == 0) {
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
glDisable(GL_TEXTURE_2D);
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
/* glDisable(GL_TEXTURE_2D); */
}
else if (Texture == 1) {
glActiveTextureARB(GL_TEXTURE0_ARB);
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
/* glDisable(GL_TEXTURE_2D); */
}
else {
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
glEnable(GL_TEXTURE_2D);
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
/* glEnable(GL_TEXTURE_2D); */
}
break;
case 'w':
@@ -212,8 +212,8 @@ static void SpecialKey( int key, int x, int y )
static void Init( int argc, char *argv[] )
{
GLuint u;
for (u = 0; u < 2; u++) {
glActiveTextureARB(GL_TEXTURE0_ARB + u);
for (u = 0; u < 1; u++) {
/* glActiveTextureARB(GL_TEXTURE0_ARB + u); */
glBindTexture(GL_TEXTURE_2D, 10+u);
if (u == 0)
glEnable(GL_TEXTURE_2D);

7
src/glu/mini/.cvsignore Normal file
View File

@@ -0,0 +1,7 @@
.deps
.libs
Makefile.in
*.lo
*.o
*.la
depend

46
src/glu/mini/Makefile Normal file
View File

@@ -0,0 +1,46 @@
MESA = ../..
default: libGLU.so.1.1 install
include $(MESA)/Makefile.include
LIBDIR = $(MESA)/lib
INCLUDES = -I$(MESA)/include
CFLAGS = -c -g $(INCLUDES) -MD
SOURCES = glu.c \
mipmap.c \
nurbs.c \
polytest.c \
project.c \
quadric.c \
tess.c \
tesselat.c
OBJS = $(addsuffix .o,$(basename $(SOURCES)))
LIBS=-L$(MESA)/lib -lGL -lm
libGLU.so.1.1: $(OBJS) Makefile
gcc -shared -Wl,-soname,libGLU.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@
install:
rm -f $(MESA)/lib/libGLU.so*
install -D libGLU.so.1.1 $(MESA)/lib/libGLU.so.1.1
ln -s libGLU.so.1.1 $(MESA)/lib/libGLU.so.1
ln -s libGLU.so.1 $(MESA)/lib/libGLU.so
clean: clean_here
clean_here:
rm -f ../lib/libGLU.so*
-include $(SOURCES:.c=.d)

55
src/glu/mini/all.h Normal file
View File

@@ -0,0 +1,55 @@
/* $Id: all.h,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file includes all .h files needed for the GLU source code for
* the purpose of precompiled headers.
*
* If the preprocessor symbol PCH is defined at compile time then each
* of the .c files will #include "all.h" only, instead of a bunch of
* individual .h files.
*/
#ifndef GLU_ALL_H
#define GLU_ALL_H
#ifndef PC_HEADER
This is an error. all.h should be included only if PCH is defined.
#endif
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GL/gl.h"
#include "GL/glu.h"
#include "gluP.h"
#include "nurbs.h"
#include "tess.h"
#endif /*GLU_ALL_H */

417
src/glu/mini/glu.c Normal file
View File

@@ -0,0 +1,417 @@
/* $Id: glu.c,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
* Copyright (C) 1995-2001 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gluP.h"
#endif
/*
* Miscellaneous utility functions
*/
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#define EPS 0.00001
#ifndef GLU_INCOMPATIBLE_GL_VERSION
#define GLU_INCOMPATIBLE_GL_VERSION 100903
#endif
void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
{
GLfloat m[16];
GLfloat x[3], y[3], z[3];
GLfloat mag;
/* Make rotation matrix */
/* Z vector */
z[0] = eyex - centerx;
z[1] = eyey - centery;
z[2] = eyez - centerz;
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) { /* mpichler, 19950515 */
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}
/* Y vector */
y[0] = upx;
y[1] = upy;
y[2] = upz;
/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];
/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];
/* mpichler, 19950515 */
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
if (mag) {
x[0] /= mag;
x[1] /= mag;
x[2] /= mag;
}
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
if (mag) {
y[0] /= mag;
y[1] /= mag;
y[2] /= mag;
}
#define M(row,col) m[col*4+row]
M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
M(1, 0) = y[0];
M(1, 1) = y[1];
M(1, 2) = y[2];
M(1, 3) = 0.0;
M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);
/* Translate Eye to Origin */
glTranslatef(-eyex, -eyey, -eyez);
}
void GLAPIENTRY
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
{
glOrtho(left, right, bottom, top, -1.0, 1.0);
}
static void
frustum(GLfloat left, GLfloat right,
GLfloat bottom, GLfloat top,
GLfloat nearval, GLfloat farval)
{
GLfloat x, y, a, b, c, d;
GLfloat m[16];
x = (2.0 * nearval) / (right - left);
y = (2.0 * nearval) / (top - bottom);
a = (right + left) / (right - left);
b = (top + bottom) / (top - bottom);
c = -(farval + nearval) / ( farval - nearval);
d = -(2.0 * farval * nearval) / (farval - nearval);
#define M(row,col) m[col*4+row]
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
glMultMatrixf(m);
}
void GLAPIENTRY
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLfloat xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
/* don't call glFrustum() because of error semantics (covglu) */
frustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
void GLAPIENTRY
gluPickMatrix(GLdouble x, GLdouble y,
GLdouble width, GLdouble height, GLint viewport[4])
{
GLfloat m[16];
GLfloat sx, sy;
GLfloat tx, ty;
sx = viewport[2] / width;
sy = viewport[3] / height;
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
#define M(row,col) m[col*4+row]
M(0, 0) = sx;
M(0, 1) = 0.0;
M(0, 2) = 0.0;
M(0, 3) = tx;
M(1, 0) = 0.0;
M(1, 1) = sy;
M(1, 2) = 0.0;
M(1, 3) = ty;
M(2, 0) = 0.0;
M(2, 1) = 0.0;
M(2, 2) = 1.0;
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);
}
const GLubyte *GLAPIENTRY
gluErrorString(GLenum errorCode)
{
static char *tess_error[] = {
"missing gluBeginPolygon",
"missing gluBeginContour",
"missing gluEndPolygon",
"missing gluEndContour",
"misoriented or self-intersecting loops",
"coincident vertices",
"colinear vertices",
"FIST recovery process fatal error"
};
static char *nurbs_error[] = {
"spline order un-supported",
"too few knots",
"valid knot range is empty",
"decreasing knot sequence knot",
"knot multiplicity greater than order of spline",
"endcurve() must follow bgncurve()",
"bgncurve() must precede endcurve()",
"missing or extra geometric data",
"can't draw pwlcurves",
"missing bgncurve()",
"missing bgnsurface()",
"endtrim() must precede endsurface()",
"bgnsurface() must precede endsurface()",
"curve of improper type passed as trim curve",
"bgnsurface() must precede bgntrim()",
"endtrim() must follow bgntrim()",
"bgntrim() must precede endtrim()",
"invalid or missing trim curve",
"bgntrim() must precede pwlcurve()",
"pwlcurve referenced twice",
"pwlcurve and nurbscurve mixed",
"improper usage of trim data type",
"nurbscurve referenced twice",
"nurbscurve and pwlcurve mixed",
"nurbssurface referenced twice",
"invalid property",
"endsurface() must follow bgnsurface()",
"misoriented trim curves",
"intersecting trim curves",
"UNUSED",
"unconnected trim curves",
"unknown knot error",
"negative vertex count encountered",
"negative byte-stride encountered",
"unknown type descriptor",
"null control array or knot vector",
"duplicate point on pwlcurve"
};
/* GL Errors */
if (errorCode == GL_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GL_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GL_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GL_INVALID_OPERATION) {
return (GLubyte *) "invalid operation";
}
else if (errorCode == GL_STACK_OVERFLOW) {
return (GLubyte *) "stack overflow";
}
else if (errorCode == GL_STACK_UNDERFLOW) {
return (GLubyte *) "stack underflow";
}
else if (errorCode == GL_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
/* GLU Errors */
else if (errorCode == GLU_NO_ERROR) {
return (GLubyte *) "no error";
}
else if (errorCode == GLU_INVALID_ENUM) {
return (GLubyte *) "invalid enum";
}
else if (errorCode == GLU_INVALID_VALUE) {
return (GLubyte *) "invalid value";
}
else if (errorCode == GLU_OUT_OF_MEMORY) {
return (GLubyte *) "out of memory";
}
else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
return (GLubyte *) "incompatible GL version";
}
else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
}
else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
}
else {
return NULL;
}
}
/*
* New in GLU 1.1
*/
const GLubyte *GLAPIENTRY
gluGetString(GLenum name)
{
static char *extensions = "GL_EXT_abgr";
static char *version = "1.1 Mesa 3.5";
switch (name) {
case GLU_EXTENSIONS:
return (GLubyte *) extensions;
case GLU_VERSION:
return (GLubyte *) version;
default:
return NULL;
}
}
#if 0 /* gluGetProcAddressEXT not finalized yet! */
#ifdef __cplusplus
/* for BeOS R4.5 */
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
#else
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
#endif
{
struct proc
{
const char *name;
void *address;
};
static struct proc procTable[] = {
{"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT}, /* me! */
/* new 1.1 functions */
{"gluGetString", (void *) gluGetString},
/* new 1.2 functions */
{"gluTessBeginPolygon", (void *) gluTessBeginPolygon},
{"gluTessBeginContour", (void *) gluTessBeginContour},
{"gluTessEndContour", (void *) gluTessEndContour},
{"gluTessEndPolygon", (void *) gluTessEndPolygon},
{"gluGetTessProperty", (void *) gluGetTessProperty},
/* new 1.3 functions */
{NULL, NULL}
};
GLuint i;
for (i = 0; procTable[i].address; i++) {
if (strcmp((const char *) procName, procTable[i].name) == 0)
return (void (GLAPIENTRY *) ()) procTable[i].address;
}
return NULL;
}
#endif
/*
* New in GLU 1.3
*/
#ifdef GLU_VERSION_1_3
GLboolean GLAPIENTRY
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
{
assert(extName);
assert(extString);
{
const int len = strlen((const char *) extName);
const char *start = (const char *) extString;
while (1) {
const char *c = strstr(start, (const char *) extName);
if (!c)
return GL_FALSE;
if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))
return GL_TRUE;
start = c + len;
}
}
}
#endif

142
src/glu/mini/gluP.h Normal file
View File

@@ -0,0 +1,142 @@
/* $Id: gluP.h,v 1.1.2.1 2003/03/21 13:02:10 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file allows the GLU code to be compiled either with the Mesa
* headers or with the real OpenGL headers.
*/
#ifndef GLUP_H
#define GLUP_H
#include <GL/gl.h>
#include <GL/glu.h>
#include <string.h>
#if defined(_WIN32) && !defined(__WIN32__)
# define __WIN32__
#endif
#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN__))
# pragma warning( disable : 4068 ) /* unknown pragma */
# pragma warning( disable : 4710 ) /* function 'foo' not inlined */
# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */
# pragma warning( disable : 4127 ) /* conditional expression is constant */
# if defined(MESA_MINWARN)
# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
# endif
# if defined(_MSC_VER) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
# define GLAPI __declspec(dllexport)
# define WGLAPI __declspec(dllexport)
# elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
# define GLAPI __declspec(dllimport)
# define WGLAPI __declspec(dllimport)
# else /* for use with static link lib build of Win32 edition only */
# define GLAPI extern
# define WGLAPI __declspec(dllimport)
# endif /* _STATIC_MESA support */
# define GLAPIENTRY __stdcall
# define GLAPIENTRYP __stdcall *
# define GLCALLBACK __stdcall
# define GLCALLBACKP __stdcall *
# if defined(__CYGWIN__)
# define GLCALLBACKPCAST *
# else
# define GLCALLBACKPCAST __stdcall *
# endif
# define GLWINAPI __stdcall
# define GLWINAPIV __cdecl
#else
/* non-Windows compilation */
# define GLAPI extern
# define GLAPIENTRY
# define GLAPIENTRYP *
# define GLCALLBACK
# define GLCALLBACKP *
# define GLCALLBACKPCAST *
# define GLWINAPI
# define GLWINAPIV
#endif /* WIN32 / CYGWIN bracket */
/* compatability guard so we don't need to change client code */
#if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP)
# define CALLBACK GLCALLBACK
typedef int (GLAPIENTRY *PROC)();
typedef void *HGLRC;
typedef void *HDC;
typedef unsigned long COLORREF;
#endif
#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP)
# define WGL_FONT_LINES 0
# define WGL_FONT_POLYGONS 1
#ifndef _GNU_H_WINDOWS32_FUNCTIONS
# ifdef UNICODE
# define wglUseFontBitmaps wglUseFontBitmapsW
# define wglUseFontOutlines wglUseFontOutlinesW
# else
# define wglUseFontBitmaps wglUseFontBitmapsA
# define wglUseFontOutlines wglUseFontOutlinesA
# endif /* !UNICODE */
#endif /* _GNU_H_WINDOWS32_FUNCTIONS */
typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR;
#include <gl/mesa_wgl.h>
#endif
#ifndef GLU_TESS_ERROR9
/* If we're using the real OpenGL header files... */
# define GLU_TESS_ERROR9 100159
#endif
#define GLU_NO_ERROR GL_NO_ERROR
/* for Sun: */
#ifdef SUNOS4
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
#else
#define MEMCPY( DST, SRC, BYTES) \
memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
#endif
#ifndef NULL
# define NULL 0
#endif
#endif

764
src/glu/mini/mipmap.c Normal file
View File

@@ -0,0 +1,764 @@
/* $Id: mipmap.c,v 1.1.2.1 2003/03/21 13:02:12 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.4
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
/*
* Compute ceiling of integer quotient of A divided by B:
*/
#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
#ifdef EPSILON
#undef EPSILON
#endif
#define EPSILON 0.001
/* To work around optimizer bug in MSVC4.1 */
#if defined(__WIN32__) && !defined(OPENSTEP)
void
dummy(GLuint j, GLuint k)
{
}
#else
#define dummy(J, K)
#endif
GLint GLAPIENTRY
gluScaleImage(GLenum format,
GLsizei widthin, GLsizei heightin,
GLenum typein, const void *datain,
GLsizei widthout, GLsizei heightout,
GLenum typeout, void *dataout)
{
GLint components, i, j, k;
GLfloat *tempin, *tempout, f;
GLfloat sx, sy;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
GLint sizein, sizeout;
GLint rowstride, rowlen;
/* Determine number of components per pixel */
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
components = 1;
break;
case GL_LUMINANCE_ALPHA:
components = 2;
break;
case GL_RGB:
case GL_BGR:
components = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
components = 4;
break;
default:
return GLU_INVALID_ENUM;
}
/* Determine bytes per input datum */
switch (typein) {
case GL_UNSIGNED_BYTE:
sizein = sizeof(GLubyte);
break;
case GL_BYTE:
sizein = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizein = sizeof(GLushort);
break;
case GL_SHORT:
sizein = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizein = sizeof(GLuint);
break;
case GL_INT:
sizein = sizeof(GLint);
break;
case GL_FLOAT:
sizein = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Determine bytes per output datum */
switch (typeout) {
case GL_UNSIGNED_BYTE:
sizeout = sizeof(GLubyte);
break;
case GL_BYTE:
sizeout = sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
sizeout = sizeof(GLushort);
break;
case GL_SHORT:
sizeout = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
sizeout = sizeof(GLuint);
break;
case GL_INT:
sizeout = sizeof(GLint);
break;
case GL_FLOAT:
sizeout = sizeof(GLfloat);
break;
case GL_BITMAP:
/* not implemented yet */
default:
return GL_INVALID_ENUM;
}
/* Get glPixelStore state */
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
/* Allocate storage for intermediate images */
tempin = (GLfloat *) malloc(widthin * heightin
* components * sizeof(GLfloat));
if (!tempin) {
return GLU_OUT_OF_MEMORY;
}
tempout = (GLfloat *) malloc(widthout * heightout
* components * sizeof(GLfloat));
if (!tempout) {
free(tempin);
return GLU_OUT_OF_MEMORY;
}
/*
* Unpack the pixel data and convert to floating point
*/
if (unpackrowlength > 0) {
rowlen = unpackrowlength;
}
else {
rowlen = widthin;
}
if (sizein >= unpackalignment) {
rowstride = components * rowlen;
}
else {
rowstride = unpackalignment / sizein
* CEILING(components * rowlen * sizein, unpackalignment);
}
switch (typein) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLubyte *ubptr = (GLubyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * ubptr++;
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightin; i++) {
GLbyte *bptr = (GLbyte *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * bptr++;
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLushort *usptr = (GLushort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * usptr++;
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightin; i++) {
GLshort *sptr = (GLshort *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * sptr++;
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLuint *uiptr = (GLuint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * uiptr++;
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightin; i++) {
GLint *iptr = (GLint *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = (GLfloat) * iptr++;
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightin; i++) {
GLfloat *fptr = (GLfloat *) datain
+ i * rowstride
+ unpackskiprows * rowstride + unpackskippixels * components;
for (j = 0; j < widthin * components; j++) {
dummy(j, k);
tempin[k++] = *fptr++;
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/*
* Scale the image!
*/
if (widthout > 1)
sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
else
sx = (GLfloat) (widthin - 1);
if (heightout > 1)
sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
else
sy = (GLfloat) (heightin - 1);
/*#define POINT_SAMPLE*/
#ifdef POINT_SAMPLE
for (i = 0; i < heightout; i++) {
GLint ii = i * sy;
for (j = 0; j < widthout; j++) {
GLint jj = j * sx;
GLfloat *src = tempin + (ii * widthin + jj) * components;
GLfloat *dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
*dst++ = *src++;
}
}
}
#else
if (sx < 1.0 && sy < 1.0) {
/* magnify both width and height: use weighted sample of 4 pixels */
GLint i0, i1, j0, j1;
GLfloat alpha, beta;
GLfloat *src00, *src01, *src10, *src11;
GLfloat s1, s2;
GLfloat *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON;*/
alpha = i * sy - i0;
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
beta = j * sx - j0;
/* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
src00 = tempin + (i0 * widthin + j0) * components;
src01 = tempin + (i0 * widthin + j1) * components;
src10 = tempin + (i1 * widthin + j0) * components;
src11 = tempin + (i1 * widthin + j1) * components;
dst = tempout + (i * widthout + j) * components;
for (k = 0; k < components; k++) {
s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
*dst++ = s1 * (1.0 - alpha) + s2 * alpha;
}
}
}
}
else {
/* shrink width and/or height: use an unweighted box filter */
GLint i0, i1;
GLint j0, j1;
GLint ii, jj;
GLfloat sum, *dst;
for (i = 0; i < heightout; i++) {
i0 = i * sy;
i1 = i0 + 1;
if (i1 >= heightin)
i1 = heightin - 1;
/* i1 = (i+1) * sy - EPSILON; */
for (j = 0; j < widthout; j++) {
j0 = j * sx;
j1 = j0 + 1;
if (j1 >= widthin)
j1 = widthin - 1;
/* j1 = (j+1) * sx - EPSILON; */
dst = tempout + (i * widthout + j) * components;
/* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
for (k = 0; k < components; k++) {
sum = 0.0;
for (ii = i0; ii <= i1; ii++) {
for (jj = j0; jj <= j1; jj++) {
sum += *(tempin + (ii * widthin + jj) * components + k);
}
}
sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
*dst++ = sum;
}
}
}
}
#endif
/*
* Return output image
*/
if (packrowlength > 0) {
rowlen = packrowlength;
}
else {
rowlen = widthout;
}
if (sizeout >= packalignment) {
rowstride = components * rowlen;
}
else {
rowstride = packalignment / sizeout
* CEILING(components * rowlen * sizeout, packalignment);
}
switch (typeout) {
case GL_UNSIGNED_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLubyte *ubptr = (GLubyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*ubptr++ = (GLubyte) tempout[k++];
}
}
break;
case GL_BYTE:
k = 0;
for (i = 0; i < heightout; i++) {
GLbyte *bptr = (GLbyte *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*bptr++ = (GLbyte) tempout[k++];
}
}
break;
case GL_UNSIGNED_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLushort *usptr = (GLushort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*usptr++ = (GLushort) tempout[k++];
}
}
break;
case GL_SHORT:
k = 0;
for (i = 0; i < heightout; i++) {
GLshort *sptr = (GLshort *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*sptr++ = (GLshort) tempout[k++];
}
}
break;
case GL_UNSIGNED_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLuint *uiptr = (GLuint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*uiptr++ = (GLuint) tempout[k++];
}
}
break;
case GL_INT:
k = 0;
for (i = 0; i < heightout; i++) {
GLint *iptr = (GLint *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*iptr++ = (GLint) tempout[k++];
}
}
break;
case GL_FLOAT:
k = 0;
for (i = 0; i < heightout; i++) {
GLfloat *fptr = (GLfloat *) dataout
+ i * rowstride
+ packskiprows * rowstride + packskippixels * components;
for (j = 0; j < widthout * components; j++) {
dummy(j, k + i);
*fptr++ = tempout[k++];
}
}
break;
default:
return GLU_INVALID_ENUM;
}
/* free temporary image storage */
free(tempin);
free(tempout);
return 0;
}
/*
* Return the largest k such that 2^k <= n.
*/
static GLint
ilog2(GLint n)
{
GLint k;
if (n <= 0)
return 0;
for (k = 0; n >>= 1; k++);
return k;
}
/*
* Find the value nearest to n which is also a power of two.
*/
static GLint
round2(GLint n)
{
GLint m;
for (m = 1; m < n; m *= 2);
/* m>=n */
if (m - n <= n - m / 2) {
return m;
}
else {
return m / 2;
}
}
/*
* Given an pixel format and datatype, return the number of bytes to
* store one pixel.
*/
static GLint
bytes_per_pixel(GLenum format, GLenum type)
{
GLint n, m;
switch (format) {
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
n = 1;
break;
case GL_LUMINANCE_ALPHA:
n = 2;
break;
case GL_RGB:
case GL_BGR:
n = 3;
break;
case GL_RGBA:
case GL_BGRA:
#ifdef GL_EXT_abgr
case GL_ABGR_EXT:
#endif
n = 4;
break;
default:
n = 0;
}
switch (type) {
case GL_UNSIGNED_BYTE:
m = sizeof(GLubyte);
break;
case GL_BYTE:
m = sizeof(GLbyte);
break;
case GL_BITMAP:
m = 1;
break;
case GL_UNSIGNED_SHORT:
m = sizeof(GLushort);
break;
case GL_SHORT:
m = sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
m = sizeof(GLuint);
break;
case GL_INT:
m = sizeof(GLint);
break;
case GL_FLOAT:
m = sizeof(GLfloat);
break;
default:
m = 0;
}
return n * m;
}
/*
* WARNING: This function isn't finished and has never been tested!!!!
*/
GLint GLAPIENTRY
gluBuild1DMipmaps(GLenum target, GLint components,
GLsizei width, GLenum format, GLenum type, const void *data)
{
return 0;
}
GLint GLAPIENTRY
gluBuild2DMipmaps(GLenum target, GLint components,
GLsizei width, GLsizei height, GLenum format,
GLenum type, const void *data)
{
GLint w, h;
GLint maxsize;
void *image, *newimage;
GLint neww, newh, level, bpp;
int error;
GLboolean done;
GLint retval = 0;
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
GLint packrowlength, packalignment, packskiprows, packskippixels;
GLfloat f;
if (width < 1 || height < 1)
return GLU_INVALID_VALUE;
glGetFloatv(GL_MAX_TEXTURE_SIZE, &f); maxsize = (int)f;
w = round2(width);
if (w > maxsize) {
w = maxsize;
}
h = round2(height);
if (h > maxsize) {
h = maxsize;
}
bpp = bytes_per_pixel(format, type);
if (bpp == 0) {
/* probably a bad format or type enum */
return GLU_INVALID_ENUM;
}
/* Get current glPixelStore values */
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
/* set pixel packing */
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
done = GL_FALSE;
if (w != width || h != height) {
/* must rescale image to get "top" mipmap texture image */
image = malloc((w + 4) * h * bpp);
if (!image) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, width, height, type, data,
w, h, type, image);
if (error) {
retval = error;
done = GL_TRUE;
}
}
else {
image = (void *) data;
}
level = 0;
while (!done) {
if (image != data) {
/* set pixel unpacking */
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
}
glTexImage2D(target, level, components, w, h, 0, format, type, image);
if (w == 1 && h == 1)
break;
neww = (w < 2) ? 1 : w / 2;
newh = (h < 2) ? 1 : h / 2;
newimage = malloc((neww + 4) * newh * bpp);
if (!newimage) {
return GLU_OUT_OF_MEMORY;
}
error = gluScaleImage(format, w, h, type, image,
neww, newh, type, newimage);
if (error) {
retval = error;
done = GL_TRUE;
}
if (image != data) {
free(image);
}
image = newimage;
w = neww;
h = newh;
level++;
}
if (image != data) {
free(image);
}
/* Restore original glPixelStore state */
glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
return retval;
}

158
src/glu/mini/nurbs.c Normal file
View File

@@ -0,0 +1,158 @@
/* $Id: nurbs.c,v 1.1.2.1 2003/03/21 13:02:13 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
void
call_user_error(GLUnurbsObj * nobj, GLenum error)
{
nobj->error = error;
if (nobj->error_callback != NULL) {
(*(nobj->error_callback)) (error);
}
else {
printf("NURBS error %d %s\n", error, (char *) gluErrorString(error));
}
}
GLUnurbsObj *GLAPIENTRY
gluNewNurbsRenderer(void)
{
GLUnurbsObj *n;
GLfloat tmp_viewport[4];
GLint i, j;
n = (GLUnurbsObj *) malloc(sizeof(GLUnurbsObj));
return n;
}
void GLAPIENTRY
gluDeleteNurbsRenderer(GLUnurbsObj * nobj)
{
if (nobj) {
free(nobj);
}
}
void GLAPIENTRY
gluLoadSamplingMatrices(GLUnurbsObj * nobj,
const GLfloat modelMatrix[16],
const GLfloat projMatrix[16], const GLint viewport[4])
{
}
void GLAPIENTRY
gluNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat value)
{
}
void GLAPIENTRY
gluGetNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat * value)
{
}
void GLAPIENTRY
gluBeginCurve(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluEndCurve(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot,
GLint stride, GLfloat * ctlarray, GLint order, GLenum type)
{
}
void GLAPIENTRY
gluBeginSurface(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluEndSurface(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluNurbsSurface(GLUnurbsObj * nobj,
GLint sknot_count, GLfloat * sknot,
GLint tknot_count, GLfloat * tknot,
GLint s_stride, GLint t_stride,
GLfloat * ctrlarray, GLint sorder, GLint torder, GLenum type)
{
}
void GLAPIENTRY
gluNurbsCallback(GLUnurbsObj * nobj, GLenum which, void (GLCALLBACK * fn) ())
{
}
void GLAPIENTRY
gluBeginTrim(GLUnurbsObj * nobj)
{
}
void GLAPIENTRY
gluPwlCurve(GLUnurbsObj * nobj, GLint count, GLfloat * array, GLint stride,
GLenum type)
{
}
void GLAPIENTRY
gluEndTrim(GLUnurbsObj * nobj)
{
}

253
src/glu/mini/nurbs.h Normal file
View File

@@ -0,0 +1,253 @@
/* $Id: nurbs.h,v 1.1.2.1 2003/03/21 13:02:14 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifndef NURBS_H
#define NURBS_H
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
}
GLU_nurbs_enum;
typedef enum
{
GLU_TRIM_NURBS, GLU_TRIM_PWL
}
GLU_trim_enum;
typedef struct
{
GLint sknot_count;
GLfloat *sknot;
GLint tknot_count;
GLfloat *tknot;
GLint s_stride;
GLint t_stride;
GLfloat *ctrlarray;
GLint sorder;
GLint torder;
GLint dim;
GLenum type;
}
surface_attribs;
typedef struct
{
surface_attribs geom;
surface_attribs color;
surface_attribs texture;
surface_attribs normal;
}
nurbs_surface;
typedef struct
{
GLint knot_count;
GLfloat *knot;
GLint stride;
GLfloat *ctrlarray;
GLint order;
GLint dim;
GLenum type;
}
curve_attribs;
typedef struct
{
GLint pt_count;
GLfloat *ctrlarray;
GLint stride;
GLint dim;
GLenum type;
}
pwl_curve_attribs;
typedef struct
{
curve_attribs geom;
curve_attribs color;
curve_attribs texture;
curve_attribs normal;
}
nurbs_curve;
typedef struct trim_list_str
{
GLU_trim_enum trim_type;
union
{
pwl_curve_attribs pwl_curve;
curve_attribs nurbs_curve;
}
curve;
struct trim_list_str *next;
}
trim_list;
typedef struct seg_trim_str
{
GLfloat *points;
GLint pt_cnt, seg_array_len;
struct seg_trim_str *next;
}
trim_segments;
typedef struct nurbs_trim_str
{
trim_list *trim_loop;
trim_segments *segments;
struct nurbs_trim_str *next;
}
nurbs_trim;
typedef struct
{
GLfloat model[16], proj[16], viewport[4];
}
culling_and_sampling_str;
struct GLUnurbs
{
GLboolean culling;
GLenum error;
void (GLCALLBACK * error_callback) (GLenum err);
GLenum display_mode;
GLU_nurbs_enum nurbs_type;
GLboolean auto_load_matrix;
culling_and_sampling_str sampling_matrices;
GLenum sampling_method;
GLfloat sampling_tolerance;
GLfloat parametric_tolerance;
GLint u_step, v_step;
nurbs_surface surface;
nurbs_curve curve;
nurbs_trim *trim;
};
typedef struct
{
GLfloat *knot;
GLint nknots;
GLfloat *unified_knot;
GLint unified_nknots;
GLint order;
GLint t_min, t_max;
GLint delta_nknots;
GLboolean open_at_begin, open_at_end;
GLfloat *new_knot;
GLfloat *alpha;
}
knot_str_type;
typedef struct
{
GLfloat *geom_ctrl;
GLint geom_s_stride, geom_t_stride;
GLfloat **geom_offsets;
GLint geom_s_pt_cnt, geom_t_pt_cnt;
GLfloat *color_ctrl;
GLint color_s_stride, color_t_stride;
GLfloat **color_offsets;
GLint color_s_pt_cnt, color_t_pt_cnt;
GLfloat *normal_ctrl;
GLint normal_s_stride, normal_t_stride;
GLfloat **normal_offsets;
GLint normal_s_pt_cnt, normal_t_pt_cnt;
GLfloat *texture_ctrl;
GLint texture_s_stride, texture_t_stride;
GLfloat **texture_offsets;
GLint texture_s_pt_cnt, texture_t_pt_cnt;
GLint s_bezier_cnt, t_bezier_cnt;
}
new_ctrl_type;
extern void call_user_error(GLUnurbsObj * nobj, GLenum error);
extern GLenum test_knot(GLint nknots, GLfloat * knot, GLint order);
extern GLenum explode_knot(knot_str_type * the_knot);
extern GLenum calc_alphas(knot_str_type * the_knot);
extern GLenum calc_new_ctrl_pts(GLfloat * ctrl, GLint stride,
knot_str_type * the_knot, GLint dim,
GLfloat ** new_ctrl, GLint * ncontrol);
extern GLenum glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * new_ctrl,
GLint n_ctrl, GLint order, GLint dim,
GLint ** factors);
extern GLenum glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLenum glu_do_sampling_param_3D(GLUnurbsObj * nobj,
new_ctrl_type * new_ctrl,
int **sfactors, GLint ** tfactors);
extern GLboolean fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint n_ctrl, GLint stride, GLint dim);
extern GLboolean fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * ctrl,
GLint s_n_ctrl, GLint t_n_ctrl,
GLint s_stride, GLint t_stride,
GLint dim);
extern void do_nurbs_curve(GLUnurbsObj * nobj);
extern void do_nurbs_surface(GLUnurbsObj * nobj);
extern GLenum patch_trimming(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
GLint * sfactors, GLint * tfactors);
extern void collect_unified_knot(knot_str_type * dest, knot_str_type * src,
GLfloat maximal_min_knot,
GLfloat minimal_max_knot);
extern GLenum select_knot_working_range(GLUnurbsObj * nobj,
knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
extern void free_unified_knots(knot_str_type * geom_knot,
knot_str_type * color_knot,
knot_str_type * normal_knot,
knot_str_type * texture_knot);
#endif

133
src/glu/mini/nurbscrv.c Normal file
View File

@@ -0,0 +1,133 @@
/* $Id: nurbscrv.c,v 1.1.2.1 2003/03/21 13:02:16 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
* See README2 for more info.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "nurbs.h"
#endif
/* main NURBS curve procedure */
void
do_nurbs_curve(GLUnurbsObj * nobj)
{
GLint geom_order, color_order = 0, normal_order = 0, texture_order = 0;
GLenum geom_type;
GLint n_ctrl;
GLfloat *new_geom_ctrl, *new_color_ctrl, *new_normal_ctrl,
*new_texture_ctrl;
GLfloat *geom_ctrl = 0, *color_ctrl = 0, *normal_ctrl = 0, *texture_ctrl = 0;
GLint *factors;
GLint i, j;
GLint geom_dim, color_dim = 0, normal_dim = 0, texture_dim = 0;
/* test the user supplied data */
if (test_nurbs_curves(nobj) != GLU_NO_ERROR)
return;
if (convert_curves(nobj, &new_geom_ctrl, &n_ctrl, &new_color_ctrl,
&new_normal_ctrl, &new_texture_ctrl) != GLU_NO_ERROR)
return;
geom_order = nobj->curve.geom.order;
geom_type = nobj->curve.geom.type;
geom_dim = nobj->curve.geom.dim;
if (glu_do_sampling_crv(nobj, new_geom_ctrl, n_ctrl, geom_order, geom_dim,
&factors) != GLU_NO_ERROR) {
free(new_geom_ctrl);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
return;
}
glEnable(geom_type);
if (new_color_ctrl) {
glEnable(nobj->curve.color.type);
color_dim = nobj->curve.color.dim;
color_ctrl = new_color_ctrl;
color_order = nobj->curve.color.order;
}
if (new_normal_ctrl) {
glEnable(nobj->curve.normal.type);
normal_dim = nobj->curve.normal.dim;
normal_ctrl = new_normal_ctrl;
normal_order = nobj->curve.normal.order;
}
if (new_texture_ctrl) {
glEnable(nobj->curve.texture.type);
texture_dim = nobj->curve.texture.dim;
texture_ctrl = new_texture_ctrl;
texture_order = nobj->curve.texture.order;
}
for (i = 0, j = 0, geom_ctrl = new_geom_ctrl;
i < n_ctrl; i += geom_order, j++, geom_ctrl += geom_order * geom_dim) {
if (fine_culling_test_2D
(nobj, geom_ctrl, geom_order, geom_dim, geom_dim)) {
color_ctrl += color_order * color_dim;
normal_ctrl += normal_order * normal_dim;
texture_ctrl += texture_order * texture_dim;
continue;
}
glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl);
if (new_color_ctrl) {
glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim,
color_order, color_ctrl);
color_ctrl += color_order * color_dim;
}
if (new_normal_ctrl) {
glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim,
normal_order, normal_ctrl);
normal_ctrl += normal_order * normal_dim;
}
if (new_texture_ctrl) {
glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim,
texture_order, texture_ctrl);
texture_ctrl += texture_order * texture_dim;
}
glMapGrid1f(factors[j], 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, factors[j]);
}
free(new_geom_ctrl);
free(factors);
if (new_color_ctrl)
free(new_color_ctrl);
if (new_normal_ctrl)
free(new_normal_ctrl);
if (new_texture_ctrl)
free(new_texture_ctrl);
}

938
src/glu/mini/polytest.c Normal file
View File

@@ -0,0 +1,938 @@
/* $Id: polytest.c,v 1.1.2.1 2003/03/21 13:02:17 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "gluP.h"
#include "tess.h"
#endif
static GLenum store_polygon_as_contour(GLUtriangulatorObj *);
static void free_current_polygon(tess_polygon *);
static void prepare_projection_info(GLUtriangulatorObj *);
static GLdouble twice_the_polygon_area(tess_vertex *, tess_vertex *);
static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *);
void tess_find_contour_hierarchies(GLUtriangulatorObj *);
static GLenum test_for_overlapping_contours(GLUtriangulatorObj *);
static GLenum contours_overlap(tess_contour *, tess_polygon *);
static GLenum is_contour_contained_in(tess_contour *, tess_contour *);
static void add_new_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_new_interior(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static void add_interior_with_hierarchy_check(GLUtriangulatorObj *,
tess_contour *, tess_contour *);
static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *,
tess_contour *,
tess_contour *);
static GLboolean point_in_polygon(tess_contour *, GLdouble, GLdouble);
static void shift_interior_to_exterior(GLUtriangulatorObj *, tess_contour *);
static void add_exterior_with_check(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum cut_out_hole(GLUtriangulatorObj *, tess_contour *,
tess_contour *);
static GLenum merge_hole_with_contour(GLUtriangulatorObj *,
tess_contour *, tess_contour *,
tess_vertex *, tess_vertex *);
static GLenum
find_normal(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *va, *vb, *vc;
GLdouble A, B, C;
GLdouble A0, A1, A2, B0, B1, B2;
va = polygon->vertices;
vb = va->next;
A0 = vb->location[0] - va->location[0];
A1 = vb->location[1] - va->location[1];
A2 = vb->location[2] - va->location[2];
for (vc = vb->next; vc != va; vc = vc->next) {
B0 = vc->location[0] - va->location[0];
B1 = vc->location[1] - va->location[1];
B2 = vc->location[2] - va->location[2];
A = A1 * B2 - A2 * B1;
B = A2 * B0 - A0 * B2;
C = A0 * B1 - A1 * B0;
if (fabs(A) > EPSILON || fabs(B) > EPSILON || fabs(C) > EPSILON) {
polygon->A = A;
polygon->B = B;
polygon->C = C;
polygon->D =
-A * va->location[0] - B * va->location[1] - C * va->location[2];
return GLU_NO_ERROR;
}
}
tess_call_user_error(tobj, GLU_TESS_ERROR7);
return GLU_ERROR;
}
void
tess_test_polygon(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
/* any vertices defined? */
if (polygon->vertex_cnt < 3) {
free_current_polygon(polygon);
return;
}
/* wrap pointers */
polygon->last_vertex->next = polygon->vertices;
polygon->vertices->previous = polygon->last_vertex;
/* determine the normal */
if (find_normal(tobj) == GLU_ERROR)
return;
/* compare the normals of previously defined contours and this one */
/* first contour define ? */
if (tobj->contours == NULL) {
tobj->A = polygon->A;
tobj->B = polygon->B;
tobj->C = polygon->C;
tobj->D = polygon->D;
/* determine the best projection to use */
if (fabs(polygon->A) > fabs(polygon->B))
if (fabs(polygon->A) > fabs(polygon->C))
tobj->projection = OYZ;
else
tobj->projection = OXY;
else if (fabs(polygon->B) > fabs(polygon->C))
tobj->projection = OXZ;
else
tobj->projection = OXY;
}
else {
GLdouble a[3], b[3];
tess_vertex *vertex = polygon->vertices;
a[0] = tobj->A;
a[1] = tobj->B;
a[2] = tobj->C;
b[0] = polygon->A;
b[1] = polygon->B;
b[2] = polygon->C;
/* compare the normals */
if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON ||
fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON ||
fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) {
/* not coplanar */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
/* the normals are parallel - test for plane equation */
if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] +
a[2] * vertex->location[2] + tobj->D) > EPSILON) {
/* not the same plane */
tess_call_user_error(tobj, GLU_TESS_ERROR9);
return;
}
}
prepare_projection_info(tobj);
if (verify_edge_vertex_intersections(tobj) == GLU_ERROR)
return;
if (test_for_overlapping_contours(tobj) == GLU_ERROR)
return;
if (store_polygon_as_contour(tobj) == GLU_ERROR)
return;
}
static GLenum
test_for_overlapping_contours(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
tess_polygon *polygon;
polygon = tobj->current_polygon;
for (contour = tobj->contours; contour != NULL; contour = contour->next)
if (contours_overlap(contour, polygon) != GLU_NO_ERROR) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return GLU_ERROR;
}
return GLU_NO_ERROR;
}
static GLenum
store_polygon_as_contour(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour = tobj->contours;
/* the first contour defined */
if (contour == NULL) {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
tobj->contours = tobj->last_contour = contour;
contour->next = contour->previous = NULL;
}
else {
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
free_current_polygon(polygon);
return GLU_ERROR;
}
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
contour->next = NULL;
}
/* mark all vertices in new contour as not special */
/* and all are boundary edges */
{
tess_vertex *vertex;
GLuint vertex_cnt, i;
for (vertex = polygon->vertices, i = 0, vertex_cnt =
polygon->vertex_cnt; i < vertex_cnt; vertex = vertex->next, i++) {
vertex->shadow_vertex = NULL;
vertex->edge_flag = GL_TRUE;
}
}
contour->vertex_cnt = polygon->vertex_cnt;
contour->area = polygon->area;
contour->orientation = polygon->orientation;
contour->type = GLU_UNKNOWN;
contour->vertices = polygon->vertices;
contour->last_vertex = polygon->last_vertex;
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
++(tobj->contour_cnt);
return GLU_NO_ERROR;
}
static void
free_current_polygon(tess_polygon * polygon)
{
tess_vertex *vertex, *vertex_tmp;
GLuint i;
/* free current_polygon structures */
for (vertex = polygon->vertices, i = 0; i < polygon->vertex_cnt; i++) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
polygon->vertices = polygon->last_vertex = NULL;
polygon->vertex_cnt = 0;
}
static void
prepare_projection_info(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex, *last_vertex_ptr;
GLdouble area;
last_vertex_ptr = polygon->last_vertex;
switch (tobj->projection) {
case OXY:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[1];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[1];
break;
case OXZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[0];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[0];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
case OYZ:
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
vertex = vertex->next) {
vertex->x = vertex->location[1];
vertex->y = vertex->location[2];
}
last_vertex_ptr->x = last_vertex_ptr->location[1];
last_vertex_ptr->y = last_vertex_ptr->location[2];
break;
}
area = twice_the_polygon_area(polygon->vertices, polygon->last_vertex);
if (area >= 0.0) {
polygon->orientation = GLU_CCW;
polygon->area = area;
}
else {
polygon->orientation = GLU_CW;
polygon->area = -area;
}
}
static GLdouble
twice_the_polygon_area(tess_vertex * vertex, tess_vertex * last_vertex)
{
tess_vertex *next;
GLdouble area, x, y;
area = 0.0;
x = vertex->x;
y = vertex->y;
vertex = vertex->next;
for (; vertex != last_vertex; vertex = vertex->next) {
next = vertex->next;
area +=
(vertex->x - x) * (next->y - y) - (vertex->y - y) * (next->x - x);
}
return area;
}
/* test if edges ab and cd intersect */
/* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */
/* else if adjacent return GLU_TESS_ERROR4 */
static GLenum
edge_edge_intersect(tess_vertex * a,
tess_vertex * b, tess_vertex * c, tess_vertex * d)
{
GLdouble denom, r, s;
GLdouble xba, ydc, yba, xdc, yac, xac;
xba = b->x - a->x;
yba = b->y - a->y;
xdc = d->x - c->x;
ydc = d->y - c->y;
xac = a->x - c->x;
yac = a->y - c->y;
denom = xba * ydc - yba * xdc;
r = yac * xdc - xac * ydc;
/* parallel? */
if (fabs(denom) < EPSILON) {
if (fabs(r) < EPSILON) {
/* colinear */
if (fabs(xba) < EPSILON) {
/* compare the Y coordinate */
if (yba > 0.0) {
if (
(fabs(a->y - c->y) < EPSILON
&& fabs(c->y - b->y) < EPSILON)
|| (fabs(a->y - d->y) < EPSILON
&& fabs(d->y - b->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->y - c->y) < EPSILON
&& fabs(c->y - a->y) < EPSILON)
|| (fabs(b->y - d->y) < EPSILON
&& fabs(d->y - a->y) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
else {
/* compare the X coordinate */
if (xba > 0.0) {
if (
(fabs(a->x - c->x) < EPSILON
&& fabs(c->x - b->x) < EPSILON)
|| (fabs(a->x - d->x) < EPSILON
&& fabs(d->x - b->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
else {
if (
(fabs(b->x - c->x) < EPSILON
&& fabs(c->x - a->x) < EPSILON)
|| (fabs(b->x - d->x) < EPSILON
&& fabs(d->x - a->x) <
EPSILON)) return GLU_TESS_ERROR4;
}
}
}
return GLU_NO_ERROR;
}
r /= denom;
s = (yac * xba - xac * yba) / denom;
/* test if one vertex lies on other edge */
if (((fabs(r) < EPSILON || (r < 1.0 + EPSILON && r > 1.0 - EPSILON)) &&
s > -EPSILON && s < 1.0 + EPSILON) ||
((fabs(s) < EPSILON || (s < 1.0 + EPSILON && s > 1.0 - EPSILON)) &&
r > -EPSILON && r < 1.0 + EPSILON)) {
return GLU_TESS_ERROR4;
}
/* test for crossing */
if (r > -EPSILON && r < 1.0 + EPSILON && s > -EPSILON && s < 1.0 + EPSILON) {
return GLU_TESS_ERROR8;
}
return GLU_NO_ERROR;
}
static GLenum
verify_edge_vertex_intersections(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *vertex1, *last_vertex, *vertex2;
GLenum test;
last_vertex = polygon->last_vertex;
vertex1 = last_vertex;
for (vertex2 = vertex1->next->next;
vertex2->next != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
for (vertex1 = polygon->vertices;
vertex1->next->next != last_vertex; vertex1 = vertex1->next) {
for (vertex2 = vertex1->next->next;
vertex2 != last_vertex; vertex2 = vertex2->next) {
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next);
if (test != GLU_NO_ERROR) {
tess_call_user_error(tobj, test);
return GLU_ERROR;
}
}
}
return GLU_NO_ERROR;
}
static int
#ifdef WIN32
__cdecl
#endif
area_compare(const void *a, const void *b)
{
GLdouble area1, area2;
area1 = (*((tess_contour **) a))->area;
area2 = (*((tess_contour **) b))->area;
if (area1 < area2)
return 1;
if (area1 > area2)
return -1;
return 0;
}
void
tess_find_contour_hierarchies(GLUtriangulatorObj * tobj)
{
tess_contour **contours; /* dinamic array of pointers */
tess_contour *tmp_contour_ptr = tobj->contours;
GLuint cnt, i;
GLenum result;
GLboolean hierarchy_changed;
/* any contours? */
if (tobj->contour_cnt < 2) {
tobj->contours->type = GLU_EXTERIOR;
return;
}
if ((contours = (tess_contour **)
malloc(sizeof(tess_contour *) * (tobj->contour_cnt))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
for (tmp_contour_ptr = tobj->contours, cnt = 0;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next)
contours[cnt++] = tmp_contour_ptr;
/* now sort the contours in decreasing area size order */
qsort((void *) contours, (size_t) cnt, (size_t) sizeof(tess_contour *),
area_compare);
/* we leave just the first contour - remove others from list */
tobj->contours = contours[0];
tobj->contours->next = tobj->contours->previous = NULL;
tobj->last_contour = tobj->contours;
tobj->contour_cnt = 1;
/* first contour is the one with greatest area */
/* must be EXTERIOR */
tobj->contours->type = GLU_EXTERIOR;
tmp_contour_ptr = tobj->contours;
/* now we play! */
for (i = 1; i < cnt; i++) {
hierarchy_changed = GL_FALSE;
for (tmp_contour_ptr = tobj->contours;
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) {
if (tmp_contour_ptr->type == GLU_EXTERIOR) {
/* check if contour completely contained in EXTERIOR */
result = is_contour_contained_in(tmp_contour_ptr, contours[i]);
switch (result) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (tmp_contour_ptr->next != NULL &&
tmp_contour_ptr->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj,
tmp_contour_ptr,
contours[i]);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, tmp_contour_ptr, contours[i]);
}
hierarchy_changed = GL_TRUE;
break;
case GLU_EXTERIOR:
/* ooops, the marked as EXTERIOR (contours[i]) is */
/* actually an interior of tmp_contour_ptr */
/* reverse the local hierarchy */
reverse_hierarchy_and_add_exterior(tobj, tmp_contour_ptr,
contours[i]);
hierarchy_changed = GL_TRUE;
break;
case GLU_NO_ERROR:
break;
default:
abort();
}
}
if (hierarchy_changed)
break; /* break from for loop */
}
if (hierarchy_changed == GL_FALSE) {
/* disjoint with all contours, add to contour list */
add_new_exterior(tobj, contours[i]);
}
}
free(contours);
}
/* returns GLU_INTERIOR if inner is completey enclosed within outer */
/* returns GLU_EXTERIOR if outer is completely enclosed within inner */
/* returns GLU_NO_ERROR if contours are disjoint */
static GLenum
is_contour_contained_in(tess_contour * outer, tess_contour * inner)
{
GLenum relation_flag;
/* set relation_flag to relation of containment of first inner vertex */
/* regarding outer contour */
if (point_in_polygon(outer, inner->vertices->x, inner->vertices->y))
relation_flag = GLU_INTERIOR;
else
relation_flag = GLU_EXTERIOR;
if (relation_flag == GLU_INTERIOR)
return GLU_INTERIOR;
if (point_in_polygon(inner, outer->vertices->x, outer->vertices->y))
return GLU_EXTERIOR;
return GLU_NO_ERROR;
}
static GLboolean
point_in_polygon(tess_contour * contour, GLdouble x, GLdouble y)
{
tess_vertex *v1, *v2;
GLuint i, vertex_cnt;
GLdouble xp1, yp1, xp2, yp2;
GLboolean tst;
tst = GL_FALSE;
v1 = contour->vertices;
v2 = contour->vertices->previous;
for (i = 0, vertex_cnt = contour->vertex_cnt; i < vertex_cnt; i++) {
xp1 = v1->x;
yp1 = v1->y;
xp2 = v2->x;
yp2 = v2->y;
if ((((yp1 <= y) && (y < yp2)) || ((yp2 <= y) && (y < yp1))) &&
(x < (xp2 - xp1) * (y - yp1) / (yp2 - yp1) + xp1))
tst = (tst == GL_FALSE ? GL_TRUE : GL_FALSE);
v2 = v1;
v1 = v1->next;
}
return tst;
}
static GLenum
contours_overlap(tess_contour * contour, tess_polygon * polygon)
{
tess_vertex *vertex1, *vertex2;
GLuint vertex1_cnt, vertex2_cnt, i, j;
GLenum test;
vertex1 = contour->vertices;
vertex2 = polygon->vertices;
vertex1_cnt = contour->vertex_cnt;
vertex2_cnt = polygon->vertex_cnt;
for (i = 0; i < vertex1_cnt; vertex1 = vertex1->next, i++) {
for (j = 0; j < vertex2_cnt; vertex2 = vertex2->next, j++)
if ((test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
vertex2->next)) != GLU_NO_ERROR)
return test;
}
return GLU_NO_ERROR;
}
static void
add_new_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->type = GLU_EXTERIOR;
contour->next = NULL;
contour->previous = tobj->last_contour;
tobj->last_contour->next = contour;
tobj->last_contour = contour;
}
static void
add_new_interior(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
contour->type = GLU_INTERIOR;
contour->next = outer->next;
contour->previous = outer;
if (outer->next != NULL)
outer->next->previous = contour;
outer->next = contour;
if (tobj->last_contour == outer)
tobj->last_contour = contour;
}
static void
add_interior_with_hierarchy_check(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* for all interiors of outer check if they are interior of contour */
/* if so, change that interior to exterior and move it of of the */
/* interior sequence */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
GLenum test;
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) {
test = is_contour_contained_in(ptr, contour);
switch (test) {
case GLU_INTERIOR:
/* contour is contained in one of the interiors */
/* check if possibly contained in other exteriors */
/* move ptr to first EXTERIOR */
for (; ptr != NULL && ptr->type == GLU_INTERIOR; ptr = ptr->next);
if (ptr == NULL)
/* another exterior */
add_new_exterior(tobj, contour);
else
add_exterior_with_check(tobj, ptr, contour);
return;
case GLU_EXTERIOR:
/* one of the interiors is contained in the contour */
/* change it to EXTERIOR, and shift it away from the */
/* interior sequence */
shift_interior_to_exterior(tobj, ptr);
break;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
}
/* add contour to the interior sequence */
add_new_interior(tobj, outer, contour);
}
static void
reverse_hierarchy_and_add_exterior(GLUtriangulatorObj * tobj,
tess_contour * outer,
tess_contour * contour)
{
tess_contour *ptr;
/* reverse INTERIORS to EXTERIORS */
/* any INTERIORS? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR)
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
ptr = ptr->next) ptr->type = GLU_EXTERIOR;
/* the outer now becomes inner */
outer->type = GLU_INTERIOR;
/* contour is the EXTERIOR */
contour->next = outer;
if (tobj->contours == outer) {
/* first contour beeing reversed */
contour->previous = NULL;
tobj->contours = contour;
}
else {
outer->previous->next = contour;
contour->previous = outer->previous;
}
outer->previous = contour;
}
static void
shift_interior_to_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
{
contour->previous->next = contour->next;
if (contour->next != NULL)
contour->next->previous = contour->previous;
else
tobj->last_contour = contour->previous;
}
static void
add_exterior_with_check(GLUtriangulatorObj * tobj,
tess_contour * outer, tess_contour * contour)
{
GLenum test;
/* this contour might be interior to further exteriors - check */
/* if not, just add as a new exterior */
for (; outer != NULL && outer->type == GLU_EXTERIOR; outer = outer->next) {
test = is_contour_contained_in(outer, contour);
switch (test) {
case GLU_INTERIOR:
/* now we have to check if contour is inside interiors */
/* or not */
/* any interiors? */
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
/* for all interior, check if inside any of them */
/* if not inside any of interiors, its another */
/* interior */
/* or it may contain some interiors, then change */
/* the contained interiors to exterior ones */
add_interior_with_hierarchy_check(tobj, outer, contour);
}
else {
/* not in interior, add as new interior contour */
add_new_interior(tobj, outer, contour);
}
return;
case GLU_NO_ERROR:
/* disjoint */
break;
default:
abort();
}
}
/* add contour to the exterior sequence */
add_new_exterior(tobj, contour);
}
void
tess_handle_holes(GLUtriangulatorObj * tobj)
{
tess_contour *contour, *hole;
GLenum exterior_orientation;
/* verify hole orientation */
for (contour = tobj->contours; contour != NULL;) {
exterior_orientation = contour->orientation;
for (contour = contour->next;
contour != NULL && contour->type == GLU_INTERIOR;
contour = contour->next) {
if (contour->orientation == exterior_orientation) {
tess_call_user_error(tobj, GLU_TESS_ERROR5);
return;
}
}
}
/* now cut-out holes */
for (contour = tobj->contours; contour != NULL;) {
hole = contour->next;
while (hole != NULL && hole->type == GLU_INTERIOR) {
if (cut_out_hole(tobj, contour, hole) == GLU_ERROR)
return;
hole = contour->next;
}
contour = contour->next;
}
}
static GLenum
cut_out_hole(GLUtriangulatorObj * tobj,
tess_contour * contour, tess_contour * hole)
{
tess_contour *tmp_hole;
tess_vertex *v1, *v2, *tmp_vertex;
GLuint vertex1_cnt, vertex2_cnt, tmp_vertex_cnt;
GLuint i, j, k;
GLenum test = 0;
/* find an edge connecting contour and hole not intersecting any other */
/* edge belonging to either the contour or any of the other holes */
for (v1 = contour->vertices, vertex1_cnt = contour->vertex_cnt, i = 0;
i < vertex1_cnt; i++, v1 = v1->next) {
for (v2 = hole->vertices, vertex2_cnt = hole->vertex_cnt, j = 0;
j < vertex2_cnt; j++, v2 = v2->next) {
/* does edge (v1,v2) intersect any edge of contour */
for (tmp_vertex = contour->vertices, tmp_vertex_cnt =
contour->vertex_cnt, k = 0; k < tmp_vertex_cnt;
tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v1 == tmp_vertex || v1 == tmp_vertex->next)
continue;
test = edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = hole->vertices,
tmp_vertex_cnt = hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
/* skip edge tests for edges directly connected */
if (v2 == tmp_vertex || v2 == tmp_vertex->next)
continue;
test =
edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test == GLU_NO_ERROR) {
/* does edge (v1,v2) intersect any other hole? */
for (tmp_hole = hole->next;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next) {
/* does edge (v1,v2) intersect any edge of hole */
for (tmp_vertex = tmp_hole->vertices,
tmp_vertex_cnt = tmp_hole->vertex_cnt, k = 0;
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
test = edge_edge_intersect(v1, v2, tmp_vertex,
tmp_vertex->next);
if (test != GLU_NO_ERROR)
break;
}
if (test != GLU_NO_ERROR)
break;
}
}
}
if (test == GLU_NO_ERROR) {
/* edge (v1,v2) is good for eliminating the hole */
if (merge_hole_with_contour(tobj, contour, hole, v1, v2)
== GLU_NO_ERROR)
return GLU_NO_ERROR;
else
return GLU_ERROR;
}
}
}
/* other holes are blocking all possible connections of hole */
/* with contour, we shift this hole as the last hole and retry */
for (tmp_hole = hole;
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
tmp_hole = tmp_hole->next);
contour->next = hole->next;
hole->next->previous = contour;
if (tmp_hole == NULL) {
/* last EXTERIOR contour, shift hole as last contour */
hole->next = NULL;
hole->previous = tobj->last_contour;
tobj->last_contour->next = hole;
tobj->last_contour = hole;
}
else {
tmp_hole->previous->next = hole;
hole->previous = tmp_hole->previous;
tmp_hole->previous = hole;
hole->next = tmp_hole;
}
hole = contour->next;
/* try once again - recurse */
return cut_out_hole(tobj, contour, hole);
}
static GLenum
merge_hole_with_contour(GLUtriangulatorObj * tobj,
tess_contour * contour,
tess_contour * hole,
tess_vertex * v1, tess_vertex * v2)
{
tess_vertex *v1_new, *v2_new;
/* make copies of v1 and v2, place them respectively after their originals */
if ((v1_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
if ((v2_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return GLU_ERROR;
}
v1_new->edge_flag = GL_TRUE;
v1_new->data = v1->data;
v1_new->location[0] = v1->location[0];
v1_new->location[1] = v1->location[1];
v1_new->location[2] = v1->location[2];
v1_new->x = v1->x;
v1_new->y = v1->y;
v1_new->shadow_vertex = v1;
v1->shadow_vertex = v1_new;
v1_new->next = v1->next;
v1_new->previous = v1;
v1->next->previous = v1_new;
v1->next = v1_new;
v2_new->edge_flag = GL_TRUE;
v2_new->data = v2->data;
v2_new->location[0] = v2->location[0];
v2_new->location[1] = v2->location[1];
v2_new->location[2] = v2->location[2];
v2_new->x = v2->x;
v2_new->y = v2->y;
v2_new->shadow_vertex = v2;
v2->shadow_vertex = v2_new;
v2_new->next = v2->next;
v2_new->previous = v2;
v2->next->previous = v2_new;
v2->next = v2_new;
/* link together the two lists */
v1->next = v2_new;
v2_new->previous = v1;
v2->next = v1_new;
v1_new->previous = v2;
/* update the vertex count of the contour */
contour->vertex_cnt += hole->vertex_cnt + 2;
/* remove the INTERIOR contour */
contour->next = hole->next;
if (hole->next != NULL)
hole->next->previous = contour;
free(hole);
/* update tobj structure */
--(tobj->contour_cnt);
if (contour->last_vertex == v1)
contour->last_vertex = v1_new;
/* mark two vertices with edge_flag */
v2->edge_flag = GL_FALSE;
v1->edge_flag = GL_FALSE;
return GLU_NO_ERROR;
}

402
src/glu/mini/project.c Normal file
View File

@@ -0,0 +1,402 @@
/* $Id: project.c,v 1.1.2.1 2003/03/21 13:02:18 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "gluP.h"
#endif
/*
* This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr).
* Thanks Marc!!!
*/
/* implementation de gluProject et gluUnproject */
/* M. Buffat 17/2/95 */
/*
* Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in
* Input: m - the 4x4 matrix
* in - the 4x1 vector
* Output: out - the resulting 4x1 vector.
*/
static void
transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
/*
* Perform a 4x4 matrix multiplication (product = a x b).
* Input: a, b - matrices to multiply
* Output: product - product of a and b
*/
static void
matmul(GLdouble * product, const GLdouble * a, const GLdouble * b)
{
/* This matmul was contributed by Thomas Malik */
GLdouble temp[16];
GLint i;
#define A(row,col) a[(col<<2)+row]
#define B(row,col) b[(col<<2)+row]
#define T(row,col) temp[(col<<2)+row]
/* i-te Zeile */
for (i = 0; i < 4; i++) {
T(i, 0) =
A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i,
3) *
B(3, 0);
T(i, 1) =
A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i,
3) *
B(3, 1);
T(i, 2) =
A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i,
3) *
B(3, 2);
T(i, 3) =
A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i,
3) *
B(3, 3);
}
#undef A
#undef B
#undef T
MEMCPY(product, temp, 16 * sizeof(GLdouble));
}
/*
* Compute inverse of 4x4 transformation matrix.
* Code contributed by Jacques Leroy jle@star.be
* Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
*/
static GLboolean
invert_matrix(const GLdouble * m, GLdouble * out)
{
/* NB. OpenGL Matrices are COLUMN major. */
#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
#define MAT(m,r,c) (m)[(c)*4+(r)]
GLdouble wtmp[4][8];
GLdouble m0, m1, m2, m3, s;
GLdouble *r0, *r1, *r2, *r3;
r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1),
r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3),
r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1),
r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3),
r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1),
r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3),
r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1),
r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3),
r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
/* choose pivot - or die */
if (fabs(r3[0]) > fabs(r2[0]))
SWAP_ROWS(r3, r2);
if (fabs(r2[0]) > fabs(r1[0]))
SWAP_ROWS(r2, r1);
if (fabs(r1[0]) > fabs(r0[0]))
SWAP_ROWS(r1, r0);
if (0.0 == r0[0])
return GL_FALSE;
/* eliminate first variable */
m1 = r1[0] / r0[0];
m2 = r2[0] / r0[0];
m3 = r3[0] / r0[0];
s = r0[1];
r1[1] -= m1 * s;
r2[1] -= m2 * s;
r3[1] -= m3 * s;
s = r0[2];
r1[2] -= m1 * s;
r2[2] -= m2 * s;
r3[2] -= m3 * s;
s = r0[3];
r1[3] -= m1 * s;
r2[3] -= m2 * s;
r3[3] -= m3 * s;
s = r0[4];
if (s != 0.0) {
r1[4] -= m1 * s;
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r0[5];
if (s != 0.0) {
r1[5] -= m1 * s;
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r0[6];
if (s != 0.0) {
r1[6] -= m1 * s;
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r0[7];
if (s != 0.0) {
r1[7] -= m1 * s;
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[1]) > fabs(r2[1]))
SWAP_ROWS(r3, r2);
if (fabs(r2[1]) > fabs(r1[1]))
SWAP_ROWS(r2, r1);
if (0.0 == r1[1])
return GL_FALSE;
/* eliminate second variable */
m2 = r2[1] / r1[1];
m3 = r3[1] / r1[1];
r2[2] -= m2 * r1[2];
r3[2] -= m3 * r1[2];
r2[3] -= m2 * r1[3];
r3[3] -= m3 * r1[3];
s = r1[4];
if (0.0 != s) {
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r1[5];
if (0.0 != s) {
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r1[6];
if (0.0 != s) {
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r1[7];
if (0.0 != s) {
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* choose pivot - or die */
if (fabs(r3[2]) > fabs(r2[2]))
SWAP_ROWS(r3, r2);
if (0.0 == r2[2])
return GL_FALSE;
/* eliminate third variable */
m3 = r3[2] / r2[2];
r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
/* last check */
if (0.0 == r3[3])
return GL_FALSE;
s = 1.0 / r3[3]; /* now back substitute row 3 */
r3[4] *= s;
r3[5] *= s;
r3[6] *= s;
r3[7] *= s;
m2 = r2[3]; /* now back substitute row 2 */
s = 1.0 / r2[2];
r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
m1 = r1[3];
r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
m0 = r0[3];
r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
m1 = r1[2]; /* now back substitute row 1 */
s = 1.0 / r1[1];
r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
m0 = r0[2];
r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
m0 = r0[1]; /* now back substitute row 0 */
s = 1.0 / r0[0];
r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
MAT(out, 0, 0) = r0[4];
MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6];
MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4];
MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6];
MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4];
MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6];
MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4];
MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6];
MAT(out, 3, 3) = r3[7];
return GL_TRUE;
#undef MAT
#undef SWAP_ROWS
}
/* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */
GLint GLAPIENTRY
gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * winx, GLdouble * winy, GLdouble * winz)
{
/* matrice de transformation */
GLdouble in[4], out[4];
/* initilise la matrice et le vecteur a transformer */
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0;
transform_point(out, model, in);
transform_point(in, proj, out);
/* d'ou le resultat normalise entre -1 et 1 */
if (in[3] == 0.0)
return GL_FALSE;
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
/* en coordonnees ecran */
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
/* entre 0 et 1 suivant z */
*winz = (1 + in[2]) / 2;
return GL_TRUE;
}
/* transformation du point ecran (winx,winy,winz) en point objet */
GLint GLAPIENTRY
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * objx, GLdouble * objy, GLdouble * objz)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2 * winz - 1.0;
in[3] = 1.0;
/* calcul transformation inverse */
matmul(A, proj, model);
invert_matrix(A, m);
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
return GL_TRUE;
}
/*
* New in GLU 1.3
* This is like gluUnProject but also takes near and far DepthRange values.
*/
#ifdef GLU_VERSION_1_3
GLint GLAPIENTRY
gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLclampd nearZ, GLclampd farZ,
GLdouble * objx, GLdouble * objy, GLdouble * objz,
GLdouble * objw)
{
/* matrice de transformation */
GLdouble m[16], A[16];
GLdouble in[4], out[4];
GLdouble z = nearZ + winz * (farZ - nearZ);
/* transformation coordonnees normalisees entre -1 et 1 */
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
in[2] = 2.0 * z - 1.0;
in[3] = clipw;
/* calcul transformation inverse */
matmul(A, projMatrix, modelMatrix);
invert_matrix(A, m);
/* d'ou les coordonnees objets */
transform_point(out, m, in);
if (out[3] == 0.0)
return GL_FALSE;
*objx = out[0] / out[3];
*objy = out[1] / out[3];
*objz = out[2] / out[3];
*objw = out[3];
return GL_TRUE;
}
#endif

774
src/glu/mini/quadric.c Normal file
View File

@@ -0,0 +1,774 @@
/* $Id: quadric.c,v 1.1.2.1 2003/03/21 13:02:22 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1999-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TODO:
* texture coordinate support
* flip normals according to orientation
* there's still some inside/outside orientation bugs in possibly all
* but the sphere function
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gluP.h"
#endif
#ifndef M_PI
# define M_PI (3.1415926)
#endif
/*
* Convert degrees to radians:
*/
#define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
/*
* Sin and Cos for degree angles:
*/
#define SIND( A ) sin( (A)*(M_PI/180.0) )
#define COSD( A) cos( (A)*(M_PI/180.0) )
/*
* Texture coordinates if texture flag is set
*/
#define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
struct GLUquadric
{
GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
GLboolean TextureFlag; /* Generate texture coords? */
GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
};
/*
* Process a GLU error.
*/
static void
quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
{
/* Call the error call back function if any */
if (qobj->ErrorFunc) {
(*qobj->ErrorFunc) (error);
}
/* Print a message to stdout if MESA_DEBUG variable is defined */
if (getenv("MESA_DEBUG")) {
fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
msg);
}
}
GLUquadricObj *GLAPIENTRY
gluNewQuadric(void)
{
GLUquadricObj *q;
q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
if (q) {
q->DrawStyle = GLU_FILL;
q->Orientation = GLU_OUTSIDE;
q->TextureFlag = GL_FALSE;
q->Normals = GLU_SMOOTH;
q->ErrorFunc = NULL;
}
return q;
}
void GLAPIENTRY
gluDeleteQuadric(GLUquadricObj * state)
{
if (state) {
free((void *) state);
}
}
/*
* Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
* or GLU_POINT.
*/
void GLAPIENTRY
gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
{
if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
|| drawStyle == GLU_SILHOUETTE
|| drawStyle == GLU_POINT)) {
quadObject->DrawStyle = drawStyle;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
}
}
/*
* Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
*/
void GLAPIENTRY
gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
{
if (quadObject
&& (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
quadObject->Orientation = orientation;
}
else {
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
}
}
/*
* Set the error handler callback function.
*/
void GLAPIENTRY
gluQuadricCallback(GLUquadricObj * qobj,
GLenum which, void (GLCALLBACK * fn) ())
{
/*
* UGH, this is a mess! I thought ANSI was a standard.
*/
if (qobj && which == GLU_ERROR) {
#ifdef __CYGWIN32__
qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
#elif defined(OPENSTEP)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#elif defined(_WIN32)
qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
#elif defined(__STORM__)
qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
#elif defined(__BEOS__)
qobj->ErrorFunc = (void (*)(GLenum)) fn;
#else
qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
#endif
}
}
void GLAPIENTRY
gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
{
if (quadObject
&& (normals == GLU_NONE || normals == GLU_FLAT
|| normals == GLU_SMOOTH)) {
quadObject->Normals = normals;
}
}
void GLAPIENTRY
gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
{
if (quadObject) {
quadObject->TextureFlag = textureCoords;
}
}
/*
* Call glNormal3f after scaling normal to unit length.
*/
static void
normal3f(GLfloat x, GLfloat y, GLfloat z)
{
}
void GLAPIENTRY
gluCylinder(GLUquadricObj * qobj,
GLdouble baseRadius, GLdouble topRadius,
GLdouble height, GLint slices, GLint stacks)
{
GLdouble da, r, dr, dz;
GLfloat x, y, z, nz, nsign;
GLint i, j;
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
da = 2.0 * M_PI / slices;
dr = (topRadius - baseRadius) / stacks;
dz = height / stacks;
nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
if (qobj->DrawStyle == GLU_POINT) {
glBegin(GL_POINTS);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glVertex3f(x * r, y * r, z);
z += dz;
r += dr;
}
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* Draw rings */
if (qobj->DrawStyle == GLU_LINE) {
z = 0.0;
r = baseRadius;
for (j = 0; j <= stacks; j++) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * r, y * r, z);
}
glEnd();
z += dz;
r += dr;
}
}
else {
/* draw one ring at each end */
if (baseRadius != 0.0) {
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
}
glEnd();
glBegin(GL_LINE_LOOP);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
}
/* draw length lines */
glBegin(GL_LINES);
for (i = 0; i < slices; i++) {
x = cos(i * da);
y = sin(i * da);
normal3f(x * nsign, y * nsign, nz * nsign);
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
glVertex3f(x * topRadius, y * topRadius, height);
}
glEnd();
}
else if (qobj->DrawStyle == GLU_FILL) {
GLfloat ds = 1.0 / slices;
GLfloat dt = 1.0 / stacks;
GLfloat t = 0.0;
z = 0.0;
r = baseRadius;
for (j = 0; j < stacks; j++) {
GLfloat s = 0.0;
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= slices; i++) {
GLfloat x, y;
if (i == slices) {
x = sin(0.0);
y = cos(0.0);
}
else {
x = sin(i * da);
y = cos(i * da);
}
if (nsign == 1.0) {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
else {
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t);
glVertex3f(x * r, y * r, z);
normal3f(x * nsign, y * nsign, nz * nsign);
TXTR_COORD(s, t + dt);
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
}
s += ds;
} /* for slices */
glEnd();
r += dr;
t += dt;
z += dz;
} /* for stacks */
}
}
void GLAPIENTRY
gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
{
GLfloat rho, drho, theta, dtheta;
GLfloat x, y, z;
GLfloat s, t, ds, dt;
GLint i, j, imin, imax;
GLboolean normals;
GLfloat nsign;
if (qobj->Normals == GLU_NONE) {
normals = GL_FALSE;
}
else {
normals = GL_TRUE;
}
if (qobj->Orientation == GLU_INSIDE) {
nsign = -1.0;
}
else {
nsign = 1.0;
}
drho = M_PI / (GLfloat) stacks;
dtheta = 2.0 * M_PI / (GLfloat) slices;
/* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
/* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
/* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
if (qobj->DrawStyle == GLU_FILL) {
if (!qobj->TextureFlag) {
/* draw +Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
/* glNormal3f(0.0, 0.0, 1.0); */
glVertex3f(0.0, 0.0, nsign * radius);
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(drho);
y = cos(theta) * sin(drho);
z = nsign * cos(drho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
ds = 1.0 / slices;
dt = 1.0 / stacks;
t = 1.0; /* because loop now runs from 0 */
if (qobj->TextureFlag) {
imin = 0;
imax = stacks;
}
else {
imin = 1;
imax = stacks - 1;
}
/* draw intermediate stacks as quad strips */
for (i = imin; i < imax; i++) {
rho = i * drho;
glBegin(GL_QUAD_STRIP);
s = 0.0;
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
TXTR_COORD(s, t);
glVertex3f(x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
TXTR_COORD(s, t - dt);
s += ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
t -= dt;
}
if (!qobj->TextureFlag) {
/* draw -Z end as a triangle fan */
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0, 0.0, -radius * nsign);
rho = M_PI - drho;
s = 1.0;
t = dt;
for (j = slices; j >= 0; j--) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
s -= ds;
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
/* draw stack lines */
for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
rho = i * drho;
glBegin(GL_LINE_LOOP);
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
/* draw slice lines */
for (j = 0; j < slices; j++) {
theta = j * dtheta;
glBegin(GL_LINE_STRIP);
for (i = 0; i <= stacks; i++) {
rho = i * drho;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
glEnd();
}
}
else if (qobj->DrawStyle == GLU_POINT) {
/* top and bottom-most points */
glBegin(GL_POINTS);
glVertex3f(0.0, 0.0, radius);
glVertex3f(0.0, 0.0, -radius);
/* loop over stacks */
for (i = 1; i < stacks - 1; i++) {
rho = i * drho;
for (j = 0; j < slices; j++) {
theta = j * dtheta;
x = cos(theta) * sin(rho);
y = sin(theta) * sin(rho);
z = cos(rho);
glVertex3f(x * radius, y * radius, z * radius);
}
}
glEnd();
}
}
void GLAPIENTRY
gluDisk(GLUquadricObj * qobj,
GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
{
GLfloat da, dr;
#if 0
GLdouble a, da;
GLfloat r, dr;
GLfloat x, y;
GLfloat r1, r2, dtc;
GLint s, l;
#endif
da = 2.0 * M_PI / slices;
dr = (outerRadius - innerRadius) / (GLfloat) loops;
switch (qobj->DrawStyle) {
case GLU_FILL:
{
/* texture of a gluDisk is a cut out of the texture unit square
* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
* (linear mapping)
*/
GLfloat dtc = 2.0f * outerRadius;
GLfloat sa, ca;
GLfloat r1 = innerRadius;
GLint l;
for (l = 0; l < loops; l++) {
GLfloat r2 = r1 + dr;
if (qobj->Orientation == GLU_OUTSIDE) {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = 0; s <= slices; s++) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
else {
GLint s;
glBegin(GL_QUAD_STRIP);
for (s = slices; s >= 0; s--) {
GLfloat a;
if (s == slices)
a = 0.0;
else
a = s * da;
sa = sin(a);
ca = cos(a);
TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
glVertex2f(r2 * sa, r2 * ca);
TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
glVertex2f(r1 * sa, r1 * ca);
}
glEnd();
}
r1 = r2;
}
break;
}
case GLU_LINE:
{
GLint l, s;
/* draw loops */
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glBegin(GL_LINE_LOOP);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
glVertex2f(r * sin(a), r * cos(a));
}
glEnd();
}
/* draw spokes */
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
glBegin(GL_LINE_STRIP);
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius + l * dr;
glVertex2f(r * x, r * y);
}
glEnd();
}
break;
}
case GLU_POINT:
{
GLint s;
glBegin(GL_POINTS);
for (s = 0; s < slices; s++) {
GLfloat a = s * da;
GLfloat x = sin(a);
GLfloat y = cos(a);
GLint l;
for (l = 0; l <= loops; l++) {
GLfloat r = innerRadius * l * dr;
glVertex2f(r * x, r * y);
}
}
glEnd();
break;
}
case GLU_SILHOUETTE:
{
if (innerRadius != 0.0) {
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0.0; a < 2.0 * M_PI; a += da) {
GLfloat x = innerRadius * sin(a);
GLfloat y = innerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
{
GLfloat a;
glBegin(GL_LINE_LOOP);
for (a = 0; a < 2.0 * M_PI; a += da) {
GLfloat x = outerRadius * sin(a);
GLfloat y = outerRadius * cos(a);
glVertex2f(x, y);
}
glEnd();
}
break;
}
default:
abort();
}
}
void GLAPIENTRY
gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
GLdouble outerRadius, GLint slices, GLint loops,
GLdouble startAngle, GLdouble sweepAngle)
{
if (qobj->DrawStyle == GLU_POINT) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / (loops - 1);
delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
glBegin(GL_POINTS);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
radius += delta_radius;
}
glEnd();
}
else if (qobj->DrawStyle == GLU_LINE) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw rings */
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
angle = DEG_TO_RAD(startAngle);
glBegin(GL_LINE_STRIP);
for (slice = 0; slice <= slices; slice++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
/* draw spokes */
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
radius = innerRadius;
glBegin(GL_LINE_STRIP);
for (loop = 0; loop < loops; loop++) {
glVertex2f(radius * sin(angle), radius * cos(angle));
radius += delta_radius;
}
glEnd();
angle += delta_angle;
}
}
else if (qobj->DrawStyle == GLU_SILHOUETTE) {
GLint slice;
GLdouble angle, delta_angle;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
/* draw outer ring */
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
glVertex2f(outerRadius * sin(angle), outerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
/* draw inner ring */
if (innerRadius > 0.0) {
glBegin(GL_LINE_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice < slices; slice++) {
glVertex2f(innerRadius * sin(angle), innerRadius * cos(angle));
angle += delta_angle;
}
glEnd();
}
/* draw spokes */
if (sweepAngle < 360.0) {
GLdouble stopAngle = startAngle + sweepAngle;
glBegin(GL_LINES);
glVertex2f(innerRadius * SIND(startAngle),
innerRadius * COSD(startAngle));
glVertex2f(outerRadius * SIND(startAngle),
outerRadius * COSD(startAngle));
glVertex2f(innerRadius * SIND(stopAngle),
innerRadius * COSD(stopAngle));
glVertex2f(outerRadius * SIND(stopAngle),
outerRadius * COSD(stopAngle));
glEnd();
}
}
else if (qobj->DrawStyle == GLU_FILL) {
GLint loop, slice;
GLdouble radius, delta_radius;
GLdouble angle, delta_angle;
delta_radius = (outerRadius - innerRadius) / loops;
delta_angle = DEG_TO_RAD(sweepAngle / slices);
radius = innerRadius;
for (loop = 0; loop < loops; loop++) {
glBegin(GL_QUAD_STRIP);
angle = DEG_TO_RAD(startAngle);
for (slice = 0; slice <= slices; slice++) {
if (qobj->Orientation == GLU_OUTSIDE) {
glVertex2f((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
glVertex2f(radius * sin(angle), radius * cos(angle));
}
else {
glVertex2f(radius * sin(angle), radius * cos(angle));
glVertex2f((radius + delta_radius) * sin(angle),
(radius + delta_radius) * cos(angle));
}
angle += delta_angle;
}
glEnd();
radius += delta_radius;
}
}
}

328
src/glu/mini/tess.c Normal file
View File

@@ -0,0 +1,328 @@
/* $Id: tess.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <math.h>
#include <stdlib.h>
#include "tess.h"
#endif
/*
* This is ugly, but seems the easiest way to do things to make the
* code work under YellowBox for Windows
*/
#if defined(OPENSTEP) && defined(CALLBACK)
#undef CALLBACK
#define CALLBACK
#endif
static void delete_contours(GLUtriangulatorObj *);
#ifdef __CYGWIN32__
#define _CALLBACK
#else
#define _CALLBACK GLCALLBACK
#endif
static void
init_callbacks(tess_callbacks * callbacks)
{
callbacks->begin = (void (_CALLBACK *) (GLenum)) 0;
callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0;
callbacks->vertex = (void (_CALLBACK *) (void *)) 0;
callbacks->end = (void (_CALLBACK *) (void)) 0;
callbacks->error = (void (_CALLBACK *) (GLenum)) 0;
}
void
tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr)
{
if (tobj->error == GLU_NO_ERROR)
tobj->error = gluerr;
if (tobj->callbacks.error != NULL)
(tobj->callbacks.error) (gluerr);
}
GLUtriangulatorObj *GLAPIENTRY
gluNewTess(void)
{
GLUtriangulatorObj *tobj;
if ((tobj = (GLUtriangulatorObj *)
malloc(sizeof(struct GLUtesselator))) == NULL)
return NULL;
tobj->contours = tobj->last_contour = NULL;
init_callbacks(&tobj->callbacks);
tobj->error = GLU_NO_ERROR;
tobj->current_polygon = NULL;
tobj->contour_cnt = 0;
return tobj;
}
void GLAPIENTRY
gluTessCallback(GLUtriangulatorObj * tobj, GLenum which,
void (GLCALLBACK * fn) ())
{
switch (which) {
case GLU_BEGIN:
tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn;
break;
case GLU_EDGE_FLAG:
tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn;
break;
case GLU_VERTEX:
tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn;
break;
case GLU_END:
tobj->callbacks.end = (void (_CALLBACK *) (void)) fn;
break;
case GLU_ERROR:
tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn;
break;
default:
tobj->error = GLU_INVALID_ENUM;
break;
}
}
void GLAPIENTRY
gluDeleteTess(GLUtriangulatorObj * tobj)
{
if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt)
/* was gluEndPolygon called? */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
free(tobj);
}
void GLAPIENTRY
gluBeginPolygon(GLUtriangulatorObj * tobj)
{
/*
if(tobj->error!=GLU_NO_ERROR)
return;
*/
tobj->error = GLU_NO_ERROR;
if (tobj->current_polygon != NULL) {
/* gluEndPolygon was not called */
tess_call_user_error(tobj, GLU_TESS_ERROR1);
/* delete all internal structures */
delete_contours(tobj);
}
else {
if ((tobj->current_polygon =
(tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
tobj->current_polygon->vertex_cnt = 0;
tobj->current_polygon->vertices =
tobj->current_polygon->last_vertex = NULL;
}
}
void GLAPIENTRY
gluEndPolygon(GLUtriangulatorObj * tobj)
{
/*tess_contour *contour_ptr; */
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* check if gluBeginPolygon was called */
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
tess_test_polygon(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* any real contours? */
if (tobj->contour_cnt == 0) {
/* delete all internal structures */
delete_contours(tobj);
return;
}
tess_find_contour_hierarchies(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
tess_handle_holes(tobj);
/* there was an error */
if (tobj->error != GLU_NO_ERROR)
goto end;
/* if no callbacks, nothing to do */
if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL &&
tobj->callbacks.end != NULL) {
if (tobj->callbacks.edgeFlag == NULL)
tess_tesselate(tobj);
else
tess_tesselate_with_edge_flag(tobj);
}
end:
/* delete all internal structures */
delete_contours(tobj);
}
void GLAPIENTRY
gluNextContour(GLUtriangulatorObj * tobj, GLenum type)
{
if (tobj->error != GLU_NO_ERROR)
return;
if (tobj->current_polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
/* first contour? */
if (tobj->current_polygon->vertex_cnt)
tess_test_polygon(tobj);
}
void GLAPIENTRY
gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data)
{
tess_polygon *polygon = tobj->current_polygon;
tess_vertex *last_vertex_ptr;
if (tobj->error != GLU_NO_ERROR)
return;
if (polygon == NULL) {
tess_call_user_error(tobj, GLU_TESS_ERROR2);
return;
}
last_vertex_ptr = polygon->last_vertex;
if (last_vertex_ptr == NULL) {
if ((last_vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
polygon->vertices = last_vertex_ptr;
polygon->last_vertex = last_vertex_ptr;
last_vertex_ptr->data = data;
last_vertex_ptr->location[0] = v[0];
last_vertex_ptr->location[1] = v[1];
last_vertex_ptr->location[2] = v[2];
last_vertex_ptr->next = NULL;
last_vertex_ptr->previous = NULL;
++(polygon->vertex_cnt);
}
else {
tess_vertex *vertex_ptr;
/* same point twice? */
if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON &&
fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON &&
fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) {
tess_call_user_error(tobj, GLU_TESS_ERROR6);
return;
}
if ((vertex_ptr = (tess_vertex *)
malloc(sizeof(tess_vertex))) == NULL) {
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
return;
}
vertex_ptr->data = data;
vertex_ptr->location[0] = v[0];
vertex_ptr->location[1] = v[1];
vertex_ptr->location[2] = v[2];
vertex_ptr->next = NULL;
vertex_ptr->previous = last_vertex_ptr;
++(polygon->vertex_cnt);
last_vertex_ptr->next = vertex_ptr;
polygon->last_vertex = vertex_ptr;
}
}
static void
delete_contours(GLUtriangulatorObj * tobj)
{
tess_polygon *polygon = tobj->current_polygon;
tess_contour *contour, *contour_tmp;
tess_vertex *vertex, *vertex_tmp;
/* remove current_polygon list - if exists due to detected error */
if (polygon != NULL) {
if (polygon->vertices) {
for (vertex = polygon->vertices; vertex != polygon->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
}
free(polygon);
tobj->current_polygon = NULL;
}
/* remove all contour data */
for (contour = tobj->contours; contour != NULL;) {
for (vertex = contour->vertices; vertex != contour->last_vertex;) {
vertex_tmp = vertex->next;
free(vertex);
vertex = vertex_tmp;
}
free(vertex);
contour_tmp = contour->next;
free(contour);
contour = contour_tmp;
}
tobj->contours = tobj->last_contour = NULL;
tobj->contour_cnt = 0;
}
void GLAPIENTRY
gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ)
{
/* dummy function */
(void) tess;
(void) valueX;
(void) valueY;
(void) valueZ;
}

108
src/glu/mini/tess.h Normal file
View File

@@ -0,0 +1,108 @@
/* $Id: tess.h,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifndef TESS_H
#define TESS_H
#include "gluP.h"
#define EPSILON 1e-06 /* epsilon for double precision compares */
typedef enum
{
OXY,
OYZ,
OXZ
}
projection_type;
typedef struct callbacks_str
{
void (GLCALLBACK * begin) (GLenum mode);
void (GLCALLBACK * edgeFlag) (GLboolean flag);
void (GLCALLBACK * vertex) (GLvoid * v);
void (GLCALLBACK * end) (void);
void (GLCALLBACK * error) (GLenum err);
}
tess_callbacks;
typedef struct vertex_str
{
void *data;
GLdouble location[3];
GLdouble x, y;
GLboolean edge_flag;
struct vertex_str *shadow_vertex;
struct vertex_str *next, *previous;
}
tess_vertex;
typedef struct contour_str
{
GLenum type;
GLuint vertex_cnt;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
struct contour_str *next, *previous;
}
tess_contour;
typedef struct polygon_str
{
GLuint vertex_cnt;
GLdouble A, B, C, D;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices, *last_vertex;
}
tess_polygon;
struct GLUtesselator
{
tess_contour *contours, *last_contour;
GLuint contour_cnt;
tess_callbacks callbacks;
tess_polygon *current_polygon;
GLenum error;
GLdouble A, B, C, D;
projection_type projection;
};
extern void tess_call_user_error(GLUtriangulatorObj *, GLenum);
extern void tess_test_polygon(GLUtriangulatorObj *);
extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
extern void tess_handle_holes(GLUtriangulatorObj *);
extern void tess_tesselate(GLUtriangulatorObj *);
extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
#endif

407
src/glu/mini/tesselat.c Normal file
View File

@@ -0,0 +1,407 @@
/* $Id: tesselat.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
* Copyright (C) 1995-2000 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdlib.h>
#include <math.h>
#include "tess.h"
#endif
static GLboolean edge_flag;
static void emit_triangle(GLUtriangulatorObj *, tess_vertex *,
tess_vertex *, tess_vertex *);
static void emit_triangle_with_edge_flag(GLUtriangulatorObj *,
tess_vertex *, GLboolean,
tess_vertex *, GLboolean,
tess_vertex *, GLboolean);
static GLdouble
twice_the_triangle_area(tess_vertex * va, tess_vertex * vb, tess_vertex * vc)
{
return (vb->x - va->x) * (vc->y - va->y) - (vb->y - va->y) * (vc->x -
va->x);
}
static GLboolean
left(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
{
if (A * x + B * y + C > -EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLboolean
right(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
{
if (A * x + B * y + C < EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLint
convex_ccw(tess_vertex * va,
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
{
GLdouble d;
d = twice_the_triangle_area(va, vb, vc);
if (d > EPSILON) {
return 1;
}
else if (d < -EPSILON) {
return 0;
}
else {
return -1;
}
}
static GLint
convex_cw(tess_vertex * va,
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
{
GLdouble d;
d = twice_the_triangle_area(va, vb, vc);
if (d < -EPSILON) {
return 1;
}
else if (d > EPSILON) {
return 0;
}
else {
return -1;
}
}
static GLboolean
diagonal_ccw(tess_vertex * va,
tess_vertex * vb,
GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
struct
{
GLdouble A, B, C;
}
ac, cb, ba;
GLdouble x, y;
GLint res = convex_ccw(va, vc, vb, tobj);
if (res == 0)
return GL_FALSE;
if (res == -1)
return GL_TRUE;
ba.A = vb->y - va->y;
ba.B = va->x - vb->x;
ba.C = -ba.A * va->x - ba.B * va->y;
ac.A = va->y - vc->y;
ac.B = vc->x - va->x;
ac.C = -ac.A * vc->x - ac.B * vc->y;
cb.A = vc->y - vb->y;
cb.B = vb->x - vc->x;
cb.C = -cb.A * vb->x - cb.B * vb->y;
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
shadow_vertex = vertex->shadow_vertex;
if (shadow_vertex != NULL &&
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
continue;
x = vertex->x;
y = vertex->y;
if (left(ba.A, ba.B, ba.C, x, y) &&
left(ac.A, ac.B, ac.C, x, y) && left(cb.A, cb.B, cb.C, x, y))
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean
diagonal_cw(tess_vertex * va,
tess_vertex * vb,
GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
struct
{
GLdouble A, B, C;
}
ac, cb, ba;
GLdouble x, y;
GLint res = convex_cw(va, vc, vb, tobj);
if (res == 0)
return GL_FALSE;
if (res == -1)
return GL_TRUE;
ba.A = vb->y - va->y;
ba.B = va->x - vb->x;
ba.C = -ba.A * va->x - ba.B * va->y;
ac.A = va->y - vc->y;
ac.B = vc->x - va->x;
ac.C = -ac.A * vc->x - ac.B * vc->y;
cb.A = vc->y - vb->y;
cb.B = vb->x - vc->x;
cb.C = -cb.A * vb->x - cb.B * vb->y;
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
shadow_vertex = vertex->shadow_vertex;
if (shadow_vertex != NULL &&
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
continue;
x = vertex->x;
y = vertex->y;
if (right(ba.A, ba.B, ba.C, x, y) &&
right(ac.A, ac.B, ac.C, x, y) && right(cb.A, cb.B, cb.C, x, y))
return GL_FALSE;
}
return GL_TRUE;
}
static void
clip_ear(GLUtriangulatorObj * tobj, tess_vertex * v, tess_contour * contour)
{
emit_triangle(tobj, v->previous, v, v->next);
/* the first in the list */
if (contour->vertices == v) {
contour->vertices = v->next;
contour->last_vertex->next = v->next;
v->next->previous = contour->last_vertex;
}
else
/* the last ? */
if (contour->last_vertex == v) {
contour->vertices->previous = v->previous;
v->previous->next = v->next;
contour->last_vertex = v->previous;
}
else {
v->next->previous = v->previous;
v->previous->next = v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void
clip_ear_with_edge_flag(GLUtriangulatorObj * tobj,
tess_vertex * v, tess_contour * contour)
{
emit_triangle_with_edge_flag(tobj, v->previous, v->previous->edge_flag,
v, v->edge_flag, v->next, GL_FALSE);
v->previous->edge_flag = GL_FALSE;
/* the first in the list */
if (contour->vertices == v) {
contour->vertices = v->next;
contour->last_vertex->next = v->next;
v->next->previous = contour->last_vertex;
}
else
/* the last ? */
if (contour->last_vertex == v) {
contour->vertices->previous = v->previous;
v->previous->next = v->next;
contour->last_vertex = v->previous;
}
else {
v->next->previous = v->previous;
v->previous->next = v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void
triangulate_ccw(GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_cw(GLUtriangulatorObj * tobj, tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_ccw_with_edge_flag(GLUtriangulatorObj * tobj,
tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj, vertex->next, contour);
--vertex_cnt;
}
}
static void
triangulate_cw_with_edge_flag(GLUtriangulatorObj * tobj,
tess_contour * contour)
{
tess_vertex *vertex;
GLuint vertex_cnt = contour->vertex_cnt;
while (vertex_cnt > 3) {
vertex = contour->vertices;
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
GL_FALSE && tobj->error == GLU_NO_ERROR)
vertex = vertex->next;
if (tobj->error != GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj, vertex->next, contour);
--vertex_cnt;
}
}
void
tess_tesselate(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
if (contour->orientation == GLU_CCW) {
triangulate_ccw(tobj, contour);
}
else {
triangulate_cw(tobj, contour);
}
if (tobj->error != GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle(tobj, contour->vertices, contour->vertices->next,
contour->vertices->next->next);
}
}
void
tess_tesselate_with_edge_flag(GLUtriangulatorObj * tobj)
{
tess_contour *contour;
edge_flag = GL_TRUE;
/* first callback with edgeFlag set to GL_TRUE */
(tobj->callbacks.edgeFlag) (GL_TRUE);
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
if (contour->orientation == GLU_CCW)
triangulate_ccw_with_edge_flag(tobj, contour);
else
triangulate_cw_with_edge_flag(tobj, contour);
if (tobj->error != GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle_with_edge_flag(tobj, contour->vertices,
contour->vertices->edge_flag,
contour->vertices->next,
contour->vertices->next->edge_flag,
contour->vertices->next->next,
contour->vertices->next->next->edge_flag);
}
}
static void
emit_triangle(GLUtriangulatorObj * tobj,
tess_vertex * v1, tess_vertex * v2, tess_vertex * v3)
{
(tobj->callbacks.begin) (GL_TRIANGLES);
(tobj->callbacks.vertex) (v1->data);
(tobj->callbacks.vertex) (v2->data);
(tobj->callbacks.vertex) (v3->data);
(tobj->callbacks.end) ();
}
static void
emit_triangle_with_edge_flag(GLUtriangulatorObj * tobj,
tess_vertex * v1,
GLboolean edge_flag1,
tess_vertex * v2,
GLboolean edge_flag2,
tess_vertex * v3, GLboolean edge_flag3)
{
(tobj->callbacks.begin) (GL_TRIANGLES);
if (edge_flag1 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v1->data);
if (edge_flag2 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v2->data);
if (edge_flag3 != edge_flag) {
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag) (edge_flag);
}
(tobj->callbacks.vertex) (v3->data);
(tobj->callbacks.end) ();
}

View File

@@ -1,43 +1,11 @@
# Mesa 3-D graphics library
# Version: 4.0
#
# Copyright (C) 1999 Brian Paul All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# DOS/DJGPP glut makefile v1.1 for Mesa 4.0
#
# Copyright (C) 2002 - Borca Daniel
# Email : dborca@yahoo.com
# Web : http://www.geocities.com/dborca
MESA = ../..
MARK = $(MESA)/src-glut
default: libglut.so.3.7 install
include $(MESA)/Makefile.include
.PHONY: all clean
TOP = ../..
MARK = $(TOP)/src-glut
LIBDIR = $(TOP)/lib
GLUT_LIB = libglut.so
CC = gcc
INCLUDES = -I$(TOP)/include -I$(MARK)
CFLAGS = -c -g $(INCLUDES) -MD
INCLUDES = -I$(MESA)/include -I$(MARK)
CORE_SOURCES = \
bitmap.c \
@@ -64,35 +32,19 @@ MARK_SOURCES = \
SOURCES = $(CORE_SOURCES) $(MARK_SOURCES)
OBJS = $(addsuffix .o,$(basename $(SOURCES)))
LIBS=-L$(TOP)/lib -lGL -lGLU -lm
.c.o:
$(CC) -o $@ -c $(CFLAGS) $<
.S.o:
$(CC) -o $@ -c $(CFLAGS) $<
default: libglut.so.3.7 install
OBJS = $(SOURCES:.c=.o)
LIBS = -L$(MESA)/lib -lGL -lGLU -lm
libglut.so.3.7: $(OBJS) Makefile
gcc -shared -Wl,-soname,libglut.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@
install:
rm -f $(TOP)/lib/libglut.so*
install -D libglut.so.3.7 $(TOP)/lib/libglut.so.3.7
ln -s libglut.so.3.7 $(TOP)/lib/libglut.so.3
ln -s libglut.so.3 $(TOP)/lib/libglut.so
clean:
rm -f *~ .*~ *.o libglut.so* *.d
rm -f $(MESA)/lib/libglut.so*
install -D libglut.so.3.7 $(MESA)/lib/libglut.so.3.7
ln -s libglut.so.3.7 $(MESA)/lib/libglut.so.3
ln -s libglut.so.3 $(MESA)/lib/libglut.so
-include $(SOURCES:.c=.d)
.SUFFIXES: .c .d
.c.d:
$(CC) -M $(INCLUDES) $< > $@

View File

@@ -12,8 +12,8 @@ glutBitmapCharacter(GLUTbitmapFont font, int c)
{
const BitmapCharRec *ch;
BitmapFontPtr fontinfo;
GLint swapbytes, lsbfirst, rowlength;
GLint skiprows, skippixels, alignment;
GLfloat swapbytes, lsbfirst, rowlength;
GLfloat skiprows, skippixels, alignment;
#if defined(_WIN32)
fontinfo = (BitmapFontPtr) __glutFont(font);
@@ -27,30 +27,30 @@ glutBitmapCharacter(GLUTbitmapFont font, int c)
ch = fontinfo->ch[c - fontinfo->first];
if (ch) {
/* Save current modes. */
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
/* glGetFloatv(GL_UNPACK_SWAP_BYTES, &swapbytes); */
/* glGetFloatv(GL_UNPACK_LSB_FIRST, &lsbfirst); */
/* glGetFloatv(GL_UNPACK_ROW_LENGTH, &rowlength); */
/* glGetFloatv(GL_UNPACK_SKIP_ROWS, &skiprows); */
/* glGetFloatv(GL_UNPACK_SKIP_PIXELS, &skippixels); */
glGetFloatv(GL_UNPACK_ALIGNMENT, &alignment);
/* Little endian machines (DEC Alpha for example) could
benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE
instead of GL_FALSE, but this would require changing the
generated bitmaps too. */
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); */
/* glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); */
/* glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); */
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
ch->advance, 0, ch->bitmap);
/* Restore saved modes. */
glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
/* glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); */
/* glPixelStorei(GL_UNPACK_LSB_FIRST, (int)lsbfirst); */
/* glPixelStorei(GL_UNPACK_ROW_LENGTH, (int)rowlength); */
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); */
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); */
glPixelStorei(GL_UNPACK_ALIGNMENT, (int)alignment);
}
}

View File

@@ -40,9 +40,6 @@ void APIENTRY glutInit (int *argcp, char **argv)
void APIENTRY glutInitDisplayMode (unsigned int mode)
{
g_display_mode = mode;
/* pc_install_keyb(); */
/* g_mouse = pc_install_mouse(); */
}
@@ -60,103 +57,3 @@ void APIENTRY glutInitWindowSize (int width, int height)
}
void APIENTRY glutMainLoop (void)
{
GLboolean idle;
static int old_mouse_x = 0;
static int old_mouse_y = 0;
static int old_mouse_b = 0;
glutPostRedisplay();
if (reshape_func) reshape_func(g_width, g_height);
if (visibility_func) visibility_func(GLUT_VISIBLE);
/* if (g_mouse) pc_show_mouse(); */
while (GL_TRUE) {
idle = GL_TRUE;
if (g_redisplay && display_func) {
idle = GL_FALSE;
g_redisplay = GL_FALSE;
/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_scare_mouse(); */
display_func();
/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_unscare_mouse(); */
}
#if 0
if (pc_keypressed()) {
int key;
idle = GL_FALSE;
key = pc_readkey();
switch (key>>16) {
case KEY_F1: if (special_func) special_func(GLUT_KEY_F1, 0, 0); break;
case KEY_F2: if (special_func) special_func(GLUT_KEY_F2, 0, 0); break;
case KEY_F3: if (special_func) special_func(GLUT_KEY_F3, 0, 0); break;
case KEY_F4: if (special_func) special_func(GLUT_KEY_F4, 0, 0); break;
case KEY_F5: if (special_func) special_func(GLUT_KEY_F5, 0, 0); break;
case KEY_F6: if (special_func) special_func(GLUT_KEY_F6, 0, 0); break;
case KEY_F7: if (special_func) special_func(GLUT_KEY_F7, 0, 0); break;
case KEY_F8: if (special_func) special_func(GLUT_KEY_F8, 0, 0); break;
case KEY_F9: if (special_func) special_func(GLUT_KEY_F9, 0, 0); break;
case KEY_F10: if (special_func) special_func(GLUT_KEY_F10, 0, 0); break;
case KEY_F11: if (special_func) special_func(GLUT_KEY_F11, 0, 0); break;
case KEY_F12: if (special_func) special_func(GLUT_KEY_F12, 0, 0); break;
case KEY_LEFT: if (special_func) special_func(GLUT_KEY_LEFT, 0, 0); break;
case KEY_UP: if (special_func) special_func(GLUT_KEY_UP, 0, 0); break;
case KEY_RIGHT: if (special_func) special_func(GLUT_KEY_RIGHT, 0, 0); break;
case KEY_DOWN: if (special_func) special_func(GLUT_KEY_DOWN, 0, 0); break;
case KEY_PGUP: if (special_func) special_func(GLUT_KEY_PAGE_UP, 0, 0); break;
case KEY_PGDN: if (special_func) special_func(GLUT_KEY_PAGE_DOWN, 0, 0); break;
case KEY_HOME: if (special_func) special_func(GLUT_KEY_HOME, 0, 0); break;
case KEY_END: if (special_func) special_func(GLUT_KEY_END, 0, 0); break;
case KEY_INSERT: if (special_func) special_func(GLUT_KEY_INSERT, 0, 0); break;
default: if (keyboard_func) keyboard_func(key & 0xFF, 0, 0);
}
}
if (g_mouse) {
int mouse_x;
int mouse_y;
int mouse_b;
mouse_b = pc_query_mouse(&mouse_x, &mouse_y);
if (motion_func && ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y))) {
idle = GL_FALSE;
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
motion_func(old_mouse_x, old_mouse_y);
}
if (mouse_func && (mouse_b != old_mouse_b)) {
int new_mouse_b = mouse_b;
if ((old_mouse_b & 1) && !(new_mouse_b & 1))
mouse_func(GLUT_LEFT_BUTTON, GLUT_UP, mouse_x, mouse_y);
else if (!(old_mouse_b & 1) && (new_mouse_b & 1))
mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
if ((old_mouse_b & 2) && !(new_mouse_b & 2))
mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP, mouse_x, mouse_y);
else if (!(old_mouse_b & 2) && (new_mouse_b & 2))
mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
if ((old_mouse_b & 4) && !(new_mouse_b & 4))
mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP, mouse_x, mouse_y);
else if (!(old_mouse_b & 3) && (new_mouse_b & 4))
mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
idle = GL_FALSE;
old_mouse_b = new_mouse_b;
}
}
#endif
if (idle && idle_func)
idle_func();
}
}

View File

@@ -152,7 +152,7 @@ drawBox(GLfloat size, GLenum type)
for (i = 5; i >= 0; i--) {
glBegin(type);
glNormal3fv(&n[i][0]);
/* glNormal3fv(&n[i][0]); */
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
@@ -205,9 +205,9 @@ doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
/* glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); */
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
/* glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); */
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
@@ -222,10 +222,10 @@ void APIENTRY
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
glPushAttrib(GL_POLYGON_BIT);
/* glPushAttrib(GL_POLYGON_BIT); */
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
doughnut(innerRadius, outerRadius, nsides, rings);
glPopAttrib();
/* glPopAttrib(); */
}
void APIENTRY
@@ -318,7 +318,7 @@ pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
normalize(n0);
glBegin(shadeType);
glNormal3fv(n0);
/* glNormal3fv(n0); */
glVertex3fv(&dodec[a][0]);
glVertex3fv(&dodec[b][0]);
glVertex3fv(&dodec[c][0]);
@@ -377,7 +377,7 @@ recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
normalize(q1);
glBegin(shadeType);
glNormal3fv(q1);
/* glNormal3fv(q1); */
glVertex3fv(n1);
glVertex3fv(n2);
glVertex3fv(n3);

View File

@@ -143,6 +143,7 @@ teapot(GLint grid, GLdouble scale, GLenum type)
float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
long i, j, k, l;
#if 0
glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
@@ -194,6 +195,7 @@ teapot(GLint grid, GLdouble scale, GLenum type)
}
glPopMatrix();
glPopAttrib();
#endif
}
/* CENTRY */

View File

@@ -218,3 +218,56 @@ void APIENTRY glutShowWindow (void)
void APIENTRY glutHideWindow (void)
{
}
void APIENTRY glutMainLoop (void)
{
GLboolean idle;
GLboolean have_event;
XEvent evt;
int visible = 0;
glutPostRedisplay();
if (reshape_func) reshape_func(g_width, g_height);
while (GL_TRUE) {
idle = GL_TRUE;
if (visible && idle_func)
have_event = XCheckMaskEvent( dpy, ~0, &evt );
else
have_event = XNextEvent( dpy, &evt );
if (have_event) {
idle = GL_FALSE;
switch(evt.type) {
case MapNotify:
if (visibility_func) {
visibility_func(GLUT_VISIBLE);
}
visible = 1;
break;
case UnmapNotify:
if (visibility_func) {
visibility_func(GLUT_NOT_VISIBLE);
}
visible = 0;
break;
case Expose:
g_redisplay = 1;
break;
}
}
if (visible && g_redisplay && display_func) {
idle = GL_FALSE;
g_redisplay = GL_FALSE;
display_func();
}
if (visible && idle && idle_func) {
idle_func();
}
}
}

1
src/kernel/agpgart/NOTES Normal file
View File

@@ -0,0 +1 @@
This directory not really of interest to anybody... Feel free to ignore.

1960
src/kernel/agpgart/agp.c Normal file

File diff suppressed because it is too large Load Diff

544
src/kernel/agpgart/agp.h Normal file
View File

@@ -0,0 +1,544 @@
/**
* \file agp.h
* AGPGART module generic backend
* \version 0.99
*
* \author Jeff Hartmann
*/
/*
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* 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
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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.
*
*/
#ifndef _AGP_BACKEND_PRIV_H
#define _AGP_BACKEND_PRIV_H 1
#include <asm/agp.h> /* for flush_agp_cache() */
extern struct agp_bridge_data agp_bridge;
/** \name Generic routines. */
/*@{*/
void agp_generic_agp_enable(u32 mode);
int agp_generic_create_gatt_table(void);
int agp_generic_free_gatt_table(void);
agp_memory *agp_create_memory(int scratch_pages);
int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
void agp_generic_free_by_type(agp_memory * curr);
void *agp_generic_alloc_page(void);
void agp_generic_destroy_page(void *addr);
int agp_generic_suspend(void);
void agp_generic_resume(void);
void agp_free_key(int key);
/*@}*/
/** \name Chipset specific initialization routines */
/*@{*/
int __init ali_generic_setup (struct pci_dev *pdev);
int __init amd_irongate_setup (struct pci_dev *pdev);
int __init amd_8151_setup (struct pci_dev *pdev);
int __init hp_zx1_setup (struct pci_dev *pdev);
int __init intel_i460_setup (struct pci_dev *pdev);
int __init intel_generic_setup (struct pci_dev *pdev);
int __init intel_i810_setup(struct pci_dev *i810_dev);
int __init intel_815_setup(struct pci_dev *pdev);
int __init intel_i830_setup(struct pci_dev *i830_dev);
int __init intel_820_setup (struct pci_dev *pdev);
int __init intel_830mp_setup (struct pci_dev *pdev);
int __init intel_840_setup (struct pci_dev *pdev);
int __init intel_845_setup (struct pci_dev *pdev);
int __init intel_850_setup (struct pci_dev *pdev);
int __init intel_860_setup (struct pci_dev *pdev);
int __init serverworks_setup (struct pci_dev *pdev);
int __init sis_generic_setup (struct pci_dev *pdev);
int __init via_generic_setup (struct pci_dev *pdev);
/*@}*/
#define AGPGART_MODULE_NAME "agpgart"
#define PFX AGPGART_MODULE_NAME ": "
/**
* \fn global_cache_flush
* Calls flush_agp_cache() on all processors.
*/
#ifdef CONFIG_SMP
static void ipi_handler(void *null)
{
flush_agp_cache();
}
static void __attribute__((unused)) global_cache_flush(void)
{
if (smp_call_function(ipi_handler, NULL, 1, 1) != 0)
panic(PFX "timed out waiting for the other CPUs!\n");
flush_agp_cache();
}
#else
static void global_cache_flush(void)
{
flush_agp_cache();
}
#endif /* !CONFIG_SMP */
/**
* Type of the aperture size fields in agp_bridge_data.
*/
enum aper_size_type {
U8_APER_SIZE, /**< aper_size_info_8 */
U16_APER_SIZE, /**< aper_size_info_16 */
U32_APER_SIZE, /**< aper_size_info_32 */
LVL2_APER_SIZE, /**< aper_size_info_lvl2 */
FIXED_APER_SIZE /**< aper_size_info_fixed */
};
/**
* Totally device specific, for integrated chipsets that
* might have different types of memory masks. For other
* devices this will probably be ignored.
*/
struct gatt_mask {
unsigned long mask;
u32 type;
};
/** Aperture size information - u8 */
struct aper_size_info_8 {
int size;
int num_entries;
int page_order;
u8 size_value;
};
/** Aperture size information - u16 */
struct aper_size_info_16 {
int size;
int num_entries;
int page_order;
u16 size_value;
};
/** Aperture size information - u32 */
struct aper_size_info_32 {
int size;
int num_entries;
int page_order;
u32 size_value;
};
/** Aperture size information - 2 level */
struct aper_size_info_lvl2 {
int size;
int num_entries;
u32 size_value;
};
/** Aperture size information - fixed */
struct aper_size_info_fixed {
int size;
int num_entries;
int page_order;
};
/**
* AGP bridge data.
*/
struct agp_bridge_data {
struct agp_version *version;
void *aperture_sizes; /**< All aperture sizes. \sa agp_bridge_data::size_type */
void *previous_size; /**< Previous aperture size. \sa agp_bridge_data::size_type */
void *current_size; /**< Current aperture size. One of
agp_bridge_data::aperture_sizes. \sa
agp_bridge_data::size_type */
void *dev_private_data;
struct pci_dev *dev; /**< PCI device */
struct gatt_mask *masks;
unsigned long *gatt_table;
unsigned long *gatt_table_real;
unsigned long scratch_page; /**< scratch page used as default value
in empty GATT entries */
unsigned long gart_bus_addr;
unsigned long gatt_bus_addr;
u32 mode; /**< bus mode */
enum chipset_type type;
enum aper_size_type size_type; /**< type of agp_bridge_data::aperture_sizes */
unsigned long *key_list; /**< bit array for the keys */
atomic_t current_memory_agp;
atomic_t agp_in_use; /**< whether the AGP device has been acquired */
int max_memory_agp; /**< maximum AGP memory in number of pages */
int needs_scratch_page; /**< whether to allocate a scratch page in
agp_bridge_data::scratch_page */
int aperture_size_idx;
int num_aperture_sizes;
int num_of_masks;
int capndx;
int cant_use_aperture;
/** \name Links to driver specific functions */
/*@{*/
int (*fetch_size) (void);
int (*configure) (void);
/**
* Enable the AGP bus.
*
* \param mode AGP mode.
*/
void (*agp_enable) (u32 mode);
void (*cleanup) (void);
/** Flush the table */
void (*tlb_flush) (agp_memory *);
unsigned long (*mask_memory) (unsigned long, int);
void (*cache_flush) (void);
/**
* Create the GATT table
*
* \return zero on success, or a negative number on failure.
*/
int (*create_gatt_table) (void);
/**
* Free the GATT table
*
* \return zero on success, or a negative number on failure.
*/
int (*free_gatt_table) (void);
/**
* Insert memory into the GATT table.
*
* \param mem memory.
* \param pg_start start page.
* \param type type.
* \return zero on success, or a negative number on failure.
*/
int (*insert_memory) (agp_memory *mem, off_t pg_start, int type);
/**
* Remove memory from the GATT table.
*
* \param mem memory.
* \param pg_start start page.
* \param type type.
* \return zero on success, or a negative number on failure.
*/
int (*remove_memory) (agp_memory *mem, off_t pg_start, int type);
/**
* Allocate memory by type.
*
* \param page_count number of pages to allocate.
* \param type type.
* \return pointer to a agp_memory structure on success, or NULL on failure.
*/
agp_memory *(*alloc_by_type) (size_t page_count, int type);
/**
* Free memory allocated with agp_bridge_data::alloc_by_type.
*
* \param curr memory to free.
*/
void (*free_by_type) (agp_memory * curr);
/**
* Allocate a page.
*
* \return pointer to a page on success, or zero on failure.
*/
void *(*agp_alloc_page) (void);
/**
* Destroy a page allocated with the agp_bridge_data::agp_alloc_page
* method.
*
* \param pointer to the page to be destroyed.
*/
void (*agp_destroy_page) (void *);
/** Suspend the device */
int (*suspend)(void);
/** Resume the device */
void (*resume)(void);
/*@}*/
};
/** Write a 64 bit register */
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
/** Write a 32 bit register */
#define OUTREG32(mmap, addr, val) __raw_writel((val), (mmap)+(addr))
/** Write a 16 bit register */
#define OUTREG16(mmap, addr, val) __raw_writew((val), (mmap)+(addr))
/** Write a 8 bit register */
#define OUTREG8(mmap, addr, val) __raw_writeb((val), (mmap)+(addr))
/** Read a 64 bit register */
#define INREG64(mmap, addr) __raw_readq((mmap)+(addr))
/** Read a 32 bit register */
#define INREG32(mmap, addr) __raw_readl((mmap)+(addr))
/** Read a 16 bit register */
#define INREG16(mmap, addr) __raw_readw((mmap)+(addr))
/** Read a 8 bit register */
#define INREG8(mmap, addr) __raw_readb((mmap)+(addr))
#define KB(x) ((x) * 1024)
#define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x)))
#define CACHE_FLUSH agp_bridge.cache_flush
/** Aperture size cast -- u8 */
#define A_SIZE_8(x) ((struct aper_size_info_8 *) x)
/** Aperture size cast -- u16 */
#define A_SIZE_16(x) ((struct aper_size_info_16 *) x)
/** Aperture size cast -- u32 */
#define A_SIZE_32(x) ((struct aper_size_info_32 *) x)
/** Aperture size cast -- 2 level */
#define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x)
/** Aperture size cast -- fixed */
#define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x)
/** Indexing of agp_bridge_data::aperture_sizes -- u8 */
#define A_IDX8() (A_SIZE_8(agp_bridge.aperture_sizes) + i)
/** Indexing of agp_bridge_data::aperture_sizes -- u16 */
#define A_IDX16() (A_SIZE_16(agp_bridge.aperture_sizes) + i)
/** Indexing of agp_bridge_data::aperture_sizes -- u32 */
#define A_IDX32() (A_SIZE_32(agp_bridge.aperture_sizes) + i)
/** Indexing of agp_bridge_data::aperture_sizes -- 2 level */
#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge.aperture_sizes) + i)
/** Indexing of agp_bridge_data::aperture_sizes -- fixed */
#define A_IDXFIX() (A_SIZE_FIX(agp_bridge.aperture_sizes) + i)
#define MAXKEY (4096 * 32)
/**
* Check for an empty page.
*
* \param p page.
* \return non-zero if \p p is empty, or zero otherwise.
*
* A page is empty if it's zero or points to the scratch page,
* agp_bridge_data::scratch_page.
*/
#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
/** \name Intel registers */
/*@{*/
#define INTEL_APBASE 0x10
#define INTEL_APSIZE 0xb4
#define INTEL_ATTBASE 0xb8
#define INTEL_AGPCTRL 0xb0
#define INTEL_NBXCFG 0x50
#define INTEL_ERRSTS 0x91
/*@}*/
/** \name Intel 460GX registers */
/*@{*/
#define INTEL_I460_APBASE 0x10
#define INTEL_I460_BAPBASE 0x98
#define INTEL_I460_GXBCTL 0xa0
#define INTEL_I460_AGPSIZ 0xa2
#define INTEL_I460_ATTBASE 0xfe200000
#define INTEL_I460_GATT_VALID (1UL << 24)
#define INTEL_I460_GATT_COHERENT (1UL << 25)
/*@}*/
/** \name Intel i830 registers */
/*@{*/
#define I830_GMCH_CTRL 0x52
#define I830_GMCH_ENABLED 0x4
#define I830_GMCH_MEM_MASK 0x1
#define I830_GMCH_MEM_64M 0x1
#define I830_GMCH_MEM_128M 0
#define I830_GMCH_GMS_MASK 0x70
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
#define I830_GMCH_GMS_STOLEN_1024 0x30
#define I830_GMCH_GMS_STOLEN_8192 0x40
#define I830_RDRAM_CHANNEL_TYPE 0x03010
#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5)
#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3)
/** This one is for I830MP with an external graphic card */
#define INTEL_I830_ERRSTS 0x92
/*@}*/
/** \name Intel 815 registers */
/*@{*/
#define INTEL_815_APCONT 0x51
#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
/*@}*/
/** \name Intel i820 registers */
/*@{*/
#define INTEL_I820_RDCR 0x51
#define INTEL_I820_ERRSTS 0xc8
/*@}*/
/** \name Intel i840 registers */
/*@{*/
#define INTEL_I840_MCHCFG 0x50
#define INTEL_I840_ERRSTS 0xc8
/*@}*/
/** \name Intel i845 registers */
/*@{*/
#define INTEL_I845_AGPM 0x51
#define INTEL_I845_ERRSTS 0xc8
/*@}*/
/** \name Intel i850 registers */
/*@{*/
#define INTEL_I850_MCHCFG 0x50
#define INTEL_I850_ERRSTS 0xc8
/*@}*/
/** \name Intel i860 registers */
/*@{*/
#define INTEL_I860_MCHCFG 0x50
#define INTEL_I860_ERRSTS 0xc8
/*@}*/
/** \name Intel i810 registers */
/*@{*/
#define I810_GMADDR 0x10
#define I810_MMADDR 0x14
#define I810_PTE_BASE 0x10000
#define I810_PTE_MAIN_UNCACHED 0x00000000
#define I810_PTE_LOCAL 0x00000002
#define I810_PTE_VALID 0x00000001
#define I810_SMRAM_MISCC 0x70
#define I810_GFX_MEM_WIN_SIZE 0x00010000
#define I810_GFX_MEM_WIN_32M 0x00010000
#define I810_GMS 0x000000c0
#define I810_GMS_DISABLE 0x00000000
#define I810_PGETBL_CTL 0x2020
#define I810_PGETBL_ENABLED 0x00000001
#define I810_DRAM_CTL 0x3000
#define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001
/*@}*/
/** \name VIA registers */
/*@{*/
#define VIA_APBASE 0x10
#define VIA_GARTCTRL 0x80
#define VIA_APSIZE 0x84
#define VIA_ATTBASE 0x88
/*@}*/
/** \name SiS registers */
/*@{*/
#define SIS_APBASE 0x10
#define SIS_ATTBASE 0x90
#define SIS_APSIZE 0x94
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
/*@}*/
/** \name AMD registers */
/*@{*/
#define AMD_APBASE 0x10
#define AMD_MMBASE 0x14
#define AMD_APSIZE 0xac
#define AMD_MODECNTL 0xb0
#define AMD_MODECNTL2 0xb2
#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
#define AMD_8151_APSIZE 0xb4
#define AMD_8151_GARTBLOCK 0xb8
#define AMD_X86_64_GARTAPERTURECTL 0x90
#define AMD_X86_64_GARTAPERTUREBASE 0x94
#define AMD_X86_64_GARTTABLEBASE 0x98
#define AMD_X86_64_GARTCACHECTL 0x9c
#define AMD_X86_64_GARTEN 1<<0
#define AMD_8151_VMAPERTURE 0x10
#define AMD_8151_AGP_CTL 0xb0
#define AMD_8151_APERTURESIZE 0xb4
#define AMD_8151_GARTPTR 0xb8
#define AMD_8151_GTLBEN 1<<7
#define AMD_8151_APEREN 1<<8
/*@}*/
/** \name ALi registers */
/*@{*/
#define ALI_APBASE 0x10
#define ALI_AGPCTRL 0xb8
#define ALI_ATTBASE 0xbc
#define ALI_TLBCTRL 0xc0
#define ALI_TAGCTRL 0xc4
#define ALI_CACHE_FLUSH_CTRL 0xD0
#define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000
#define ALI_CACHE_FLUSH_EN 0x100
/*@}*/
/** \name Serverworks Registers */
/*@{*/
#define SVWRKS_APSIZE 0x10
#define SVWRKS_SIZE_MASK 0xfe000000
#define SVWRKS_MMBASE 0x14
#define SVWRKS_CACHING 0x4b
#define SVWRKS_FEATURE 0x68
/* func 1 registers */
#define SVWRKS_AGP_ENABLE 0x60
#define SVWRKS_COMMAND 0x04
/* Memory mapped registers */
#define SVWRKS_GART_CACHE 0x02
#define SVWRKS_GATTBASE 0x04
#define SVWRKS_TLBFLUSH 0x10
#define SVWRKS_POSTFLUSH 0x14
#define SVWRKS_DIRFLUSH 0x0c
/*@}*/
/** \name HP ZX1 SBA registers */
/*@{*/
#define HP_ZX1_CTRL 0x200
#define HP_ZX1_IBASE 0x300
#define HP_ZX1_IMASK 0x308
#define HP_ZX1_PCOM 0x310
#define HP_ZX1_TCNFG 0x318
#define HP_ZX1_PDIR_BASE 0x320
#define HP_ZX1_CACHE_FLUSH 0x428
/*@}*/
#endif /* _AGP_BACKEND_PRIV_H */

View File

@@ -0,0 +1,171 @@
/**
* \file agp_backend.h
* AGPGART module backend
* \version 0.99
*
* \author Jeff Hartmann
*/
/*
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* 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
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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.
*
*/
#ifndef _AGP_BACKEND_H
#define _AGP_BACKEND_H 1
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define AGPGART_VERSION_MAJOR 0
#define AGPGART_VERSION_MINOR 99
/** Supported chipset types */
enum chipset_type {
NOT_SUPPORTED,
INTEL_GENERIC,
INTEL_LX,
INTEL_BX,
INTEL_GX,
INTEL_I810,
INTEL_I815,
INTEL_I820,
INTEL_I830_M,
INTEL_I845_G,
INTEL_I840,
INTEL_I845,
INTEL_I850,
INTEL_I860,
INTEL_460GX,
VIA_GENERIC,
VIA_VP3,
VIA_MVP3,
VIA_MVP4,
VIA_APOLLO_PRO,
VIA_APOLLO_KX133,
VIA_APOLLO_KT133,
SIS_GENERIC,
AMD_GENERIC,
AMD_IRONGATE,
AMD_761,
AMD_762,
AMD_8151,
ALI_M1541,
ALI_M1621,
ALI_M1631,
ALI_M1632,
ALI_M1641,
ALI_M1644,
ALI_M1647,
ALI_M1651,
ALI_M1671,
ALI_GENERIC,
SVWRKS_HE,
SVWRKS_LE,
SVWRKS_GENERIC,
HP_ZX1,
};
struct agp_version {
u16 major;
u16 minor;
};
typedef struct _agp_kern_info {
struct agp_version version;
struct pci_dev *device;
enum chipset_type chipset;
unsigned long mode;
off_t aper_base;
size_t aper_size;
int max_memory; /**< In pages */
int current_memory;
int cant_use_aperture;
unsigned long page_mask;
} agp_kern_info;
/**
* The agp_memory structure has information
* about the block of agp memory allocated.
* A caller may manipulate the next and prev
* pointers to link each allocated item into
* a list. These pointers are ignored by the
* backend. Everything else should never be
* written to, but the caller may read any of
* the items to detrimine the status of this
* block of agp memory.
*/
typedef struct _agp_memory {
int key; /** hash key */
struct _agp_memory *next;
struct _agp_memory *prev;
size_t page_count;
int num_scratch_pages;
unsigned long *memory;
off_t pg_start;
u32 type;
u32 physical;
u8 is_bound;
u8 is_flushed;
} agp_memory;
#define AGP_NORMAL_MEMORY 0
extern void agp_free_memory(agp_memory *);
extern agp_memory *agp_allocate_memory(size_t, u32);
extern int agp_copy_info(agp_kern_info *);
extern int agp_bind_memory(agp_memory *, off_t);
extern int agp_unbind_memory(agp_memory *);
extern void agp_enable(u32);
extern int agp_backend_acquire(void);
extern void agp_backend_release(void);
/**
* Interface between DRM and AGP code. When AGP initializes, it makes
* this structure available via inter_module_register(), DRM might
* use it.
*
* \author Keith Owens <kaos@ocs.com.au>
* \date 28 Oct 2000.
*/
typedef struct {
void (*free_memory)(agp_memory *);
agp_memory *(*allocate_memory)(size_t, u32);
int (*bind_memory)(agp_memory *, off_t);
int (*unbind_memory)(agp_memory *);
void (*enable)(u32);
int (*acquire)(void);
void (*release)(void);
int (*copy_info)(agp_kern_info *);
} drm_agp_t;
extern const drm_agp_t *drm_agp_p;
#endif /* _AGP_BACKEND_H */

View File

@@ -0,0 +1,248 @@
/**
* \file agpgart.h
* AGPGART module
* \version 0.99
*
* \author Jeff Hartmann
*/
/*
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* 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
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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.
*
*/
#ifndef _AGP_H
#define _AGP_H 1
#define AGPIOC_BASE 'A'
#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, agp_info*)
#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, agp_setup*)
#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, agp_region*)
#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, agp_region*)
#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, agp_allocate*)
#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, agp_bind*)
#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, agp_unbind*)
#define AGP_DEVICE "/dev/agpgart"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef __KERNEL__
#include <linux/types.h>
#include <asm/types.h>
struct agp_version {
__u16 major;
__u16 minor;
};
typedef struct _agp_info {
struct agp_version version; /**< version of the driver */
__u32 bridge_id; /**< bridge vendor/device */
__u32 agp_mode; /**< mode info of bridge */
off_t aper_base; /**< base of aperture */
size_t aper_size; /**< size of aperture */
size_t pg_total; /**< max pages (swap + system) */
size_t pg_system; /**< max pages (system) */
size_t pg_used; /**< current pages used */
} agp_info;
typedef struct _agp_setup {
__u32 agp_mode; /**< mode info of bridge */
} agp_setup;
/**<
* The "prot" down below needs still a "sleep" flag somehow ...
*/
typedef struct _agp_segment {
off_t pg_start; /**< starting page to populate */
size_t pg_count; /**< number of pages */
int prot; /**< prot flags for mmap */
} agp_segment;
typedef struct _agp_region {
pid_t pid; /**< pid of process */
size_t seg_count; /**< number of segments */
struct _agp_segment *seg_list;
} agp_region;
typedef struct _agp_allocate {
int key; /**< tag of allocation */
size_t pg_count; /**< number of pages */
__u32 type; /**< 0 == normal, other devspec */
__u32 physical; /**< device specific (some devices
* need a phys address of the
* actual page behind the gatt
* table) */
} agp_allocate;
typedef struct _agp_bind {
int key; /**< tag of allocation */
off_t pg_start; /**< starting page to populate */
} agp_bind;
typedef struct _agp_unbind {
int key; /**< tag of allocation */
__u32 priority; /**< priority for paging out */
} agp_unbind;
#else /* __KERNEL__ */
#define AGPGART_MINOR 175
/** Unlocks the AGP device */
#define AGP_UNLOCK() up(&(agp_fe.agp_mutex));
/** Locks the AGP device */
#define AGP_LOCK() down(&(agp_fe.agp_mutex));
/** Initializes the AGP device lock */
#define AGP_LOCK_INIT() sema_init(&(agp_fe.agp_mutex), 1)
#ifndef _AGP_BACKEND_H
struct _agp_version {
u16 major;
u16 minor;
} agp_version;
#endif
/** Information ioctl argument */
typedef struct _agp_info {
struct agp_version version; /**< version of the driver */
u32 bridge_id; /**< bridge vendor/device */
u32 agp_mode; /**< mode info of bridge */
off_t aper_base; /**< base of aperture */
size_t aper_size; /**< size of aperture */
size_t pg_total; /**< max pages (swap + system) */
size_t pg_system; /**< max pages (system) */
size_t pg_used; /**< current pages used */
} agp_info;
/** Setup ioctl argument */
typedef struct _agp_setup {
u32 agp_mode; /**< mode info of bridge */
} agp_setup;
/** Segment (user). */
typedef struct _agp_segment {
off_t pg_start; /**< starting page to populate */
size_t pg_count; /**< number of pages */
int prot; /**< prot flags for mmap.
* \todo still needs a "sleep" flag somehow...
* */
} agp_segment;
/** Segment (private) */
typedef struct _agp_segment_priv {
off_t pg_start; /**< starting page to populate */
size_t pg_count; /**< number of pages */
pgprot_t prot; /**< memory protection flags */
} agp_segment_priv;
/** Reserve ioctl argument */
typedef struct _agp_region {
pid_t pid; /**< pid of process */
size_t seg_count; /**< number of segments */
struct _agp_segment *seg_list;
} agp_region;
/** Allocate ioctl argument */
typedef struct _agp_allocate {
int key; /**< tag of allocation */
size_t pg_count; /**< number of pages */
u32 type; /**< 0 == normal, other devspec */
u32 physical; /**< device specific (some devices
* need a phys address of the
* actual page behind the gatt
* table) */
} agp_allocate;
/** Bind ioctl argument */
typedef struct _agp_bind {
int key; /**< tag of allocation */
off_t pg_start; /**< starting page to populate */
} agp_bind;
/** Unbind ioctl argument */
typedef struct _agp_unbind {
int key; /**< tag of allocation */
u32 priority; /**< priority for paging out */
} agp_unbind;
/** AGP client */
typedef struct _agp_client {
struct _agp_client *next;
struct _agp_client *prev;
pid_t pid; /**< process id */
int num_segments; /**< number of segments */
agp_segment_priv **segments; /**< segment array */
} agp_client;
/** AGP controller. */
typedef struct _agp_controller {
struct _agp_controller *next;
struct _agp_controller *prev;
pid_t pid; /**< process id */
int num_clients; /**< number of clients */
agp_memory *pool; /**< doubly linked memory pool */
agp_client *clients; /**< doubly linked client list */
} agp_controller;
/** \name File flags */
/*@{*/
#define AGP_FF_ALLOW_CLIENT 0
#define AGP_FF_ALLOW_CONTROLLER 1
#define AGP_FF_IS_CLIENT 2
#define AGP_FF_IS_CONTROLLER 3
#define AGP_FF_IS_VALID 4
/*@}*/
/** File private data. */
typedef struct _agp_file_private {
struct _agp_file_private *next;
struct _agp_file_private *prev;
pid_t my_pid; /**< process id */
long access_flags; /**< long required for set_bit --RR */
} agp_file_private;
/** Frontend data. */
struct agp_front_data {
struct semaphore agp_mutex; /**< device mutex. \sa #AGP_INIT, #AGP_LOCK and #AGP_UNLOCK */
agp_controller *current_controller; /**< current controller */
agp_controller *controllers; /**< controllers list */
agp_file_private *file_priv_list; /**< file private data doubly linked list */
u8 used_by_controller;
u8 backend_acquired; /**< whether the backend has been acquired */
};
#endif /* __KERNEL__ */
#endif /* _AGP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,600 @@
/**
* \file i810_agp.c
* AGPGART module i810 backend
* \version 0.99
*
* \author Jeff Hartmann
*
* \todo Allocate more than order 0 pages to avoid too much linear map splitting.
*/
/*
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* 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
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
static struct aper_size_info_fixed intel_i810_sizes[] =
{
{64, 16384, 4},
/* The 32M mode still requires a 64k gatt */
{32, 8192, 4}
};
#define AGP_DCACHE_MEMORY 1
#define AGP_PHYS_MEMORY 2
static struct gatt_mask intel_i810_masks[] =
{
{mask: I810_PTE_VALID, type: 0},
{mask: (I810_PTE_VALID | I810_PTE_LOCAL), type: AGP_DCACHE_MEMORY},
{mask: I810_PTE_VALID, type: 0}
};
static struct _intel_i810_private {
struct pci_dev *i810_dev; /* device one */
volatile u8 *registers;
int num_dcache_entries;
} intel_i810_private;
static int intel_i810_fetch_size(void)
{
u32 smram_miscc;
struct aper_size_info_fixed *values;
pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
values = A_SIZE_FIX(agp_bridge.aperture_sizes);
if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
printk(KERN_WARNING PFX "i810 is disabled\n");
return 0;
}
if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
agp_bridge.previous_size =
agp_bridge.current_size = (void *) (values + 1);
agp_bridge.aperture_size_idx = 1;
return values[1].size;
} else {
agp_bridge.previous_size =
agp_bridge.current_size = (void *) (values);
agp_bridge.aperture_size_idx = 0;
return values[0].size;
}
return 0;
}
static int intel_i810_configure(void)
{
struct aper_size_info_fixed *current_size;
u32 temp;
int i;
current_size = A_SIZE_FIX(agp_bridge.current_size);
pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
temp &= 0xfff80000;
intel_i810_private.registers =
(volatile u8 *) ioremap(temp, 128 * 4096);
if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
/* This will need to be dynamically assigned */
printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
intel_i810_private.num_dcache_entries = 1024;
}
pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
CACHE_FLUSH();
if (agp_bridge.needs_scratch_page == TRUE) {
for (i = 0; i < current_size->num_entries; i++) {
OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4),
agp_bridge.scratch_page);
}
}
return 0;
}
static void intel_i810_cleanup(void)
{
OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
iounmap((void *) intel_i810_private.registers);
}
static void intel_i810_tlbflush(agp_memory * mem)
{
return;
}
static void intel_i810_agp_enable(u32 mode)
{
return;
}
static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
int type)
{
int i, j, num_entries;
void *temp;
temp = agp_bridge.current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if ((pg_start + mem->page_count) > num_entries) {
return -EINVAL;
}
for (j = pg_start; j < (pg_start + mem->page_count); j++) {
if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
return -EBUSY;
}
}
if (type != 0 || mem->type != 0) {
if ((type == AGP_DCACHE_MEMORY) &&
(mem->type == AGP_DCACHE_MEMORY)) {
/* special insert */
CACHE_FLUSH();
for (i = pg_start;
i < (pg_start + mem->page_count); i++) {
OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4),
(i * 4096) | I810_PTE_LOCAL |
I810_PTE_VALID);
}
CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return 0;
}
if((type == AGP_PHYS_MEMORY) &&
(mem->type == AGP_PHYS_MEMORY)) {
goto insert;
}
return -EINVAL;
}
insert:
CACHE_FLUSH();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (j * 4), mem->memory[i]);
}
CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return 0;
}
static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
int type)
{
int i;
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4),
agp_bridge.scratch_page);
}
CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return 0;
}
static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
{
agp_memory *new;
if (type == AGP_DCACHE_MEMORY) {
if (pg_count != intel_i810_private.num_dcache_entries) {
return NULL;
}
new = agp_create_memory(1);
if (new == NULL) {
return NULL;
}
new->type = AGP_DCACHE_MEMORY;
new->page_count = pg_count;
new->num_scratch_pages = 0;
vfree(new->memory);
MOD_INC_USE_COUNT;
return new;
}
if(type == AGP_PHYS_MEMORY) {
void *addr;
/* The I810 requires a physical address to program
* it's mouse pointer into hardware. However the
* Xserver still writes to it through the agp
* aperture
*/
if (pg_count != 1) {
return NULL;
}
new = agp_create_memory(1);
if (new == NULL) {
return NULL;
}
MOD_INC_USE_COUNT;
addr = agp_bridge.agp_alloc_page();
if (addr == NULL) {
/* Free this structure */
agp_free_memory(new);
return NULL;
}
new->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr), type);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
new->physical = virt_to_phys((void *) new->memory[0]);
return new;
}
return NULL;
}
static void intel_i810_free_by_type(agp_memory * curr)
{
agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) {
agp_bridge.agp_destroy_page(
phys_to_virt(curr->memory[0]));
vfree(curr->memory);
}
kfree(curr);
MOD_DEC_USE_COUNT;
}
static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
{
/* Type checking must be done elsewhere */
return addr | agp_bridge.masks[type].mask;
}
int __init intel_i810_setup(struct pci_dev *i810_dev)
{
intel_i810_private.i810_dev = i810_dev;
agp_bridge.masks = intel_i810_masks;
agp_bridge.num_of_masks = 2;
agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
agp_bridge.size_type = FIXED_APER_SIZE;
agp_bridge.num_aperture_sizes = 2;
agp_bridge.dev_private_data = (void *) &intel_i810_private;
agp_bridge.needs_scratch_page = TRUE;
agp_bridge.configure = intel_i810_configure;
agp_bridge.fetch_size = intel_i810_fetch_size;
agp_bridge.cleanup = intel_i810_cleanup;
agp_bridge.tlb_flush = intel_i810_tlbflush;
agp_bridge.mask_memory = intel_i810_mask_memory;
agp_bridge.agp_enable = intel_i810_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = intel_i810_insert_entries;
agp_bridge.remove_memory = intel_i810_remove_entries;
agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
agp_bridge.free_by_type = intel_i810_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
}
static struct aper_size_info_fixed intel_i830_sizes[] =
{
{128, 32768, 5},
/* The 64M mode still requires a 128k gatt */
{64, 16384, 5}
};
static struct _intel_i830_private {
struct pci_dev *i830_dev; /* device one */
volatile u8 *registers;
int gtt_entries;
} intel_i830_private;
static void intel_i830_init_gtt_entries(void)
{
u16 gmch_ctrl;
int gtt_entries;
u8 rdct;
static const int ddt[4] = { 0, 16, 32, 64 };
pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I830_GMCH_GMS_STOLEN_512:
gtt_entries = KB(512) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break;
case I830_GMCH_GMS_STOLEN_1024:
gtt_entries = MB(1) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break;
case I830_GMCH_GMS_STOLEN_8192:
gtt_entries = MB(8) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break;
case I830_GMCH_GMS_LOCAL:
rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE);
gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]);
printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1));
break;
default:
printk(KERN_INFO PFX "no video memory detected.\n");
gtt_entries = 0;
break;
}
gtt_entries /= KB(4);
intel_i830_private.gtt_entries = gtt_entries;
}
/* The intel i830 automatically initializes the agp aperture during POST.
* Use the memory already set aside for in the GTT.
*/
static int intel_i830_create_gatt_table(void)
{
int page_order;
struct aper_size_info_fixed *size;
int num_entries;
u32 temp;
size = agp_bridge.current_size;
page_order = size->page_order;
num_entries = size->num_entries;
agp_bridge.gatt_table_real = 0;
pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
temp &= 0xfff80000;
intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
if (!intel_i830_private.registers) return (-ENOMEM);
temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
CACHE_FLUSH();
/* we have to call this as early as possible after the MMIO base address is known */
intel_i830_init_gtt_entries();
agp_bridge.gatt_table = NULL;
agp_bridge.gatt_bus_addr = temp;
return(0);
}
/* Return the gatt table to a sane state. Use the top of stolen
* memory for the GTT.
*/
static int intel_i830_free_gatt_table(void)
{
return(0);
}
static int intel_i830_fetch_size(void)
{
u16 gmch_ctrl;
struct aper_size_info_fixed *values;
pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
values = A_SIZE_FIX(agp_bridge.aperture_sizes);
if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
agp_bridge.aperture_size_idx = 0;
return(values[0].size);
} else {
agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
agp_bridge.aperture_size_idx = 1;
return(values[1].size);
}
return(0);
}
static int intel_i830_configure(void)
{
struct aper_size_info_fixed *current_size;
u32 temp;
u16 gmch_ctrl;
int i;
current_size = A_SIZE_FIX(agp_bridge.current_size);
pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl);
OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
CACHE_FLUSH();
if (agp_bridge.needs_scratch_page == TRUE)
for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
return (0);
}
static void intel_i830_cleanup(void)
{
iounmap((void *) intel_i830_private.registers);
}
static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
{
int i,j,num_entries;
void *temp;
temp = agp_bridge.current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if (pg_start < intel_i830_private.gtt_entries) {
printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
pg_start,intel_i830_private.gtt_entries);
printk ("Trying to insert into local/stolen memory\n");
return (-EINVAL);
}
if ((pg_start + mem->page_count) > num_entries)
return (-EINVAL);
/* The i830 can't check the GTT for entries since its read only,
* depend on the caller to make the correct offset decisions.
*/
if ((type != 0 && type != AGP_PHYS_MEMORY) ||
(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
return (-EINVAL);
CACHE_FLUSH();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),mem->memory[i]);
CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return(0);
}
static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
{
int i;
CACHE_FLUSH ();
if (pg_start < intel_i830_private.gtt_entries) {
printk ("Trying to disable local/stolen memory\n");
return (-EINVAL);
}
for (i = pg_start; i < (mem->page_count + pg_start); i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
CACHE_FLUSH();
agp_bridge.tlb_flush(mem);
return (0);
}
static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
{
agp_memory *nw;
/* always return NULL for now */
if (type == AGP_DCACHE_MEMORY) return(NULL);
if (type == AGP_PHYS_MEMORY) {
void *addr;
/* The i830 requires a physical address to program
* it's mouse pointer into hardware. However the
* Xserver still writes to it through the agp
* aperture
*/
if (pg_count != 1) return(NULL);
nw = agp_create_memory(1);
if (nw == NULL) return(NULL);
MOD_INC_USE_COUNT;
addr = agp_bridge.agp_alloc_page();
if (addr == NULL) {
/* free this structure */
agp_free_memory(nw);
return(NULL);
}
nw->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr),type);
nw->page_count = 1;
nw->num_scratch_pages = 1;
nw->type = AGP_PHYS_MEMORY;
nw->physical = virt_to_phys(addr);
return(nw);
}
return(NULL);
}
int __init intel_i830_setup(struct pci_dev *i830_dev)
{
intel_i830_private.i830_dev = i830_dev;
agp_bridge.masks = intel_i810_masks;
agp_bridge.num_of_masks = 3;
agp_bridge.aperture_sizes = (void *) intel_i830_sizes;
agp_bridge.size_type = FIXED_APER_SIZE;
agp_bridge.num_aperture_sizes = 2;
agp_bridge.dev_private_data = (void *) &intel_i830_private;
agp_bridge.needs_scratch_page = TRUE;
agp_bridge.configure = intel_i830_configure;
agp_bridge.fetch_size = intel_i830_fetch_size;
agp_bridge.cleanup = intel_i830_cleanup;
agp_bridge.tlb_flush = intel_i810_tlbflush;
agp_bridge.mask_memory = intel_i810_mask_memory;
agp_bridge.agp_enable = intel_i810_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = intel_i830_create_gatt_table;
agp_bridge.free_gatt_table = intel_i830_free_gatt_table;
agp_bridge.insert_memory = intel_i830_insert_entries;
agp_bridge.remove_memory = intel_i830_remove_entries;
agp_bridge.alloc_by_type = intel_i830_alloc_by_type;
agp_bridge.free_by_type = intel_i810_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return(0);
}

View File

@@ -0,0 +1,872 @@
/**
* \file i8x0_agp.c
* AGPGART module i8x0 backend
* \version 0.99
*
* \author Jeff Hartmann
*
* \todo Allocate more than order 0 pages to avoid too much linear map splitting.
*/
/*
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* 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
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
/**
* Fetch aperture size -- Intel generic.
*
* \return always zero.
*
* Reads the aperture size from the hardware and points agp_bridge_data::previous_size and
* agp_bridge_data::current_size to the agp_bridge_data::aperture_sizes entry
* with the matching aperture size.
*/
static int intel_fetch_size(void)
{
int i;
u16 temp;
struct aper_size_info_16 *values;
pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
values = A_SIZE_16(agp_bridge.aperture_sizes);
for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge.previous_size =
agp_bridge.current_size = (void *) (values + i);
agp_bridge.aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
/**
* Fetch aperture size -- Intel i8xx.
*
* \return always zero.
*
* Same as for intel_fetch_size() but with special care for Intel 815 chipsets
* which have only one non-reserved bit on the APSIZE register.
*/
static int intel_8xx_fetch_size(void)
{
int i;
u8 temp;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp);
/* Intel 815 chipsets have a _weird_ APSIZE register with only
* one non-reserved bit, so mask the others out ... */
if (agp_bridge.type == INTEL_I815)
temp &= (1 << 3);
values = A_SIZE_8(agp_bridge.aperture_sizes);
for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge.previous_size =
agp_bridge.current_size = (void *) (values + i);
agp_bridge.aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
/**
* Flush the table -- Intel generic.
*/
static void intel_tlbflush(agp_memory * mem)
{
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
}
/**
* Flush the table -- Intel i8xx.
*/
static void intel_8xx_tlbflush(agp_memory * mem)
{
u32 temp;
pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7));
pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7));
}
/**
* Backend cleanup -- Intel generic.
*
* Resets the hardware using the previous aperture size.
*/
static void intel_cleanup(void)
{
u16 temp;
struct aper_size_info_16 *previous_size;
previous_size = A_SIZE_16(agp_bridge.previous_size);
pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
pci_write_config_word(agp_bridge.dev, INTEL_APSIZE,
previous_size->size_value);
}
/**
* Backend cleanup -- Intel i8xx.
*
* Same as intel_cleanup().
*/
static void intel_8xx_cleanup(void)
{
u16 temp;
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge.previous_size);
pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
previous_size->size_value);
}
/**
* Configure -- Intel generic.
*
* \return always zero.
*
* Updates the hardware registers to match the information in agp_bridge_data.
*/
static int intel_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_16 *current_size;
current_size = A_SIZE_16(agp_bridge.current_size);
/* aperture size */
pci_write_config_word(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
/* paccfg/nbxcfg */
pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
(temp2 & ~(1 << 10)) | (1 << 9));
/* clear any possible error conditions */
pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
return 0;
}
/**
* Configure -- Intel i815.
*
* Similar to intel_configure()
*/
static int intel_815_configure(void)
{
u32 temp, addr;
u8 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
/* the Intel 815 chipset spec. says that bits 29-31 in the
* ATTBASE register are reserved -> try not to write them */
if (agp_bridge.gatt_bus_addr & INTEL_815_ATTBASE_MASK)
panic("gatt bus addr too high");
pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr);
addr &= INTEL_815_ATTBASE_MASK;
addr |= agp_bridge.gatt_bus_addr;
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* apcont */
pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2);
pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, temp2 | (1 << 1));
/* clear any possible error conditions */
/* Oddness : this chipset seems to have no ERRSTS register ! */
return 0;
}
/** No-op. */
static void intel_820_tlbflush(agp_memory * mem)
{
return;
}
/**
* Backend cleanup -- Intel i8xx.
*
* Similar to as intel_cleanup().
*/
static void intel_820_cleanup(void)
{
u8 temp;
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge.previous_size);
pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp);
pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR,
temp & ~(1 << 1));
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
previous_size->size_value);
}
/**
* Configure -- Intel i820.
*
* Similar to intel_configure()
*/
static int intel_820_configure(void)
{
u32 temp;
u8 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* global enable aperture access */
/* This flag is not accessed through MCHCFG register as in */
/* i850 chipset. */
pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2);
pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR,
temp2 | (1 << 1));
/* clear any possible AGP-related error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c);
return 0;
}
/**
* Configure -- Intel i840.
*
* Similar to intel_configure()
*/
static int intel_840_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* mcgcfg */
pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2);
pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG,
temp2 | (1 << 9));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000);
return 0;
}
/**
* Configure -- Intel i845.
*
* Similar to intel_configure()
*/
static int intel_845_configure(void)
{
u32 temp;
u8 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* agpm */
pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2);
pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM,
temp2 | (1 << 1));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c);
return 0;
}
/** Calls intel_845_configure() */
static void intel_845_resume(void)
{
intel_845_configure();
}
/**
* Configure -- Intel i850.
*
* Similar to intel_configure()
*/
static int intel_850_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* mcgcfg */
pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2);
pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG,
temp2 | (1 << 9));
/* clear any possible AGP-related error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c);
return 0;
}
/**
* Configure -- Intel i860.
*
* Similar to intel_configure()
*/
static int intel_860_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* mcgcfg */
pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2);
pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG,
temp2 | (1 << 9));
/* clear any possible AGP-related error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700);
return 0;
}
/**
* Configure -- Intel i830mp.
*
* Similar to intel_configure()
*/
static int intel_830mp_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge.current_size);
/* aperture size */
pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
agp_bridge.gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
/* gmch */
pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
temp2 | (1 << 9));
/* clear any possible AGP-related error conditions */
pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c);
return 0;
}
/**
* Masks against the first mask in agp_bridge_data::masks.
*/
static unsigned long intel_mask_memory(unsigned long addr, int type)
{
/* Memory type is ignored */
return addr | agp_bridge.masks[0].mask;
}
/** Calls intel_configure() */
static void intel_resume(void)
{
intel_configure();
}
/** Setup function */
static struct gatt_mask intel_generic_masks[] =
{
{mask: 0x00000017, type: 0}
};
/** Aperture sizes -- Intel i815 */
static struct aper_size_info_8 intel_815_sizes[2] =
{
{64, 16384, 4, 0},
{32, 8192, 3, 8},
};
/** Aperture sizes -- Intel i8xx */
static struct aper_size_info_8 intel_8xx_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
{64, 16384, 4, 48},
{32, 8192, 3, 56},
{16, 4096, 2, 60},
{8, 2048, 1, 62},
{4, 1024, 0, 63}
};
/** Aperture sizes -- Intel generic */
static struct aper_size_info_16 intel_generic_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
{64, 16384, 4, 48},
{32, 8192, 3, 56},
{16, 4096, 2, 60},
{8, 2048, 1, 62},
{4, 1024, 0, 63}
};
/** Aperture sizes -- Intel i830mp */
static struct aper_size_info_8 intel_830mp_sizes[4] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
{64, 16384, 4, 48},
{32, 8192, 3, 56}
};
/**
* Setup -- Intel generic.
*
* \param pdev not referenced.
* \return always zero.
*
* Initializes the device dependent part agp_bride_data structure in agp_bride,
* using a mixture of the functions above and the generic driver functions in
* agp.c for the driver callbacks.
*/
int __init intel_generic_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
agp_bridge.size_type = U16_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_configure;
agp_bridge.fetch_size = intel_fetch_size;
agp_bridge.cleanup = intel_cleanup;
agp_bridge.tlb_flush = intel_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = intel_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i815.
*
* Similar to intel_generic_setup().
*/
int __init intel_815_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_815_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 2;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_815_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
}
/**
* Setup -- Intel i820.
*
* Similar to intel_generic_setup().
*/
int __init intel_820_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_820_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_820_cleanup;
agp_bridge.tlb_flush = intel_820_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i830mp.
*
* Similar to intel_generic_setup().
*/
int __init intel_830mp_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_830mp_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 4;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_830mp_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i840.
*
* Similar to intel_generic_setup().
*/
int __init intel_840_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_840_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i845.
*
* Similar to intel_generic_setup().
*/
int __init intel_845_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_845_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = intel_845_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i850.
*
* Similar to intel_generic_setup().
*/
int __init intel_850_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_850_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}
/**
* Setup -- Intel i860.
*
* Similar to intel_generic_setup().
*/
int __init intel_860_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = intel_860_configure;
agp_bridge.fetch_size = intel_8xx_fetch_size;
agp_bridge.cleanup = intel_8xx_cleanup;
agp_bridge.tlb_flush = intel_8xx_tlbflush;
agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_enable;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
(void) pdev; /* unused */
}

View File

@@ -0,0 +1 @@
This directory not really of interest to anybody... Feel free to ignore.

File diff suppressed because it is too large Load Diff

View File

@@ -136,6 +136,7 @@
#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33
#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
@@ -143,6 +144,7 @@
#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060
#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178
#define PCI_DEVICE_ID_COMPAQ_CISSC 0x0046
#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
@@ -172,6 +174,8 @@
#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623
#define PCI_DEVICE_ID_LSI_FC919 0x0624
#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625
#define PCI_DEVICE_ID_LSI_FC929X 0x0626
#define PCI_DEVICE_ID_LSI_FC919X 0x0628
#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
#define PCI_DEVICE_ID_LSI_61C102 0x0901
#define PCI_DEVICE_ID_LSI_63C815 0x1000
@@ -254,12 +258,9 @@
#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446
#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C
#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452
/* Radeon M4 */
/* Rage M4 */
#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45
#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46
/* Radeon NV-100 */
#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159
#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a
/* Radeon R100 */
#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144
#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145
@@ -274,6 +275,8 @@
#define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f
#define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c
#define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242
/* Radeon R200 (9100) */
#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d
/* Radeon RV200 (7500) */
#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157
#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158
@@ -282,11 +285,22 @@
#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965
#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966
#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967
/* Radeon RV280 (9200) */
#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960
/* Radeon R300 (9700) */
#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44
#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45
#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145
#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146
/* Radeon R300 (9500) */
#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144
/* Radeon R350 (9800) */
#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48
#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49
/* Radeon RV350 (9600) */
#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150
#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152
#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46
#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47
/* Radeon M6 */
#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59
#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a
@@ -294,11 +308,14 @@
#define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57
#define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58
/* Radeon M9 */
#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4964
#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4965
#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4966
#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4967
#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4c64
#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4c65
#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66
#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67
/* Radeon P/M */
#define PCI_DEVICE_ID_ATI_RADEON_LR 0x4c52
/* RadeonIGP */
#define PCI_DEVICE_ID_ATI_RADEON_IGP 0xCAB0
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
@@ -322,6 +339,12 @@
#define PCI_DEVICE_ID_NS_87560_USB 0x0012
#define PCI_DEVICE_ID_NS_83815 0x0020
#define PCI_DEVICE_ID_NS_83820 0x0022
#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500
#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501
#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502
#define PCI_DEVICE_ID_NS_SCx200_AUDIO 0x0503
#define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504
#define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505
#define PCI_DEVICE_ID_NS_87410 0xd001
#define PCI_VENDOR_ID_TSENG 0x100c
@@ -381,9 +404,10 @@
#define PCI_DEVICE_ID_IBM_MPIC 0x0046
#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096
#define PCI_DEVICE_ID_IBM_CPC700 0x00f9
#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc
#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105
#define PCI_DEVICE_ID_IBM_405GP 0x0156
#define PCI_DEVICE_ID_IBM_405GP 0x0156
#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd
#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
@@ -406,7 +430,7 @@
#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006
#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007
#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C
#define PCI_DEVIDE_ID_AMD_FE_GATE_700D 0x700D
#define PCI_DEVICE_ID_AMD_FE_GATE_700D 0x700D
#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E
#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F
#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400
@@ -421,13 +445,20 @@
#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411
#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413
#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414
#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440
#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441
#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443
#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448
#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449
#define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440
# define PCI_DEVICE_ID_AMD_VIPER_7440 PCI_DEVICE_ID_AMD_OPUS_7440
#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441
# define PCI_DEVICE_ID_AMD_VIPER_7441 PCI_DEVICE_ID_AMD_OPUS_7441
#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443
# define PCI_DEVICE_ID_AMD_VIPER_7443 PCI_DEVICE_ID_AMD_OPUS_7443
#define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448
# define PCI_DEVICE_ID_AMD_VIPER_7448 PCI_DEVICE_ID_AMD_OPUS_7448
#define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449
# define PCI_DEVICE_ID_AMD_VIPER_7449 PCI_DEVICE_ID_AMD_OPUS_7449
#define PCI_DEVICE_ID_AMD_8111_LAN 0x7462
#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469
#define PCI_DEVICE_ID_AMD_8111_AC97 0x746d
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
@@ -511,20 +542,28 @@
#define PCI_DEVICE_ID_SI_635 0x0635
#define PCI_DEVICE_ID_SI_640 0x0640
#define PCI_DEVICE_ID_SI_645 0x0645
#define PCI_DEVICE_ID_SI_646 0x0646
#define PCI_DEVICE_ID_SI_646 0x0646
#define PCI_DEVICE_ID_SI_648 0x0648
#define PCI_DEVICE_ID_SI_650 0x0650
#define PCI_DEVICE_ID_SI_651 0x0651
#define PCI_DEVICE_ID_SI_652 0x0652
#define PCI_DEVICE_ID_SI_730 0x0730
#define PCI_DEVICE_ID_SI_630_VGA 0x6300
#define PCI_DEVICE_ID_SI_730_VGA 0x7300
#define PCI_DEVICE_ID_SI_735 0x0735
#define PCI_DEVICE_ID_SI_740 0x0740
#define PCI_DEVICE_ID_SI_745 0x0745
#define PCI_DEVICE_ID_SI_746 0x0746
#define PCI_DEVICE_ID_SI_748 0x0748
#define PCI_DEVICE_ID_SI_750 0x0750
#define PCI_DEVICE_ID_SI_751 0x0751
#define PCI_DEVICE_ID_SI_752 0x0752
#define PCI_DEVICE_ID_SI_900 0x0900
#define PCI_DEVICE_ID_SI_5107 0x5107
#define PCI_DEVICE_ID_SI_5300 0x5300
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5518 0x5518
#define PCI_DEVICE_ID_SI_5571 0x5571
#define PCI_DEVICE_ID_SI_5591 0x5591
#define PCI_DEVICE_ID_SI_5597 0x5597
@@ -609,6 +648,7 @@
#define PCI_DEVICE_ID_TI_4410 0xac41
#define PCI_DEVICE_ID_TI_4451 0xac42
#define PCI_DEVICE_ID_TI_1420 0xac51
#define PCI_DEVICE_ID_TI_1510 0xac56
#define PCI_VENDOR_ID_SONY 0x104d
#define PCI_DEVICE_ID_SONY_CXD3222 0x8039
@@ -702,6 +742,10 @@
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d
#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034
#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e
#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
#define PCI_VENDOR_ID_YAMAHA 0x1073
#define PCI_DEVICE_ID_YAMAHA_724 0x0004
@@ -774,7 +818,9 @@
#define PCI_DEVICE_ID_CMD_648 0x0648
#define PCI_DEVICE_ID_CMD_649 0x0649
#define PCI_DEVICE_ID_CMD_670 0x0670
#define PCI_DEVICE_ID_CMD_680 0x0680
#define PCI_DEVICE_ID_SII_680 0x0680
#define PCI_DEVICE_ID_SII_3112 0x3112
#define PCI_VENDOR_ID_VISION 0x1098
#define PCI_DEVICE_ID_VISION_QD8500 0x0001
@@ -835,6 +881,14 @@
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_DEVICE_ID_3COM_3CR990 0x9900
#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902
#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903
#define PCI_DEVICE_ID_3COM_3CR990B 0x9904
#define PCI_DEVICE_ID_3COM_3CR990_FX 0x9905
#define PCI_DEVICE_ID_3COM_3CR990SVR95 0x9908
#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909
#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a
#define PCI_VENDOR_ID_SMC 0x10b8
#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
@@ -900,29 +954,46 @@
#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028
#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029
#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C
#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D
#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO 0x0112
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153
#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028
#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029
#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C
#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D
#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO 0x0112
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460 0x0170
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440 0x0171
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420 0x0172
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO 0x0174
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO 0x0175
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32 0x0176
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL 0x0178
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64 0x0179
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_200 0x017A
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C
#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600 0x0250
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400 0x0251
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200 0x0253
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
@@ -1020,6 +1091,10 @@
#define PCI_DEVICE_ID_VIA_8233C_0 0x3109
#define PCI_DEVICE_ID_VIA_8361 0x3112
#define PCI_DEVICE_ID_VIA_8233A 0x3147
#define PCI_DEVICE_ID_VIA_P4X333 0x3168
#define PCI_DEVICE_ID_VIA_8235 0x3177
#define PCI_DEVICE_ID_VIA_8377_0 0x3189
#define PCI_DEVICE_ID_VIA_8377_0 0x3189
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_8231 0x8231
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
@@ -1117,6 +1192,7 @@
#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000
#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300
#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320
#define PCI_VENDOR_ID_VMIC 0x114a
#define PCI_DEVICE_ID_VMIC_VME 0x7587
@@ -1158,6 +1234,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
@@ -1578,6 +1655,9 @@
#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d
#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
#define PCI_VENDOR_ID_SYBA 0x1592
#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
@@ -1590,7 +1670,7 @@
#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0
#define PCI_VENDOR_ID_PDC 0x15e9
#define PCI_DEVICE_ID_PDC_1841 0x1841
#define PCI_DEVICE_ID_PDC_ADMA100 0x1841
#define PCI_VENDOR_ID_ALTIMA 0x173b
#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8
@@ -1602,6 +1682,9 @@
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
#define PCI_VENDOR_ID_HINT 0x3388
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
#define PCI_VENDOR_ID_3DLABS 0x3d3d
#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
@@ -1663,7 +1746,11 @@
#define PCI_DEVICE_ID_INTEL_82430 0x0486
#define PCI_DEVICE_ID_INTEL_82434 0x04a3
#define PCI_DEVICE_ID_INTEL_I960 0x0960
#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
#define PCI_DEVICE_ID_INTEL_82562ET 0x1031
#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
@@ -1719,9 +1806,9 @@
#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452
#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453
#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459
#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b
#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d
#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e
#define PCI_DEVICE_ID_INTEL_82801E_11 0x245B
#define PCI_DEVICE_ID_INTEL_82801E_14 0x245D
#define PCI_DEVICE_ID_INTEL_82801E_15 0x245E
#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
@@ -1741,6 +1828,16 @@
#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7
#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb
#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd
#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0
#define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2
#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3
#define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4
#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5
#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6
#define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7
#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca
#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db
#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd
#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120
#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121
@@ -1762,6 +1859,7 @@
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@
#define ATY_RADEON_CRT_ON 0x00000002
#define FBIO_RADEON_GET_MIRROR _IOR('@', 3, sizeof(__u32*))
#define FBIO_RADEON_SET_MIRROR _IOW('@', 4, sizeof(__u32*))
#define FBIO_RADEON_GET_MIRROR _IOR('@', 3, __u32)
#define FBIO_RADEON_SET_MIRROR _IOW('@', 4, __u32)
#endif

View File

@@ -0,0 +1,125 @@
# $Id: Makefile,v 1.1.2.2 2003/04/26 21:17:43 keithw Exp $
# Mesa 3-D graphics library
# Version: 5.0
# Copyright (C) 1995-2002 Brian Paul
MESA = ../../..
default: mga_dri.so
include $(MESA)/Makefile.include
SHARED_INCLUDES= -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -Iserver
MINIGLX_INCLUDES = -I$(MESABUILDDIR)/miniglx
DRI_INCLUDES = -I$(MESABUILDDIR)/dri
ifeq ($(FULL_DRIVER),true)
DEFINES = \
-D_HAVE_SWRAST=1 \
-D_HAVE_SWTNL=1 \
-D_HAVE_SANITY=1 \
-D_HAVE_CODEGEN=1 \
-D_HAVE_LIGHTING=1 \
-D_HAVE_TEXGEN=1 \
-D_HAVE_USERCLIP=1 \
-D_HAVE_FULL_GL=1
else
DEFINES = \
-D_HAVE_SWRAST=0 \
-D_HAVE_SWTNL=0 \
-D_HAVE_SANITY=0 \
-D_HAVE_CODEGEN=0 \
-D_HAVE_LIGHTING=0 \
-D_HAVE_TEXGEN=0 \
-D_HAVE_USERCLIP=0 \
-D_HAVE_FULL_GL=0
endif
# The .a files for each mesa module required by this driver:
#
FULL_MESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \
$(MESABUILDDIR)/tnl/tnl.a \
$(MESABUILDDIR)/math/math.a \
$(MESABUILDDIR)/array_cache/array_cache.a \
$(MESABUILDDIR)/swrast/swrast.a \
$(MESABUILDDIR)/mesa.a \
$(MESABUILDDIR)/math/math.a #kludge
SUBSET_MESA = $(MESABUILDDIR)/mesa.a \
$(MESABUILDDIR)/math/math.a
MINIGLX_SOURCES = server/mga_dri.c
DRIVER_SOURCES = mgabuffers.c \
mgadd.c \
mgaioctl.c \
mgarender.c \
mgastate.c \
mgatris.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 = \
mgapixel.c \
mgaspan.c \
mgatex.c \
mgatexcnv.c \
mgatexmem.c \
mgavb.c \
mga_xmesa.c
INCLUDES = $(MINIGLX_INCLUDES) \
$(SHARED_INCLUDES)
ifeq ($(FULL_DRIVER),true)
C_SOURCES = $(MINIGLX_SOURCES) \
$(FULL_DRIVER_SOURCES) \
$(DRIVER_SOURCES)
MESA_MODULES = $(FULL_MESA)
else
C_SOURCES = $(MINIGLX_SOURCES) \
$(SUBSET_DRIVER_SOURCES) \
$(DRIVER_SOURCES)
MESA_MODULES = $(SUBSET_MESA)
endif
ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=$(MESABUILDDIR)/dri/dri.a
WINLIB=
else
WINOBJ=
WINLIB=-L$(MESA)/src/miniglx
endif
ASM_SOURCES =
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)
##### TARGETS #####
# Build the subset or full driver?
#
mga_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lGL -lc -lm
rm -f $(MESA)/lib/mga_dri.so && \
install mga_dri.so $(MESA)/lib/mga_dri.so
##### DEPENDENCIES #####
-include $(C_SOURCES:.c=.d)

View File

@@ -0,0 +1,26 @@
MGA DRI driver ported from XF86DRI to FBDRI
by Denis Oliver Kropp <dok@directfb.org>
INFO
This driver has been ported from the head branch of XFree86 to
the embedded-1-branch of Mesa.
STATUS
Already working very well as far as I've tested it (16/32 bit).
glxgears runs at 935 fps (G550 32MB AGP 4x, Athlon 1.33) vs 744 fps with XFree.
Other demos (terrain, fire, etc.) have been successfully tested as well.
TODO
- mgaEngineShutdown
- mgaEngineRestore
- SGRAM detection
- remove some unused bits from server/*
- subset driver support
- mgaWaitForVBlank
- deinitialization (from MGADRICloseScreen) a la radeonDestroyScreen

View File

@@ -0,0 +1,616 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include <stdio.h>
#include "mga_common.h"
#include "mga_xmesa.h"
#include "context.h"
#include "matrix.h"
#include "mmath.h"
#include "simple_list.h"
//#include "mem.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "array_cache/acache.h"
#include "tnl/t_pipeline.h"
#include "mgadd.h"
#include "mgastate.h"
#include "mgatex.h"
#include "mgaspan.h"
#include "mgaioctl.h"
#include "mgatris.h"
#include "mgavb.h"
#include "mgabuffers.h"
#include "mgapixel.h"
#include "mga_xmesa.h"
#include "mga_dri.h"
#ifndef MGA_DEBUG
int MGA_DEBUG = (0
/* | DEBUG_ALWAYS_SYNC */
/* | DEBUG_VERBOSE_MSG */
/* | DEBUG_VERBOSE_LRU */
/* | DEBUG_VERBOSE_DRI */
/* | DEBUG_VERBOSE_IOCTL */
/* | DEBUG_VERBOSE_2D */
/* | DEBUG_VERBOSE_FALLBACK */
);
#endif
static GLboolean
mgaInitDriver(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen;
MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaInitDriver\n");
/* Check that the DRM driver version is compatible */
if (sPriv->drmMajor != 3 ||
sPriv->drmMinor < 0) {
__driUtilMessage("MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
return GL_FALSE;
}
/* Allocate the private area */
mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
if (!mgaScreen) {
__driUtilMessage("Couldn't malloc screen struct");
return GL_FALSE;
}
mgaScreen->sPriv = sPriv;
sPriv->private = (void *)mgaScreen;
if (sPriv->drmMinor >= 1) {
int ret;
drmMGAGetParam gp;
gp.param = MGA_PARAM_IRQ_NR;
gp.value = (int *) &mgaScreen->irq;
ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
XFree(mgaScreen);
sPriv->private = NULL;
return GL_FALSE;
}
}
if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
serverInfo->chipset != MGA_CARD_TYPE_G400) {
XFree(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Unrecognized chipset");
return GL_FALSE;
}
mgaScreen->chipset = serverInfo->chipset;
mgaScreen->width = serverInfo->width;
mgaScreen->height = serverInfo->height;
mgaScreen->mem = serverInfo->mem;
mgaScreen->cpp = serverInfo->cpp;
mgaScreen->agpMode = serverInfo->agpMode;
mgaScreen->frontPitch = serverInfo->frontPitch;
mgaScreen->frontOffset = serverInfo->frontOffset;
mgaScreen->backOffset = serverInfo->backOffset;
mgaScreen->backPitch = serverInfo->backPitch;
mgaScreen->depthOffset = serverInfo->depthOffset;
mgaScreen->depthPitch = serverInfo->depthPitch;
mgaScreen->mmio.handle = serverInfo->registers.handle;
mgaScreen->mmio.size = serverInfo->registers.size;
if ( drmMap( sPriv->fd,
mgaScreen->mmio.handle, mgaScreen->mmio.size,
&mgaScreen->mmio.map ) < 0 ) {
FREE( mgaScreen );
sPriv->private = NULL;
__driUtilMessage( "Couldn't map MMIO registers" );
return GL_FALSE;
}
mgaScreen->primary.handle = serverInfo->primary.handle;
mgaScreen->primary.size = serverInfo->primary.size;
mgaScreen->buffers.handle = serverInfo->buffers.handle;
mgaScreen->buffers.size = serverInfo->buffers.size;
#if 0
mgaScreen->agp.handle = serverInfo->agp;
mgaScreen->agp.size = serverInfo->agpSize;
if (drmMap(sPriv->fd,
mgaScreen->agp.handle,
mgaScreen->agp.size,
(drmAddress *)&mgaScreen->agp.map) != 0)
{
Xfree(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map agp region");
return GL_FALSE;
}
#endif
mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
PDEA_pagpxfer_enable | 1);
mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
serverInfo->logTextureGranularity;
mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
serverInfo->logAgpTextureGranularity;
mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB +
serverInfo->textureOffset);
if (drmMap(sPriv->fd,
serverInfo->agpTextureOffset,
serverInfo->agpTextureSize,
(drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0)
{
free(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map agptexture region");
return GL_FALSE;
}
#if 0
mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
serverInfo->agpTextureOffset);
#endif
mgaScreen->mAccess = serverInfo->mAccess;
/* For calculating setupdma addresses.
*/
mgaScreen->dmaOffset = serverInfo->buffers.handle;
mgaScreen->bufs = drmMapBufs(sPriv->fd);
if (!mgaScreen->bufs) {
/*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
XFree(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map dma buffers");
return GL_FALSE;
}
mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
return GL_TRUE;
}
static void
mgaDestroyScreen(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaDestroyScreen\n");
/*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
free(mgaScreen);
sPriv->private = NULL;
}
extern const struct gl_pipeline_stage _mga_render_stage;
static const struct gl_pipeline_stage *mga_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
/* REMOVE: point attenuation stage */
#if 0
&_mga_render_stage, /* ADD: unclipped rastersetup-to-dma */
/* Need new ioctl for wacceptseq */
#endif
&_tnl_render_stage,
0,
};
static GLboolean
mgaCreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate )
{
int i;
GLcontext *ctx, *shareCtx;
mgaContextPtr mmesa;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+
mgaScreen->sarea_priv_offset);
if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaCreateContext\n");
/* allocate mga context */
mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
if (!mmesa) {
return GL_FALSE;
}
/* Allocate the Mesa context */
if (sharedContextPrivate)
shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
else
shareCtx = NULL;
mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, mmesa, GL_TRUE);
if (!mmesa->glCtx) {
FREE(mmesa);
return GL_FALSE;
}
driContextPriv->driverPrivate = mmesa;
/* Init mga state */
mmesa->hHWContext = driContextPriv->hHWContext;
mmesa->driFd = sPriv->fd;
mmesa->driHwLock = &sPriv->pSAREA->lock;
mmesa->mgaScreen = mgaScreen;
mmesa->driScreen = sPriv;
mmesa->sarea = (void *)saPriv;
mmesa->glBuffer = NULL;
make_empty_list(&mmesa->SwappedOut);
mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;
for (i = 0 ; i < mmesa->lastTexHeap ; i++) {
mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]);
make_empty_list(&mmesa->TexObjList[i]);
}
/* Set the maximum texture size small enough that we can guarentee
* that both texture units can bind a maximal texture and have them
* on the card at once.
*/
ctx = mmesa->glCtx;
{
int nr = 2;
if (mgaScreen->chipset == MGA_CARD_TYPE_G200)
nr = 1;
if (mgaScreen->textureSize[0] < nr*1024*1024) {
ctx->Const.MaxTextureLevels = 9;
} else if (mgaScreen->textureSize[0] < nr*4*1024*1024) {
ctx->Const.MaxTextureLevels = 10;
} else {
ctx->Const.MaxTextureLevels = 11;
}
ctx->Const.MaxTextureUnits = nr;
}
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 10.0;
ctx->Const.MaxLineWidthAA = 10.0;
ctx->Const.LineWidthGranularity = 1.0;
mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
switch (mesaVis->depthBits) {
case 16:
mmesa->depth_scale = 1.0/(GLdouble)0xffff;
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffff;
break;
case 24:
mmesa->depth_scale = 1.0/(GLdouble)0xffffff;
if (mmesa->hw_stencil) {
mmesa->depth_clear_mask = 0xffffff00;
mmesa->stencil_clear_mask = 0x000000ff;
} else
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffffff00;
break;
case 32:
mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffffffff;
break;
};
mmesa->haveHwStipple = GL_FALSE;
mmesa->RenderIndex = -1; /* impossible value */
mmesa->new_state = ~0;
mmesa->dirty = ~0;
mmesa->vertex_format = 0;
mmesa->CurrentTexObj[0] = 0;
mmesa->CurrentTexObj[1] = 0;
mmesa->tmu_source[0] = 0;
mmesa->tmu_source[1] = 1;
mmesa->texAge[0] = 0;
mmesa->texAge[1] = 0;
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
/* Install the customized pipeline:
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, mga_pipeline );
/* Configure swrast to match hardware characteristics:
*/
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
mmesa->primary_offset = mmesa->mgaScreen->primary.handle;
ctx->DriverCtx = (void *) mmesa;
mmesa->glCtx = ctx;
mgaDDExtensionsInit( ctx );
mgaDDInitStateFuncs( ctx );
mgaDDInitTextureFuncs( ctx );
mgaDDInitSpanFuncs( ctx );
mgaDDInitDriverFuncs( ctx );
mgaDDInitIoctlFuncs( ctx );
mgaDDInitPixelFuncs( ctx );
mgaDDInitTriFuncs( ctx );
mgaInitVB( ctx );
mgaInitState( mmesa );
driContextPriv->driverPrivate = (void *) mmesa;
return GL_TRUE;
}
static void
mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
{
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaDestroyContext\n");
assert(mmesa); /* should never be null */
if (mmesa) {
_swsetup_DestroyContext( mmesa->glCtx );
_tnl_DestroyContext( mmesa->glCtx );
_ac_DestroyContext( mmesa->glCtx );
_swrast_DestroyContext( mmesa->glCtx );
mgaFreeVB( mmesa->glCtx );
/* free the Mesa context */
mmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(mmesa->glCtx);
/* free the mga context */
FREE(mmesa);
}
}
static GLboolean
mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24);
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE, /* software depth buffer? */
swStencil,
mesaVis->accumRedBits > 0,
mesaVis->alphaBits > 0 );
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}
static GLboolean
mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
{
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (mmesa)
mmesa->dirty = ~0;
return GL_TRUE;
}
static GLboolean
mgaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static GLboolean
mgaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
/* This looks buggy to me - the 'b' variable isn't used anywhere...
* Hmm - It seems that the drawable is already hooked in to
* driDrawablePriv.
*
* But why are we doing context initialization here???
*/
static GLboolean
mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
fprintf(stderr, "%s\n", __FUNCTION__);
if (driContextPriv) {
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (mmesa->driDrawable != driDrawPriv) {
mmesa->driDrawable = driDrawPriv;
mmesa->dirty = ~0;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
}
_mesa_make_current2(mmesa->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
if (!mmesa->glCtx->Viewport.Width)
_mesa_set_viewport(mmesa->glCtx, 0, 0,
driDrawPriv->w, driDrawPriv->h);
}
else {
_mesa_make_current(NULL, NULL);
}
return GL_TRUE;
}
void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
MGASAREAPrivPtr sarea = mmesa->sarea;
int me = mmesa->hHWContext;
int i;
fprintf(stderr, "%s\n", __FUNCTION__);
drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
fprintf(stderr,
"mmesa->lastStamp %d dpriv->lastStamp %d *(dpriv->pStamp) %d\n",
mmesa->lastStamp,
dPriv->lastStamp,
*(dPriv->pStamp));
/* The window might have moved, so we might need to get new clip
* rects.
*
* NOTE: This releases and regrabs the hw lock to allow the X server
* to respond to the DRI protocol request for new drawable info.
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
if ( mmesa->lastStamp == 0 ||
mmesa->lastStamp != dPriv->lastStamp ) {
mmesa->lastStamp = dPriv->lastStamp;
mmesa->SetupNewInputs |= VERT_BIT_CLIP;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
}
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
if (sarea->ctxOwner != me) {
mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
sarea->ctxOwner=me;
}
for (i = 0 ; i < mmesa->lastTexHeap ; i++)
if (sarea->texAge[i] != mmesa->texAge[i])
mgaAgeTextures( mmesa, i );
sarea->last_quiescent = -1; /* just kill it for now */
}
static const struct __DriverAPIRec mgaAPI = {
mgaInitDriver,
mgaDestroyScreen,
mgaCreateContext,
mgaDestroyContext,
mgaCreateBuffer,
mgaDestroyBuffer,
mgaSwapBuffers,
mgaMakeCurrent,
mgaUnbindContext,
mgaOpenFullScreen,
mgaCloseFullScreen
};
/*
* This is the bootstrap function for the driver.
* The __driCreateScreen name is the symbol that libGL.so fetches.
* Return: pointer to a __DRIscreenPrivate.
*/
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &mgaAPI);
return (void *) psp;
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */
#ifndef _MGA_INIT_H_
#define _MGA_INIT_H_
#include <sys/time.h>
#include "dri_util.h"
#include "mtypes.h"
#include "mgaregs.h"
#include "mga_common.h"
typedef struct mga_screen_private_s {
int chipset;
int width;
int height;
int mem;
int cpp; /* for front and back buffers */
GLint agpMode;
unsigned int irq; /* IRQ number (0 means none) */
unsigned int mAccess;
unsigned int frontOffset;
unsigned int frontPitch;
unsigned int backOffset;
unsigned int backPitch;
unsigned int depthOffset;
unsigned int depthPitch;
int depthCpp;
unsigned int dmaOffset;
unsigned int textureOffset[DRM_MGA_NR_TEX_HEAPS];
unsigned int textureSize[DRM_MGA_NR_TEX_HEAPS];
int logTextureGranularity[DRM_MGA_NR_TEX_HEAPS];
char *texVirtual[DRM_MGA_NR_TEX_HEAPS];
__DRIscreenPrivate *sPriv;
drmBufMapPtr bufs;
drmRegion mmio;
drmRegion status;
drmRegion primary;
drmRegion buffers;
unsigned int sarea_priv_offset;
} mgaScreenPrivate;
#include "mgacontext.h"
extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags );
extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );
#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch
#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue
/* Lock the hardware and validate our state.
*/
#define LOCK_HARDWARE( mmesa ) \
do { \
char __ret=0; \
DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
(DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
if (__ret) \
mgaGetLock( mmesa, 0 ); \
} while (0)
/*
*/
#define LOCK_HARDWARE_QUIESCENT( mmesa ) do { \
LOCK_HARDWARE( mmesa ); \
UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); \
} while (0)
/* Unlock the hardware using the global current context
*/
#define UNLOCK_HARDWARE(mmesa) \
DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
/* Freshen our snapshot of the drawables
*/
#define REFRESH_DRAWABLE_INFO( mmesa ) \
do { \
LOCK_HARDWARE( mmesa ); \
mmesa->lastX = mmesa->drawX; \
mmesa->lastY = mmesa->drawY; \
UNLOCK_HARDWARE( mmesa ); \
} while (0)
#define GET_DRAWABLE_LOCK( mmesa ) while(0)
#define RELEASE_DRAWABLE_LOCK( mmesa ) while(0)
/* The 2D driver macros are busted -- we can't use them here as they
* rely on the 2D driver data structures rather than taking an explicit
* base address.
*/
#define MGA_BASE( reg ) ((unsigned long)(mmesa->mgaScreen->mmio.map))
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
#define MGA_DEREF( reg ) *(volatile __u32 *)MGA_ADDR( reg )
#define MGA_READ( reg ) MGA_DEREF( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
#endif

View File

@@ -0,0 +1,292 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */
#include <stdio.h>
#include "mgacontext.h"
#include "mgabuffers.h"
#include "mgastate.h"
#include "mgaioctl.h"
#include "mgatris.h"
static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
/* fprintf( stderr, "%s\n", __FUNCTION__ );*/
if (driDrawable->numClipRects == 0) {
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
mmesa->numClipRects = 1;
mmesa->pClipRects = &zeroareacliprect;
} else {
mmesa->numClipRects = driDrawable->numClipRects;
mmesa->pClipRects = driDrawable->pClipRects;
}
mmesa->drawX = driDrawable->x;
mmesa->drawY = driDrawable->y;
mmesa->setup.dstorg = mmesa->drawOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
}
static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
/* fprintf( stderr, "%s\n", __FUNCTION__ );*/
if (driDrawable->numBackClipRects == 0)
{
if (driDrawable->numClipRects == 0) {
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
mmesa->numClipRects = 1;
mmesa->pClipRects = &zeroareacliprect;
} else {
mmesa->numClipRects = driDrawable->numClipRects;
mmesa->pClipRects = driDrawable->pClipRects;
}
mmesa->drawX = driDrawable->x;
mmesa->drawY = driDrawable->y;
} else {
mmesa->numClipRects = driDrawable->numBackClipRects;
mmesa->pClipRects = driDrawable->pBackClipRects;
mmesa->drawX = driDrawable->backX;
mmesa->drawY = driDrawable->backY;
}
mmesa->setup.dstorg = mmesa->drawOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
}
#if 0
static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
__DRIscreenPrivate *driScreen = mmesa->driScreen;
MGASAREAPrivPtr sarea = mmesa->sarea;
int i = 0, top = 0;
if (sarea->exported_buffers & MGA_BACK) {
driDrawable->numBackClipRects = sarea->exported_nback;
driDrawable->pBackClipRects = mmesa->tmp_boxes[0];
top = sarea->exported_nback;
for (i = 0 ; i < top ; i++)
driDrawable->pBackClipRects[i] =
*(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
}
if (sarea->exported_buffers & MGA_FRONT)
{
int start = top;
driDrawable->numClipRects = sarea->exported_nfront;
driDrawable->pClipRects = mmesa->tmp_boxes[1];
top += sarea->exported_nfront;
for ( ; i < top ; i++)
driDrawable->pClipRects[i-start] =
*(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
}
driDrawable->index = sarea->exported_index;
driDrawable->lastStamp = sarea->exported_stamp;
driDrawable->x = sarea->exported_front_x;
driDrawable->y = sarea->exported_front_y;
driDrawable->backX = sarea->exported_back_x;
driDrawable->backY = sarea->exported_back_y;
driDrawable->w = sarea->exported_w;
driDrawable->h = sarea->exported_h;
driDrawable->pStamp =
&(driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers);
}
#endif
#if 0
static void printSareaRects( mgaContextPtr mmesa )
{
__DRIscreenPrivate *driScreen = mmesa->driScreen;
MGASAREAPrivPtr sarea = mmesa->sarea;
int i;
fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable);
fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index);
fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp);
fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x);
fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y);
fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x);
fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y);
fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w);
fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h);
fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers);
fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront);
fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback);
i = 0;
if (sarea->exported_buffers & MGA_BACK)
for ( ; i < sarea->exported_nback ; i++)
fprintf(stderr, "back %d: %d,%d-%d,%d\n", i,
sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
if (sarea->exported_buffers & MGA_FRONT) {
int start = i;
int top = i + sarea->exported_nfront;
for ( ; i < top ; i++)
fprintf(stderr, "front %d: %d,%d-%d,%d\n",
i - start,
sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
}
fprintf(stderr, "drawableTable[%d].stamp: %d\n",
sarea->exported_index,
driScreen->pSAREA->drawableTable[sarea->exported_index].stamp);
}
static void printMmesaRects( mgaContextPtr mmesa )
{
__DRIscreenPrivate *driScreen = mmesa->driScreen;
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
int nr = mmesa->numClipRects;
int i;
fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw);
fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index);
fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp);
fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX);
fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY);
fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w);
fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h);
for (i = 0 ; i < nr ; i++)
fprintf(stderr, "box %d: %d,%d-%d,%d\n", i,
mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1,
mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2);
fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer);
fprintf(stderr, "drawableTable[%d].stamp: %d\n",
driDrawable->index,
driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
}
#endif
void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
MGASAREAPrivPtr sarea = mmesa->sarea;
/* fprintf(stderr, "%s\n", __FUNCTION__);*/
DRI_VALIDATE_DRAWABLE_INFO(driScreen, driDrawable);
mmesa->dirty_cliprects = 0;
if (mmesa->draw_buffer == MGA_FRONT)
mgaXMesaSetFrontClipRects( mmesa );
else
mgaXMesaSetBackClipRects( mmesa );
#if 0
printMmesaRects(mmesa);
#endif
sarea->req_drawable = driDrawable->draw;
sarea->req_draw_buffer = mmesa->draw_buffer;
mgaUpdateClipping( mmesa->glCtx );
mgaCalcViewport( mmesa->glCtx );
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (mode == GL_FRONT_LEFT)
{
mmesa->readOffset = mmesa->mgaScreen->frontOffset;
mmesa->read_buffer = MGA_FRONT;
}
else
{
mmesa->readOffset = mmesa->mgaScreen->backOffset;
mmesa->read_buffer = MGA_BACK;
}
}
void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
FLUSH_BATCH( MGA_CONTEXT(ctx) );
/* fprintf( stderr, "%s %d\n", __FUNCTION__, mode);*/
/*
* _DrawDestMask is easier to cope with than <mode>.
*/
switch ( ctx->Color._DrawDestMask ) {
case FRONT_LEFT_BIT:
mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
mmesa->readOffset = mmesa->mgaScreen->frontOffset;
mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mmesa->draw_buffer = MGA_FRONT;
mgaXMesaSetFrontClipRects( mmesa );
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BACK_LEFT_BIT:
mmesa->drawOffset = mmesa->mgaScreen->backOffset;
mmesa->readOffset = mmesa->mgaScreen->backOffset;
mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
mmesa->draw_buffer = MGA_BACK;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mgaXMesaSetBackClipRects( mmesa );
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
break;
}
}

View File

@@ -0,0 +1,37 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.7 2002/10/30 12:51:35 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef MGA_BUFFERS_H
#define MGA_BUFFERS_H
void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode );
void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode );
void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers );
#endif

View File

@@ -0,0 +1,309 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef MGALIB_INC
#define MGALIB_INC
//#include <X11/Xlibint.h>
#include "dri_util.h"
#include "mtypes.h"
#include "xf86drm.h"
#include "mm.h"
//#include "mem.h"
#include "mga_sarea.h"
#define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask))
#define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK))
#define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT))
#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200)
#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400)
/* SoftwareFallback
* - texture env GL_BLEND -- can be fixed
* - 1D and 3D textures
* - incomplete textures
* - GL_DEPTH_FUNC == GL_NEVER not in h/w
*/
#define MGA_FALLBACK_TEXTURE 0x1
#define MGA_FALLBACK_DRAW_BUFFER 0x2
#define MGA_FALLBACK_READ_BUFFER 0x4
#define MGA_FALLBACK_LOGICOP 0x8
#define MGA_FALLBACK_RENDERMODE 0x10
#define MGA_FALLBACK_STENCIL 0x20
#define MGA_FALLBACK_DEPTH 0x40
/* For mgaCtx->new_state.
*/
#define MGA_NEW_DEPTH 0x1
#define MGA_NEW_ALPHA 0x2
#define MGA_NEW_CLIP 0x8
#define MGA_NEW_TEXTURE 0x20
#define MGA_NEW_CULL 0x40
#define MGA_NEW_WARP 0x80
#define MGA_NEW_STENCIL 0x100
#define MGA_NEW_CONTEXT 0x200
/* Use the templated vertex formats:
*/
#define TAG(x) mga##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
typedef struct mga_context_t mgaContext;
typedef struct mga_context_t *mgaContextPtr;
typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *,
mgaVertex * );
typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * );
typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * );
/* Reasons why the GL_BLEND fallback mightn't work:
*/
#define MGA_BLEND_ENV_COLOR 0x1
#define MGA_BLEND_MULTITEX 0x2
struct mga_texture_object_s;
struct mga_screen_private_s;
#define MGA_TEX_MAXLEVELS 5
typedef struct mga_texture_object_s
{
struct mga_texture_object_s *next;
struct mga_texture_object_s *prev;
struct gl_texture_object *tObj;
struct mga_context_t *ctx;
PMemBlock MemBlock;
GLuint offsets[MGA_TEX_MAXLEVELS];
int lastLevel;
GLuint dirty_images;
GLuint totalSize;
int texelBytes;
GLuint age;
int bound;
int heap; /* agp or card */
mga_texture_regs_t setup;
} mgaTextureObject_t;
struct mga_context_t {
GLcontext *glCtx;
unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp,
* need to shadow it here. */
/* Bookkeeping for texturing
*/
int lastTexHeap;
struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS];
struct mga_texture_object_s SwappedOut;
struct mga_texture_object_s *CurrentTexObj[2];
memHeap_t *texHeap[MGA_NR_TEX_HEAPS];
int c_texupload;
int c_texusage;
int tex_thrash;
/* Map GL texture units onto hardware.
*/
GLuint tmu_source[2];
GLboolean default32BitTextures;
/* Manage fallbacks
*/
GLuint Fallback;
/* Temporaries for translating away float colors:
*/
struct gl_client_array UbyteColor;
struct gl_client_array UbyteSecondaryColor;
/* Support for limited GL_BLEND fallback
*/
unsigned int blend_flags;
unsigned int envcolor;
/* Rasterization state
*/
GLuint SetupNewInputs;
GLuint SetupIndex;
GLuint RenderIndex;
GLuint hw_primitive;
GLenum raster_primitive;
GLenum render_primitive;
char *verts;
GLint vertex_stride_shift;
GLuint vertex_format;
GLuint vertex_size;
/* Fallback rasterization functions
*/
mga_point_func draw_point;
mga_line_func draw_line;
mga_tri_func draw_tri;
/* Manage driver and hardware state
*/
GLuint new_gl_state;
GLuint new_state;
GLuint dirty;
mga_context_regs_t setup;
GLuint ClearColor;
GLuint ClearDepth;
GLuint poly_stipple;
GLfloat depth_scale;
GLuint depth_clear_mask;
GLuint stencil_clear_mask;
GLuint hw_stencil;
GLuint haveHwStipple;
GLfloat hw_viewport[16];
/* Dma buffers
*/
drmBufPtr vertex_dma_buffer;
drmBufPtr iload_buffer;
/* VBI
*/
GLuint vbl_seq;
/* Drawable, cliprect and scissor information
*/
int dirty_cliprects; /* which sets of cliprects are uptodate? */
int draw_buffer; /* which buffer are we rendering to */
unsigned int drawOffset; /* draw buffer address in space */
int read_buffer;
int readOffset;
int drawX, drawY; /* origin of drawable in draw buffer */
int lastX, lastY; /* detect DSTORG bug */
GLuint numClipRects; /* cliprects for the draw buffer */
XF86DRIClipRectPtr pClipRects;
XF86DRIClipRectRec draw_rect;
XF86DRIClipRectRec scissor_rect;
int scissor;
XF86DRIClipRectRec tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS];
/* Texture aging and DMA based aging.
*/
unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */
unsigned int dirtyAge; /* buffer age for synchronization */
GLuint primary_offset;
/* Mirrors of some DRI state.
*/
GLframebuffer *glBuffer;
drmContext hHWContext;
drmLock *driHwLock;
int driFd;
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
struct mga_screen_private_s *mgaScreen;
MGASAREAPrivPtr sarea;
};
#define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx))
#define MGAPACKCOLOR555(r,g,b,a) \
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
((a) ? 0x8000 : 0))
#define MGAPACKCOLOR565(r,g,b) \
((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#define MGAPACKCOLOR88(l, a) \
(((l) << 8) | (a))
#define MGAPACKCOLOR888(r,g,b) \
(((r) << 16) | ((g) << 8) | (b))
#define MGAPACKCOLOR8888(r,g,b,a) \
(((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define MGAPACKCOLOR4444(r,g,b,a) \
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
#define MGA_DEBUG 0
#ifndef MGA_DEBUG
extern int MGA_DEBUG;
#endif
#define DEBUG_ALWAYS_SYNC 0x1
#define DEBUG_VERBOSE_MSG 0x2
#define DEBUG_VERBOSE_LRU 0x4
#define DEBUG_VERBOSE_DRI 0x8
#define DEBUG_VERBOSE_IOCTL 0x10
#define DEBUG_VERBOSE_2D 0x20
#define DEBUG_VERBOSE_FALLBACK 0x40
static __inline__ GLuint mgaPackColor(GLuint cpp,
GLubyte r, GLubyte g,
GLubyte b, GLubyte a)
{
switch (cpp) {
case 2:
return MGAPACKCOLOR565(r,g,b);
case 4:
return MGAPACKCOLOR8888(r,g,b,a);
default:
return 0;
}
}
/*
* Subpixel offsets for window coordinates:
*/
#define SUBPIXEL_X (-0.5F)
#define SUBPIXEL_Y (-0.5F + 0.125)
#define MGA_WA_TRIANGLES 0x18000000
#define MGA_WA_TRISTRIP_T0 0x02010200
#define MGA_WA_TRIFAN_T0 0x01000408
#define MGA_WA_TRISTRIP_T0T1 0x02010400
#define MGA_WA_TRIFAN_T0T1 0x01000810
#endif

View File

@@ -0,0 +1,171 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.14 2002/10/30 12:51:35 alanh Exp $ */
#include "mtypes.h"
#include <stdio.h>
#include <stdlib.h>
#include "mm.h"
#include "mgacontext.h"
#include "mgadd.h"
#include "mgastate.h"
#include "mgaspan.h"
#include "mgatex.h"
#include "mgatris.h"
#include "mgavb.h"
#include "mga_xmesa.h"
#include "extensions.h"
#if defined(USE_X86_ASM)
#include "X86/common_x86_asm.h"
#endif
#define MGA_DATE "20020221"
/***************************************
* Mesa's Driver Functions
***************************************/
static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
static char buffer[128];
switch ( name ) {
case GL_VENDOR:
return (GLubyte *) "VA Linux Systems Inc.";
case GL_RENDERER:
sprintf( buffer, "Mesa DRI %s " MGA_DATE,
MGA_IS_G400(mmesa) ? "G400" :
MGA_IS_G200(mmesa) ? "G200" : "MGA" );
/* Append any AGP-specific information.
*/
switch ( mmesa->mgaScreen->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 );
}
#endif
#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
return (GLubyte *)buffer;
default:
return NULL;
}
}
static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
/* Need to lock to make sure the driDrawable is uptodate. This
* information is used to resize Mesa's software buffers, so it has
* to be correct.
*/
LOCK_HARDWARE( mmesa );
*width = mmesa->driDrawable->w;
*height = mmesa->driDrawable->h;
UNLOCK_HARDWARE( mmesa );
}
void mgaDDExtensionsInit( GLcontext *ctx )
{
/* paletted_textures currently doesn't work, but we could fix them later */
/*
_mesa_enable_extension( ctx, "GL_EXT_shared_texture_palette" );
_mesa_enable_extension( ctx, "GL_EXT_paletted_texture" );
*/
_mesa_enable_extension( ctx, "GL_ARB_texture_compression" );
_mesa_enable_extension( ctx, "GL_ARB_multisample" );
_mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" );
/* Turn on multitexture and texenv_add for the G400.
*/
if (MGA_IS_G400(MGA_CONTEXT(ctx))) {
_mesa_enable_extension( ctx, "GL_ARB_multitexture" );
_mesa_enable_extension( ctx, "GL_ARB_texture_env_add" );
_mesa_enable_extension( ctx, "GL_EXT_texture_env_add" );
#if defined (MESA_packed_depth_stencil)
_mesa_enable_extension( ctx, "GL_MESA_packed_depth_stencil" );
#endif
#if defined (MESA_experimetal_agp_allocator)
if (!getenv("MGA_DISABLE_AGP_ALLOCATOR"))
_mesa_enable_extension( ctx, "GL_MESA_experimental_agp_allocator" );
#endif
}
}
void mgaDDInitDriverFuncs( GLcontext *ctx )
{
ctx->Driver.GetBufferSize = mgaBufferSize;
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
ctx->Driver.GetString = mgaDDGetString;
}

View File

@@ -0,0 +1,37 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef MGADD_INC
#define MGADD_INC
#include "context.h"
void mgaDDInitDriverFuncs( GLcontext *ctx );
void mgaDDExtensionsInit( GLcontext *ctx );
#endif

View File

@@ -0,0 +1,693 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
* Gareth Hughes <gareth@valinux.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.16 2002/12/16 16:18:52 dawes Exp $ */
#include <stdio.h>
#include <errno.h>
#include "mtypes.h"
#include "macros.h"
#include "dd.h"
#include "swrast/swrast.h"
#include "mm.h"
#include "mgacontext.h"
#include "mgadd.h"
#include "mgastate.h"
#include "mgatex.h"
#include "mgavb.h"
#include "mgaioctl.h"
#include "mgatris.h"
#include "mgabuffers.h"
#include "xf86drm.h"
#include "mga_common.h"
static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
unsigned long dest,
int length)
{
drmBufPtr buf = mmesa->iload_buffer;
drmMGAIload iload;
int ret, i;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",
buf->idx, (int) dest, length);
iload.idx = buf->idx;
iload.dstorg = dest;
iload.length = length;
i = 0;
do {
ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD,
&iload, sizeof(drmMGAIload) );
} while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
if ( ret < 0 ) {
printf("send iload retcode = %d\n", ret);
exit(1);
}
mmesa->iload_buffer = 0;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "finished iload dma put\n");
}
drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa )
{
int idx = 0;
int size = 0;
drmDMAReq dma;
int retcode;
drmBufPtr buf;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "Getting dma buffer\n");
dma.context = mmesa->hHWContext;
dma.send_count = 0;
dma.send_list = NULL;
dma.send_sizes = NULL;
dma.flags = 0;
dma.request_count = 1;
dma.request_size = MGA_BUFFER_SIZE;
dma.request_list = &idx;
dma.request_sizes = &size;
dma.granted_count = 0;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
dma.context, dma.request_count,
dma.request_size);
while (1) {
retcode = drmDMA(mmesa->driFd, &dma);
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
retcode,
dma.request_sizes[0],
dma.request_list[0],
dma.granted_count);
if (retcode == 0 &&
dma.request_sizes[0] &&
dma.granted_count)
break;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "\n\nflush");
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
}
buf = &(mmesa->mgaScreen->bufs->list[idx]);
buf->used = 0;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr,
"drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
"dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",
dma.request_sizes[0], dma.request_list[0],
buf->idx, buf->total,
buf->used, buf->address);
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "finished getbuffer\n");
return buf;
}
static void
mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
GLuint flags = 0;
GLuint clear_color = mmesa->ClearColor;
GLuint clear_depth = 0;
GLuint color_mask = 0;
GLuint depth_mask = 0;
int ret;
int i;
static int nrclears;
drmMGAClearRec clear;
FLUSH_BATCH( mmesa );
if ( mask & DD_FRONT_LEFT_BIT ) {
flags |= MGA_FRONT;
color_mask = mmesa->setup.plnwt;
mask &= ~DD_FRONT_LEFT_BIT;
}
if ( mask & DD_BACK_LEFT_BIT ) {
flags |= MGA_BACK;
color_mask = mmesa->setup.plnwt;
mask &= ~DD_BACK_LEFT_BIT;
}
if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) {
flags |= MGA_DEPTH;
clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask);
depth_mask |= mmesa->depth_clear_mask;
mask &= ~DD_DEPTH_BIT;
}
if ( (mask & DD_STENCIL_BIT) && mmesa->hw_stencil ) {
flags |= MGA_DEPTH;
clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask);
depth_mask |= mmesa->stencil_clear_mask;
mask &= ~DD_STENCIL_BIT;
}
if ( flags ) {
LOCK_HARDWARE( mmesa );
if ( mmesa->dirty_cliprects )
mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) );
/* flip top to bottom */
cy = dPriv->h-cy-ch;
cx += mmesa->drawX;
cy += mmesa->drawY;
if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
fprintf( stderr, "Clear, bufs %x nbox %d\n",
(int)flags, (int)mmesa->numClipRects );
for (i = 0 ; i < mmesa->numClipRects ; )
{
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
XF86DRIClipRectPtr box = mmesa->pClipRects;
XF86DRIClipRectPtr b = mmesa->sarea->boxes;
int n = 0;
if (!all) {
for ( ; i < nr ; i++) {
GLint x = box[i].x1;
GLint y = box[i].y1;
GLint w = box[i].x2 - x;
GLint h = box[i].y2 - y;
if (x < cx) w -= cx - x, x = cx;
if (y < cy) h -= cy - y, y = cy;
if (x + w > cx + cw) w = cx + cw - x;
if (y + h > cy + ch) h = cy + ch - y;
if (w <= 0) continue;
if (h <= 0) continue;
b->x1 = x;
b->y1 = y;
b->x2 = x + w;
b->y2 = y + h;
b++;
n++;
}
} else {
for ( ; i < nr ; i++) {
*b++ = *(XF86DRIClipRectPtr)&box[i];
n++;
}
}
if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
fprintf( stderr,
"DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
flags, clear_color, clear_depth, mmesa->sarea->nbox );
mmesa->sarea->nbox = n;
clear.flags = flags;
clear.clear_color = clear_color;
clear.clear_depth = clear_depth;
clear.color_mask = color_mask;
clear.depth_mask = depth_mask;
ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR,
&clear, sizeof(drmMGAClearRec));
if ( ret ) {
fprintf( stderr, "send clear retcode = %d\n", ret );
exit( 1 );
}
if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
fprintf( stderr, "finished clear %d\n", ++nrclears );
}
UNLOCK_HARDWARE( mmesa );
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT;
}
if (mask)
_swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
}
int nrswaps;
void mgaWaitForVBlank( mgaContextPtr mmesa )
{
#if 0
drmVBlank vbl;
int ret;
if ( !mmesa->mgaScreen->irq )
return;
if ( getenv("LIBGL_SYNC_REFRESH") ) {
/* Wait for until the next vertical blank */
vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 1;
} else if ( getenv("LIBGL_THROTTLE_REFRESH") ) {
/* Wait for at least one vertical blank since the last call */
vbl.request.type = DRM_VBLANK_ABSOLUTE;
vbl.request.sequence = mmesa->vbl_seq + 1;
} else {
return;
}
if ((ret = drmWaitVBlank( mmesa->driFd, &vbl ))) {
fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be"
" working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
" and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
exit(1);
}
mmesa->vbl_seq = vbl.reply.sequence;
#endif
}
/*
* Copy the back buffer to the front buffer.
*/
void mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
{
mgaContextPtr mmesa;
XF86DRIClipRectPtr pbox;
GLint nbox;
GLint ret, wait = 0;
GLint i;
GLuint last_frame, last_wrap;
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
FLUSH_BATCH( mmesa );
mgaWaitForVBlank( mmesa );
LOCK_HARDWARE( mmesa );
last_frame = mmesa->sarea->last_frame.head;
last_wrap = mmesa->sarea->last_frame.wrap;
/* FIXME: Add a timeout to this loop...
*/
while ( 1 ) {
if ( last_wrap < mmesa->sarea->last_wrap ||
( last_wrap == mmesa->sarea->last_wrap &&
last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -
mmesa->primary_offset) ) ) {
break;
}
if ( 0 ) {
wait++;
fprintf( stderr, " last: head=0x%06x wrap=%d\n",
last_frame, last_wrap );
fprintf( stderr, " head: head=0x%06lx wrap=%d\n",
(long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),
mmesa->sarea->last_wrap );
}
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
for ( i = 0 ; i < 1024 ; i++ ) {
/* Don't just hammer the register... */
}
}
if ( wait )
fprintf( stderr, "\n" );
/* Use the frontbuffer cliprects
*/
if (mmesa->dirty_cliprects & MGA_FRONT)
mgaUpdateRects( mmesa, MGA_FRONT );
pbox = dPriv->pClipRects;
nbox = dPriv->numClipRects;
for (i = 0 ; i < nbox ; )
{
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
XF86DRIClipRectPtr b = mmesa->sarea->boxes;
mmesa->sarea->nbox = nr - i;
for ( ; i < nr ; i++)
*b++ = pbox[i];
if (0)
fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");
ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
if ( ret ) {
printf("send swap retcode = %d\n", ret);
exit(1);
}
}
UNLOCK_HARDWARE( mmesa );
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
/* This is overkill
*/
void mgaDDFinish( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
FLUSH_BATCH( mmesa );
if (1/*mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue*/) {
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "mgaRegetLockQuiescent\n");
LOCK_HARDWARE( mmesa );
UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );
UNLOCK_HARDWARE( mmesa );
mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
}
}
void mgaWaitAgeLocked( mgaContextPtr mmesa, int age )
{
if (GET_DISPATCH_AGE(mmesa) < age) {
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
}
}
void mgaWaitAge( mgaContextPtr mmesa, int age )
{
if (GET_DISPATCH_AGE(mmesa) < age) {
LOCK_HARDWARE(mmesa);
if (GET_DISPATCH_AGE(mmesa) < age) {
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
}
UNLOCK_HARDWARE(mmesa);
}
}
static int intersect_rect( XF86DRIClipRectPtr out,
XF86DRIClipRectPtr a,
XF86DRIClipRectPtr b )
{
*out = *a;
if (b->x1 > out->x1) out->x1 = b->x1;
if (b->y1 > out->y1) out->y1 = b->y1;
if (b->x2 < out->x2) out->x2 = b->x2;
if (b->y2 < out->y2) out->y2 = b->y2;
if (out->x1 > out->x2) return 0;
if (out->y1 > out->y2) return 0;
return 1;
}
static void age_mmesa( mgaContextPtr mmesa, int age )
{
if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;
if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;
}
#ifdef __i386__
static int __break_vertex = 0;
#endif
void mgaFlushVerticesLocked( mgaContextPtr mmesa )
{
XF86DRIClipRectPtr pbox = mmesa->pClipRects;
int nbox = mmesa->numClipRects;
drmBufPtr buffer = mmesa->vertex_dma_buffer;
drmMGAVertex vertex;
int i;
mmesa->vertex_dma_buffer = 0;
if (!buffer)
return;
if (mmesa->dirty_cliprects & mmesa->draw_buffer)
mgaUpdateRects( mmesa, mmesa->draw_buffer );
if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
mgaEmitHwStateLocked( mmesa );
/* FIXME: Workaround bug in kernel module.
*/
mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
if (!nbox)
buffer->used = 0;
if (nbox >= MGA_NR_SAREA_CLIPRECTS)
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
#if 0
if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
{
if (nbox == 1)
mmesa->sarea->nbox = 0;
else
mmesa->sarea->nbox = nbox;
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);
vertex.idx = buffer->idx;
vertex.used = buffer->used;
vertex.discard = 1;
drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,
&vertex, sizeof(drmMGAVertex) );
age_mmesa(mmesa, mmesa->sarea->last_enqueue);
}
else
#endif
{
for (i = 0 ; i < nbox ; )
{
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
XF86DRIClipRectPtr b = mmesa->sarea->boxes;
int discard = 0;
if (mmesa->scissor) {
mmesa->sarea->nbox = 0;
for ( ; i < nr ; i++) {
*b = pbox[i];
if (intersect_rect(b, b, &mmesa->scissor_rect)) {
mmesa->sarea->nbox++;
b++;
}
}
/* Culled?
*/
if (!mmesa->sarea->nbox) {
if (nr < nbox) continue;
buffer->used = 0;
}
} else {
mmesa->sarea->nbox = nr - i;
for ( ; i < nr ; i++)
*b++ = pbox[i];
}
/* Finished with the buffer?
*/
if (nr == nbox)
discard = 1;
mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;
vertex.idx = buffer->idx;
vertex.used = buffer->used;
vertex.discard = discard;
drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,
&vertex, sizeof(drmMGAVertex) );
age_mmesa(mmesa, mmesa->sarea->last_enqueue);
}
}
/* Do we really need to do this ? */
#ifdef __i386__
if ( __break_vertex ) {
__asm__ __volatile__ ( "int $3" );
}
#endif
mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
}
void mgaFlushVertices( mgaContextPtr mmesa )
{
LOCK_HARDWARE( mmesa );
mgaFlushVerticesLocked( mmesa );
UNLOCK_HARDWARE( mmesa );
}
void mgaFireILoadLocked( mgaContextPtr mmesa,
GLuint offset, GLuint length )
{
if (!mmesa->iload_buffer) {
fprintf(stderr, "mgaFireILoad: no buffer\n");
return;
}
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",
mmesa->iload_buffer->idx, (int)offset, (int)length );
mga_iload_dma_ioctl( mmesa, offset, length );
}
void mgaGetILoadBufferLocked( mgaContextPtr mmesa )
{
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",
mmesa->iload_buffer);
mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );
}
drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa )
{
return mga_get_buffer_ioctl( mmesa );
}
void mgaDDFlush( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
FLUSH_BATCH( mmesa );
/* This may be called redundantly - dispatch_age may trail what
* has actually been sent and processed by the hardware.
*/
if (1 || GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) {
LOCK_HARDWARE( mmesa );
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
UNLOCK_HARDWARE( mmesa );
}
}
void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer )
{
drmMGAVertex vertex;
if (!buffer) return;
vertex.idx = buffer->idx;
vertex.used = 0;
vertex.discard = 1;
drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,
&vertex, sizeof(drmMGAVertex) );
}
int mgaFlushDMA( int fd, drmLockFlags flags )
{
drmMGALock lock;
int ret, i = 0;
memset( &lock, 0, sizeof(drmMGALock) );
if ( flags & DRM_LOCK_QUIESCENT ) lock.flags |= DRM_LOCK_QUIESCENT;
if ( flags & DRM_LOCK_FLUSH ) lock.flags |= DRM_LOCK_FLUSH;
if ( flags & DRM_LOCK_FLUSH_ALL ) lock.flags |= DRM_LOCK_FLUSH_ALL;
do {
ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) );
} while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );
if ( ret == 0 )
return 0;
if ( errno != EBUSY )
return -errno;
if ( lock.flags & DRM_LOCK_QUIESCENT ) {
/* Only keep trying if we need quiescence.
*/
lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL);
do {
ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) );
} while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );
}
if ( ret == 0 ) {
return 0;
} else {
return -errno;
}
}
void mgaDDInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Clear = mgaDDClear;
ctx->Driver.Flush = mgaDDFlush;
ctx->Driver.Finish = mgaDDFinish;
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
* Gareth Hughes <gareth@valinux.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
#ifndef MGA_IOCTL_H
#define MGA_IOCTL_H
#include "mgacontext.h"
#include "mga_xmesa.h"
void mgaSwapBuffers( __DRIdrawablePrivate *dPriv );
GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa );
void mgaWaitForVBlank( mgaContextPtr mmesa );
void mgaFireILoadLocked( mgaContextPtr mmesa,
GLuint offset, GLuint length );
void mgaWaitAgeLocked( mgaContextPtr mmesa, int age );
void mgaWaitAge( mgaContextPtr mmesa, int age );
void mgaFlushVertices( mgaContextPtr mmesa );
void mgaFlushVerticesLocked( mgaContextPtr mmesa );
void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer );
int mgaFlushDMA( int fd, drmLockFlags flags );
void mgaDDFlush( GLcontext *ctx );
void mgaDDFinish( GLcontext *ctx );
void mgaDDInitIoctlFuncs( GLcontext *ctx );
#define FLUSH_BATCH(mmesa) do { \
if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) \
fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa); \
} while (0)
#define MGA_STATECHANGE(mmesa, flag) do { \
FLUSH_BATCH(mmesa); \
mmesa->dirty |= flag; \
} while (0)
extern drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa );
static __inline
GLuint *mgaAllocDmaLow( mgaContextPtr mmesa, int bytes )
{
GLuint *head;
if (!mmesa->vertex_dma_buffer) {
LOCK_HARDWARE( mmesa );
mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
UNLOCK_HARDWARE( mmesa );
} else if (mmesa->vertex_dma_buffer->used + bytes >
mmesa->vertex_dma_buffer->total) {
LOCK_HARDWARE( mmesa );
mgaFlushVerticesLocked( mmesa );
mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
UNLOCK_HARDWARE( mmesa );
}
head = (GLuint *)((char *)mmesa->vertex_dma_buffer->address +
mmesa->vertex_dma_buffer->used);
mmesa->vertex_dma_buffer->used += bytes;
return head;
}
#define UPDATE_LOCK( mmesa, flags ) \
do { \
GLint ret = mgaFlushDMA( mmesa->driFd, flags ); \
if ( ret < 0 ) { \
drmCommandNone( mmesa->driFd, DRM_MGA_RESET ); \
UNLOCK_HARDWARE( mmesa ); \
fprintf( stderr, "%s: flush ret=%d\n", __FUNCTION__, ret ); \
/*fprintf( stderr, "drmMGAFlushDMA: return = %d\n", ret );*/ \
exit( 1 ); \
} \
} while (0)
#endif

View File

@@ -0,0 +1,690 @@
/*
* Copyright 2000 Compaq Computer Inc. and 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
* Gareth Hughes <gareth@valinux.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.9 2002/11/05 17:46:08 tsi Exp $ */
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "texutil.h"
#include "mgadd.h"
#include "mgacontext.h"
#include "mgaioctl.h"
#include "mgapixel.h"
#include "mgabuffers.h"
#include "xf86drm.h"
#include "mga_common.h"
#include "swrast/swrast.h"
#define IS_AGP_MEM( mmesa, p ) \
((unsigned long)mmesa->mgaScreen->buffers.map <= ((unsigned long)p) && \
(unsigned long)mmesa->mgaScreen->buffers.map + \
(unsigned long)mmesa->mgaScreen->buffers.size > ((unsigned long)p))
#define AGP_OFFSET( mmesa, p ) \
(((unsigned long)p) - (unsigned long)mmesa->mgaScreen->buffers.map)
#if defined(MESA_packed_depth_stencil)
static GLboolean
check_depth_stencil_24_8( const GLcontext *ctx, GLenum type,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz,
GLint pitch )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
return ( type == GL_UNSIGNED_INT_24_8_MESA &&
ctx->Visual->DepthBits == 24 &&
ctx->Visual->StencilBits == 8 &&
mmesa->mgaScreen->cpp == 4 &&
mmesa->hw_stencil &&
!ctx->Pixel.IndexShift &&
!ctx->Pixel.IndexOffset &&
!ctx->Pixel.MapStencilFlag &&
ctx->Pixel.DepthBias == 0.0 &&
ctx->Pixel.DepthScale == 1.0 &&
!packing->SwapBytes &&
pitch % 32 == 0 &&
pitch < 4096 );
}
#endif
static GLboolean
check_depth( const GLcontext *ctx, GLenum type,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz, GLint pitch )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if ( IS_AGP_MEM( mmesa, pixels ) &&
!( ( type == GL_UNSIGNED_INT && mmesa->mgaScreen->cpp == 4 ) ||
( type == GL_UNSIGNED_SHORT && mmesa->mgaScreen->cpp == 2 ) ) )
return GL_FALSE;
return ( ctx->Pixel.DepthBias == 0.0 &&
ctx->Pixel.DepthScale == 1.0 &&
!packing->SwapBytes &&
pitch % 32 == 0 &&
pitch < 4096 );
}
static GLboolean
check_color( const GLcontext *ctx, GLenum type, GLenum format,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz, GLint pitch )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint cpp = mmesa->mgaScreen->cpp;
/* Can't do conversions on agp reads/draws.
*/
if ( IS_AGP_MEM( mmesa, pixels ) &&
!( pitch % 32 == 0 && pitch < 4096 &&
( ( type == GL_UNSIGNED_BYTE &&
cpp == 4 && format == GL_BGRA ) ||
( type == GL_UNSIGNED_INT_8_8_8_8 &&
cpp == 4 && format == GL_BGRA ) ||
( type == GL_UNSIGNED_SHORT_5_6_5_REV &&
cpp == 2 && format == GL_RGB ) ) ) )
return GL_FALSE;
return (!ctx->_ImageTransferState &&
!packing->SwapBytes &&
!packing->LsbFirst);
}
static GLboolean
check_color_per_fragment_ops( const GLcontext *ctx )
{
return (!( ctx->Color.AlphaEnabled ||
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
ctx->Color.ColorLogicOpEnabled ||
ctx->Texture.Unit[0]._ReallyEnabled ||
ctx->Depth.OcclusionTest
) &&
ctx->Current.RasterPosValid &&
ctx->Pixel.ZoomX == 1.0F &&
(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F));
}
static GLboolean
check_depth_per_fragment_ops( const GLcontext *ctx )
{
return ( ctx->Current.RasterPosValid &&
ctx->Color.ColorMask[RCOMP] == 0 &&
ctx->Color.ColorMask[BCOMP] == 0 &&
ctx->Color.ColorMask[GCOMP] == 0 &&
ctx->Color.ColorMask[ACOMP] == 0 &&
ctx->Pixel.ZoomX == 1.0F &&
( ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F ) );
}
/* In addition to the requirements for depth:
*/
#if defined(MESA_packed_depth_stencil)
static GLboolean
check_stencil_per_fragment_ops( const GLcontext *ctx )
{
return ( !ctx->Pixel.IndexShift &&
!ctx->Pixel.IndexOffset );
}
#endif
static GLboolean
clip_pixelrect( const GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height,
GLint *skipPixels, GLint *skipRows,
GLint *size )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
*width = MIN2(*width, MAX_WIDTH); /* redundant? */
/* left clipping */
if (*x < buffer->_Xmin) {
*skipPixels += (buffer->_Xmin - *x);
*width -= (buffer->_Xmin - *x);
*x = buffer->_Xmin;
}
/* right clipping */
if (*x + *width > buffer->_Xmax)
*width -= (*x + *width - buffer->_Xmax - 1);
if (*width <= 0)
return GL_FALSE;
/* bottom clipping */
if (*y < buffer->_Ymin) {
*skipRows += (buffer->_Ymin - *y);
*height -= (buffer->_Ymin - *y);
*y = buffer->_Ymin;
}
/* top clipping */
if (*y + *height > buffer->_Ymax)
*height -= (*y + *height - buffer->_Ymax - 1);
if (*height <= 0)
return GL_FALSE;
*size = ((*y + *height - 1) * mmesa->mgaScreen->frontPitch +
(*x + *width - 1) * mmesa->mgaScreen->cpp);
return GL_TRUE;
}
static GLboolean
mgaTryReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLint size, skipPixels, skipRows;
GLint pitch = pack->RowLength ? pack->RowLength : width;
GLboolean ok;
GLuint planemask;
GLuint source;
#if 0
drmMGABlit blit;
GLuint dest;
GLint source_pitch, dest_pitch;
GLint delta_sx, delta_sy;
GLint delta_dx, delta_dy;
GLint blit_height, ydir;
#endif
if (!clip_pixelrect(ctx, ctx->ReadBuffer,
&x, &y, &width, &height,
&skipPixels, &skipRows, &size)) {
return GL_TRUE;
}
/* Only accelerate reading to agp buffers.
*/
if ( !IS_AGP_MEM(mmesa, (char *)pixels) ||
!IS_AGP_MEM(mmesa, (char *)pixels + size) )
return GL_FALSE;
switch (format) {
#if defined(MESA_packed_depth_stencil)
case GL_DEPTH_STENCIL_MESA:
ok = check_depth_stencil_24_8(ctx, type, pack, pixels, size, pitch);
planemask = ~0;
source = mmesa->mgaScreen->depthOffset;
break;
#endif
case GL_DEPTH_COMPONENT:
ok = check_depth(ctx, type, pack, pixels, size, pitch);
/* Can't accelerate at this depth -- planemask does the wrong
* thing; it doesn't clear the low order bits in the
* destination, instead it leaves them untouched.
*
* Could get the acclerator to solid fill the destination with
* zeros first... Or get the cpu to do it...
*/
if (ctx->Visual.depthBits == 24)
return GL_FALSE;
planemask = ~0;
source = mmesa->mgaScreen->depthOffset;
break;
case GL_RGB:
case GL_BGRA:
ok = check_color(ctx, type, format, pack, pixels, size, pitch);
planemask = ~0;
source = (mmesa->draw_buffer == MGA_FRONT ?
mmesa->mgaScreen->frontOffset :
mmesa->mgaScreen->backOffset);
break;
default:
return GL_FALSE;
}
if (!ok) {
return GL_FALSE;
}
LOCK_HARDWARE( mmesa );
#if 0
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
int nbox, retcode, i;
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
if (mmesa->dirty_cliprects & MGA_FRONT)
mgaUpdateRects( mmesa, MGA_FRONT );
nbox = dPriv->numClipRects;
y = dPriv->h - y - height;
x += mmesa->drawX;
y += mmesa->drawY;
dest = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) |
DO_dstmap_sys | DO_dstacc_agp);
source_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp;
dest_pitch = pitch;
delta_sx = 0;
delta_sy = 0;
delta_dx = -x;
delta_dy = -y;
blit_height = 2*y + height;
ydir = -1;
if (0) fprintf(stderr, "XX doing readpixel blit src_pitch %d dst_pitch %d\n",
source_pitch, dest_pitch);
for (i = 0 ; i < nbox ; )
{
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
XF86DRIClipRectRec *box = dPriv->pClipRects;
drm_clip_rect_t *b = mmesa->sarea->boxes;
int n = 0;
for ( ; i < nr ; i++) {
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
b->x1 = bx;
b->y1 = by;
b->x2 = bx + bw;
b->y2 = by + bh;
b++;
n++;
}
mmesa->sarea->nbox = n;
if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT,
&blit, sizeof(drmMGABlit)))) {
fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode);
UNLOCK_HARDWARE( mmesa );
exit(1);
}
}
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
}
#endif
UNLOCK_HARDWARE( mmesa );
return GL_TRUE;
}
static void
mgaDDReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
if (!mgaTryReadPixels( ctx, x, y, width, height, format, type, pack, pixels))
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels);
}
static void do_draw_pix( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint pitch,
const void *pixels,
GLuint dest, GLuint planemask)
{
#if 0
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
drmMGABlit blit;
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
XF86DRIClipRectPtr pbox = dPriv->pClipRects;
int nbox = dPriv->numClipRects;
int retcode, i;
y = dPriv->h - y - height;
x += mmesa->drawX;
y += mmesa->drawY;
blit.dest = dest;
blit.planemask = planemask;
blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels))
| SO_srcmap_sys | SO_srcacc_agp);
blit.dest_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp;
blit.source_pitch = pitch;
blit.delta_sx = -x;
blit.delta_sy = -y;
blit.delta_dx = 0;
blit.delta_dy = 0;
if (ctx->Pixel.ZoomY == -1) {
blit.height = height;
blit.ydir = 1;
} else {
blit.height = height;
blit.ydir = -1;
}
if (0) fprintf(stderr,
"doing drawpixel blit src_pitch %d dst_pitch %d\n",
blit.source_pitch, blit.dest_pitch);
for (i = 0 ; i < nbox ; )
{
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
XF86DRIClipRectRec *box = mmesa->pClipRects;
drm_clip_rect_t *b = mmesa->sarea->boxes;
int n = 0;
for ( ; i < nr ; i++) {
GLint bx = box[i].x1;
GLint by = box[i].y1;
GLint bw = box[i].x2 - bx;
GLint bh = box[i].y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
if (bw <= 0) continue;
if (bh <= 0) continue;
b->x1 = bx;
b->y1 = by;
b->x2 = bx + bw;
b->y2 = by + bh;
b++;
n++;
}
mmesa->sarea->nbox = n;
if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT,
&blit, sizeof(drmMGABlit)))) {
fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode);
UNLOCK_HARDWARE( mmesa );
exit(1);
}
}
#endif
}
static GLboolean
mgaTryDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLint size, skipPixels, skipRows;
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
GLuint dest, planemask;
GLuint cpp = mmesa->mgaScreen->cpp;
if (!clip_pixelrect(ctx, ctx->DrawBuffer,
&x, &y, &width, &height,
&skipPixels, &skipRows, &size)) {
return GL_TRUE;
}
switch (format) {
#if defined(MESA_packed_depth_stencil)
case GL_DEPTH_STENCIL_MESA:
dest = mmesa->mgaScreen->depthOffset;
planemask = ~0;
if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) ||
!check_depth_per_fragment_ops(ctx) ||
!check_stencil_per_fragment_ops(ctx))
return GL_FALSE;
break;
#endif
case GL_DEPTH_COMPONENT:
dest = mmesa->mgaScreen->depthOffset;
if (ctx->Visual.depthBits == 24)
planemask = ~0xff;
else
planemask = ~0;
if (!check_depth(ctx, type, unpack, pixels, size, pitch) ||
!check_depth_per_fragment_ops(ctx))
return GL_FALSE;
break;
case GL_RGB:
case GL_BGRA:
dest = (mmesa->draw_buffer == MGA_FRONT ?
mmesa->mgaScreen->frontOffset :
mmesa->mgaScreen->backOffset);
planemask = mgaPackColor(cpp,
ctx->Color.ColorMask[RCOMP],
ctx->Color.ColorMask[GCOMP],
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP]);
if (cpp == 2)
planemask |= planemask << 16;
if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
return GL_FALSE;
}
if (!check_color_per_fragment_ops(ctx)) {
return GL_FALSE;
}
break;
default:
return GL_FALSE;
}
LOCK_HARDWARE_QUIESCENT( mmesa );
if (mmesa->dirty_cliprects & MGA_FRONT)
mgaUpdateRects( mmesa, MGA_FRONT );
if ( IS_AGP_MEM(mmesa, (char *)pixels) &&
IS_AGP_MEM(mmesa, (char *)pixels + size) )
{
do_draw_pix( ctx, x, y, width, height, pitch, pixels,
dest, planemask );
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
}
else
{
/* Pixels is in regular memory -- get dma buffers and perform
* upload through them.
*/
/* drmBufPtr buf = mgaGetBufferLocked(mmesa); */
GLuint bufferpitch = (width*cpp+31)&~31;
char *address = 0; /* mmesa->mgaScreen->agp.map; */
do {
/* GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */
GLuint rows = height;
if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n",
rows, bufferpitch);
/* The texture conversion code is so slow that there is only
* negligble speedup when the buffers/images don't exactly
* match:
*/
#if 0
if (cpp == 2) {
if (!_mesa_convert_texsubimage2d( MESA_FORMAT_RGB565,
0, 0, width, rows,
bufferpitch, format, type,
unpack, pixels, address )) {
/* mgaReleaseBufLocked( mmesa, buf ); */
UNLOCK_HARDWARE(mmesa);
return GL_FALSE;
}
} else {
if (!_mesa_convert_texsubimage2d( MESA_FORMAT_ARGB8888,
0, 0, width, rows,
bufferpitch, format, type,
unpack, pixels, address )) {
/* mgaReleaseBufLocked( mmesa, buf ); */
UNLOCK_HARDWARE(mmesa);
return GL_FALSE;
}
}
#else
memcpy( address, pixels, rows*bufferpitch );
#endif
do_draw_pix( ctx, x, y, width, rows,
bufferpitch/cpp, address, dest, planemask );
/* Fix me -- use multiple buffers to avoid flush.
*/
UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
pixels = (void *)((char *) pixels + rows * pitch);
height -= rows;
y += rows;
} while (height);
/* mgaReleaseBufLocked( mmesa, buf ); */
}
UNLOCK_HARDWARE( mmesa );
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
return GL_TRUE;
}
static void
mgaDDDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
if (!mgaTryDrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels ))
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
}
/* Stub functions - not a real allocator, always returns pointer to
* the same block of agp space which isn't used for anything else at
* present.
*/
#if defined(MESA_hacked_agp_allocator)
static void mgaDDFreeAgpMemory( GLcontext *ctx, void *ptr )
{
(void) ptr;
}
static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP])
return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP];
else
return 0;
}
static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (!IS_AGP_MEM(mmesa, ptr))
return -1;
return AGP_OFFSET(mmesa, ptr);
}
#endif
void mgaDDInitPixelFuncs( GLcontext *ctx )
{
#if defined (MESA_experimetal_agp_allocator)
ctx->Driver.AllocateAgpMemory = mgaDDAllocateAgpMemory;
ctx->Driver.GetAgpOffset = mgaDDGetAgpOffset;
ctx->Driver.FreeAgpMemory = mgaDDFreeAgpMemory;
#endif
/* Pixel path fallbacks.
*/
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.Bitmap = _swrast_Bitmap;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
ctx->Driver.ReadPixels = _swrast_ReadPixels;
if (getenv("MGA_BLIT_PIXELS")) {
ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */
ctx->Driver.DrawPixels = mgaDDDrawPixels; /* works with agp/normal mem */
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2000-2001 Compaq Computer Inc. 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */
#ifndef MGA_PIXELS_H
#define MGA_PIXELS_H
#include "mtypes.h"
extern void mgaDDInitPixelFuncs( GLcontext *ctx );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,208 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgarender.c,v 1.4 2002/10/30 12:51:36 alanh 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:
* Keith Whitwell <keith@tungstengraphics.com>
*
*/
/*
* Render unclipped vertex buffers by emitting vertices directly to
* dma buffers. Use strip/fan hardware primitives where possible.
* Simulate missing primitives with indexed vertices.
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
//#include "mem.h"
#include "mtypes.h"
#include "mmath.h"
#include "tnl/t_context.h"
#include "mgacontext.h"
#include "mgatris.h"
#include "mgastate.h"
#include "mgaioctl.h"
#include "mgavb.h"
#define HAVE_POINTS 0
#define HAVE_LINES 0
#define HAVE_LINE_STRIPS 0
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_STRIP_1 0
#define HAVE_TRI_FANS 1
#define HAVE_POLYGONS 0
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
#define HAVE_ELTS 0 /* for now */
static void mgaDmaPrimitive( GLcontext *ctx, GLenum prim )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint hwprim;
switch (prim) {
case GL_TRIANGLES:
hwprim = MGA_WA_TRIANGLES;
break;
case GL_TRIANGLE_STRIP:
if (mmesa->vertex_size == 8)
hwprim = MGA_WA_TRISTRIP_T0;
else
hwprim = MGA_WA_TRISTRIP_T0T1;
break;
case GL_TRIANGLE_FAN:
if (mmesa->vertex_size == 8)
hwprim = MGA_WA_TRIFAN_T0;
else
hwprim = MGA_WA_TRIFAN_T0T1;
break;
default:
return;
}
mgaRasterPrimitive( ctx, GL_TRIANGLES, hwprim );
}
static void VERT_FALLBACK( GLcontext *ctx, GLuint start, GLuint count,
GLuint flags )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags );
MGA_CONTEXT(ctx)->SetupNewInputs |= VERT_BIT_CLIP;
}
#define LOCAL_VARS mgaContextPtr mmesa = MGA_CONTEXT(ctx)
#define INIT( prim ) do { \
if (0) fprintf(stderr, "%s\n", __FUNCTION__); \
FLUSH_BATCH(mmesa); \
mgaDmaPrimitive( ctx, prim ); \
} while (0)
#define NEW_PRIMITIVE() FLUSH_BATCH( mmesa )
#define NEW_BUFFER() FLUSH_BATCH( mmesa )
#define GET_CURRENT_VB_MAX_VERTS() \
0 /* fix me */
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
MGA_BUFFER_SIZE / (mmesa->vertex_size * 4)
#define EMIT_VERTS( ctx, j, nr ) \
mga_emit_contiguous_verts(ctx, j, (j)+(nr))
#define TAG(x) mga_##x
#include "tnl_dd/t_dd_dmatmp.h"
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
static GLboolean mga_run_render( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i, length, flags = 0;
/* Don't handle clipping or indexed vertices or vertex manipulations.
*/
if (VB->ClipOrMask || mmesa->RenderIndex != 0 || VB->Elts) {
return GL_TRUE;
}
tnl->Driver.Render.Start( ctx );
mmesa->SetupNewInputs = ~0;
for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
{
flags = VB->Primitive[i];
length= VB->PrimitiveLength[i];
if (length)
mga_render_tab_verts[flags & PRIM_MODE_MASK]( ctx, i, i + length,
flags );
}
tnl->Driver.Render.Finish( ctx );
return GL_FALSE; /* finished the pipe */
}
static void mga_check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
{
GLuint inputs = VERT_BIT_POS | VERT_BIT_CLIP | VERT_BIT_COLOR0;
if (ctx->RenderMode == GL_RENDER) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
inputs |= VERT_BIT_COLOR1;
if (ctx->Texture.Unit[0]._ReallyEnabled)
inputs |= VERT_BIT_TEX0;
if (ctx->Texture.Unit[1]._ReallyEnabled)
inputs |= VERT_BIT_TEX1;
if (ctx->Fog.Enabled)
inputs |= VERT_BIT_FOG;
}
stage->inputs = inputs;
}
static void dtr( struct gl_pipeline_stage *stage )
{
(void)stage;
}
const struct gl_pipeline_stage _mga_render_stage =
{
"mga render",
(_DD_NEW_SEPARATE_SPECULAR |
_NEW_TEXTURE|
_NEW_FOG|
_NEW_RENDERMODE), /* re-check (new inputs) */
0, /* re-run (always runs) */
GL_TRUE, /* active */
0, 0, /* inputs (set in check_render), outputs */
0, 0, /* changed_inputs, private */
dtr, /* destructor */
mga_check_render, /* check - initially set to alloc data */
mga_run_render /* run */
};

View File

@@ -0,0 +1,284 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
#include "mtypes.h"
#include "mgadd.h"
#include "mgacontext.h"
#include "mgaspan.h"
#include "mgaioctl.h"
#include "swrast/swrast.h"
#define DBG 0
#define LOCAL_VARS \
__DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
__DRIscreenPrivate *sPriv = mmesa->driScreen; \
GLuint pitch = mgaScreen->frontPitch; \
GLuint height = dPriv->h; \
char *read_buf = (char *)(sPriv->pFB + \
mmesa->readOffset + \
dPriv->x * mgaScreen->cpp + \
dPriv->y * pitch); \
char *buf = (char *)(sPriv->pFB + \
mmesa->drawOffset + \
dPriv->x * mgaScreen->cpp + \
dPriv->y * pitch); \
GLuint p; \
(void) read_buf; (void) buf; (void) p
#define LOCAL_DEPTH_VARS \
__DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
__DRIscreenPrivate *sPriv = mmesa->driScreen; \
GLuint pitch = mgaScreen->frontPitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(sPriv->pFB + \
mgaScreen->depthOffset + \
dPriv->x * mgaScreen->cpp + \
dPriv->y * pitch)
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
_y >= miny && _y < maxy)
#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
if ( _y < miny || _y >= maxy ) { \
_n1 = 0, _x1 = x; \
} else { \
_n1 = _n; \
_x1 = _x; \
if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
}
#define HW_LOCK() \
mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
FLUSH_BATCH(mmesa); \
LOCK_HARDWARE_QUIESCENT(mmesa);
#define HW_CLIPLOOP() \
do { \
int _nc = mmesa->numClipRects; \
while (_nc--) { \
int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
#define HW_ENDCLIPLOOP() \
} \
} while (0)
#define HW_UNLOCK() \
UNLOCK_HARDWARE(mmesa);
/* 16 bit, 565 rgb color spanline and pixel functions
*/
#define Y_FLIP(_y) (height - _y - 1)
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p, color) \
p = MGAPACKCOLOR565( color[0], color[1], color[2] )
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
(((int)g & 0xfc) << 3) | \
(((int)b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
rgba[3] = 255; \
} while(0)
#define TAG(x) mga##x##_565
#include "spantmp.h"
/* 32 bit, 8888 argb color spanline and pixel functions
*/
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p, color) \
p = MGAPACKCOLOR8888( color[0], color[1], color[2], color[3] )
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
(g << 8) | \
(b << 0) | \
(a << 24) )
#define WRITE_PIXEL(_x, _y, p) \
*(GLuint *)(buf + _x*4 + _y*pitch) = p
#define READ_RGBA(rgba, _x, _y) \
do { \
GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = 0xff; \
} while (0)
#define TAG(x) mga##x##_8888
#include "spantmp.h"
/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + _x*2 + _y*pitch);
#define TAG(x) mga##x##_16
#include "depthtmp.h"
/* 32 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch);
#define TAG(x) mga##x##_32
#include "depthtmp.h"
/* 24/8 bit interleaved depth/stencil functions
*/
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
tmp &= 0xff; \
tmp |= (d) << 8; \
*(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
}
#define READ_DEPTH( d, _x, _y ) { \
d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8; \
}
#define TAG(x) mga##x##_24_8
#include "depthtmp.h"
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
tmp &= 0xffffff00; \
tmp |= d & 0xff; \
*(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
}
#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
#define TAG(x) mga##x##_24_8
#include "stenciltmp.h"
void mgaDDInitSpanFuncs( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
switch (mmesa->mgaScreen->cpp) {
case 2:
swdd->WriteRGBASpan = mgaWriteRGBASpan_565;
swdd->WriteRGBSpan = mgaWriteRGBSpan_565;
swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_565;
swdd->WriteRGBAPixels = mgaWriteRGBAPixels_565;
swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_565;
swdd->ReadRGBASpan = mgaReadRGBASpan_565;
swdd->ReadRGBAPixels = mgaReadRGBAPixels_565;
swdd->ReadDepthSpan = mgaReadDepthSpan_16;
swdd->WriteDepthSpan = mgaWriteDepthSpan_16;
swdd->ReadDepthPixels = mgaReadDepthPixels_16;
swdd->WriteDepthPixels = mgaWriteDepthPixels_16;
break;
case 4:
swdd->WriteRGBASpan = mgaWriteRGBASpan_8888;
swdd->WriteRGBSpan = mgaWriteRGBSpan_8888;
swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_8888;
swdd->WriteRGBAPixels = mgaWriteRGBAPixels_8888;
swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_8888;
swdd->ReadRGBASpan = mgaReadRGBASpan_8888;
swdd->ReadRGBAPixels = mgaReadRGBAPixels_8888;
if (!mmesa->hw_stencil) {
swdd->ReadDepthSpan = mgaReadDepthSpan_32;
swdd->WriteDepthSpan = mgaWriteDepthSpan_32;
swdd->ReadDepthPixels = mgaReadDepthPixels_32;
swdd->WriteDepthPixels = mgaWriteDepthPixels_32;
} else {
swdd->ReadDepthSpan = mgaReadDepthSpan_24_8;
swdd->WriteDepthSpan = mgaWriteDepthSpan_24_8;
swdd->ReadDepthPixels = mgaReadDepthPixels_24_8;
swdd->WriteDepthPixels = mgaWriteDepthPixels_24_8;
swdd->ReadStencilSpan = mgaReadStencilSpan_24_8;
swdd->WriteStencilSpan = mgaWriteStencilSpan_24_8;
swdd->ReadStencilPixels = mgaReadStencilPixels_24_8;
swdd->WriteStencilPixels = mgaWriteStencilPixels_24_8;
}
break;
}
}

View File

@@ -0,0 +1,34 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.h,v 1.3 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef _MGA_SPAN_H
#define _MGA_SPAN_H
extern void mgaDDInitSpanFuncs( GLcontext *ctx );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef _MGA_STATE_H
#define _MGA_STATE_H
extern void mgaInitState( mgaContextPtr mmesa );
extern void mgaDDInitStateFuncs(GLcontext *ctx);
extern void mgaDDUpdateHwState( GLcontext *ctx );
extern void mgaUpdateClipping(const GLcontext *ctx);
extern void mgaUpdateCull( GLcontext *ctx );
extern void mgaCalcViewport( GLcontext *ctx );
#endif

View File

@@ -0,0 +1,984 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include <GL/gl.h>
#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"
#include "mgaregs.h"
#include "mgatris.h"
#include "mgaioctl.h"
#include "enums.h"
#include "simple_list.h"
//#include "mem.h"
#include "macros.h"
#include "texformat.h"
#include "texstore.h"
#include "swrast/swrast.h"
#define TEX_0 1
#define TEX_1 2
/*
* mgaDestroyTexObj
* Free all memory associated with a texture and NULL any pointers
* to it.
*/
void
mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
if ( !t ) return;
/* free the texture memory */
if (t->MemBlock) {
mmFreeMem( t->MemBlock );
t->MemBlock = 0;
if (mmesa && t->age > mmesa->dirtyAge)
mmesa->dirtyAge = t->age;
}
/* free mesa's link */
if (t->tObj)
t->tObj->DriverData = NULL;
/* see if it was the driver's current object */
if (mmesa) {
if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
}
remove_from_list(t);
free( t );
}
/*
* mgaSetTexWrappings
*/
static void mgaSetTexWrapping( mgaTextureObjectPtr t,
GLenum sWrap,
GLenum tWrap )
{
GLuint val = 0;
if (sWrap != GL_REPEAT)
val |= TMC_clampu_enable;
if (tWrap != GL_REPEAT)
val |= TMC_clampv_enable;
t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable);
t->setup.texctl |= val;
}
/*
* mgaSetTexFilter
*/
static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf)
{
GLuint val = 0;
switch (minf) {
case GL_NEAREST: val = TF_minfilter_nrst; break;
case GL_LINEAR: val = TF_minfilter_bilin; break;
case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break;
case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break;
case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break;
case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break;
default: val = TF_minfilter_nrst; break;
}
switch (magf) {
case GL_NEAREST: val |= TF_magfilter_nrst; break;
case GL_LINEAR: val |= TF_magfilter_bilin; break;
default: val |= TF_magfilter_nrst; break;
}
/* See OpenGL 1.2 specification */
if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
minf == GL_NEAREST_MIPMAP_LINEAR)) {
val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */
} else {
val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */
}
t->setup.texfilter &= (TF_minfilter_MASK |
TF_magfilter_MASK |
TF_fthres_MASK);
t->setup.texfilter |= val;
}
/*
* mgaSetTexBorderColor
*/
static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
{
t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1],
color[2],color[3]);
}
static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
struct gl_texture_image *texImage,
GLenum format, GLenum type )
{
const GLboolean do32bpt = mmesa->default32BitTextures;
const struct gl_texture_format *texFormat;
GLint ret;
if ( 0 )
fprintf( stderr, "internal=%s format=%s type=%s\n",
texImage->IntFormat == 3 ? "GL_RGB (3)" :
texImage->IntFormat == 4 ? "GL_RGBA (4)" :
_mesa_lookup_enum_by_nr( texImage->IntFormat ),
_mesa_lookup_enum_by_nr( format ),
_mesa_lookup_enum_by_nr( type ) );
#define SET_FORMAT( r, gl ) \
do { \
ret = (r); \
texFormat = &(gl); \
} while (0)
#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \
do { \
if ( do32bpt ) { \
ret = (r32); \
texFormat = &(gl32); \
} else { \
ret = (r16); \
texFormat = &(gl16); \
} \
} while (0)
switch ( texImage->IntFormat ) {
/* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
* got to be better than sticking them way down the end of this
* huge list.
*/
case 4:
case GL_RGBA:
case GL_COMPRESSED_RGBA:
if ( format == GL_BGRA ) {
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 );
break;
} else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
} else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
break;
}
}
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case 3:
case GL_RGB:
case GL_COMPRESSED_RGB:
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
}
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
/* GH: Okay, keep checking as normal. Still test for GL_RGB,
* GL_RGBA formats first.
*/
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case GL_RGBA4:
case GL_RGBA2:
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case GL_RGB5_A1:
SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
break;
case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
case GL_RGB5:
case GL_RGB4:
case GL_R3_G3_B2:
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
case GL_ALPHA:
case GL_ALPHA4:
case GL_ALPHA8:
case GL_ALPHA12:
case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE4:
case GL_LUMINANCE8:
case GL_LUMINANCE12:
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
case 2:
case GL_LUMINANCE_ALPHA:
case GL_LUMINANCE4_ALPHA4:
case GL_LUMINANCE6_ALPHA2:
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE12_ALPHA4:
case GL_LUMINANCE12_ALPHA12:
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case GL_INTENSITY:
case GL_INTENSITY4:
case GL_INTENSITY8:
case GL_INTENSITY12:
case GL_INTENSITY16:
case GL_COMPRESSED_INTENSITY:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
case GL_COLOR_INDEX:
case GL_COLOR_INDEX1_EXT:
case GL_COLOR_INDEX2_EXT:
case GL_COLOR_INDEX4_EXT:
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 );
break;
default:
fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d",
texImage->IntFormat );
return -1;
}
texImage->TexFormat = texFormat;
return ret;
}
/*
* mgaCreateTexObj
* Allocate space for and load the mesa images into the texture memory block.
* This will happen before drawing with a new texture, or drawing with a
* texture after it was swapped out or teximaged again.
*/
static void mgaCreateTexObj(mgaContextPtr mmesa,
struct gl_texture_object *tObj)
{
const GLint baseLevel = tObj->BaseLevel;
struct gl_texture_image *image = tObj->Image[baseLevel];
mgaTextureObjectPtr t;
int i, ofs;
int LastLevel;
int s, s2;
int tformat;
if (!image) return;
tObj->DriverData = t = calloc( 1, sizeof( *t ) );
if (!t) {
fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" );
return;
}
/* FIXME: Use the real DD interface...
*/
tformat = mgaChooseTexFormat( mmesa, image, image->Format,
GL_UNSIGNED_BYTE );
t->texelBytes = image->TexFormat->TexelBytes;
/* We are going to upload all levels that are present, even if
* later levels wouldn't be used by the current filtering mode. This
* allows the filtering mode to change without forcing another upload
* of the images.
*/
LastLevel = MGA_TEX_MAXLEVELS-1;
ofs = 0;
for ( i = 0 ; i <= LastLevel ; i++ ) {
if ( !tObj->Image[i] ) {
LastLevel = i - 1;
break;
}
t->offsets[i] = ofs;
t->dirty_images |= (1<<i);
ofs += ((MAX2( tObj->Image[i]->Width, 8 ) *
MAX2( tObj->Image[i]->Height, 8 ) *
t->texelBytes) + 31) & ~31;
}
t->totalSize = ofs;
t->lastLevel = LastLevel;
t->tObj = tObj;
t->ctx = mmesa;
t->age = 0;
t->bound = 0;
t->MemBlock = 0;
insert_at_tail(&(mmesa->SwappedOut), t);
/* setup hardware register values */
t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat;
if (image->WidthLog2 >= 3)
t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT);
else
t->setup.texctl |= (TMC_tpitchlin_enable |
(image->Width << TMC_tpitchext_SHIFT));
t->setup.texctl2 = TMC_ckstransdis_enable;
if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )
t->setup.texctl2 |= TMC_specen_enable;
t->setup.texfilter = (TF_minfilter_nrst |
TF_magfilter_nrst |
TF_filteralpha_enable |
(0x10 << TF_fthres_SHIFT) |
(LastLevel << TF_mapnb_SHIFT));
/* warp texture registers */
ofs = MGA_IS_G200(mmesa) ? 28 : 11;
s = image->Width;
s2 = image->WidthLog2;
t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) |
MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) |
MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ));
s = image->Height;
s2 = image->HeightLog2;
t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) |
MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) |
MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ));
/* set all the register values for filtering, border, etc */
mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
mgaSetTexBorderColor( t, tObj->_BorderChan );
}
static void mgaUpdateTextureEnvG200( GLcontext *ctx )
{
struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
mgaTextureObjectPtr t;
if (!tObj || !tObj->DriverData)
return;
t = (mgaTextureObjectPtr)tObj->DriverData;
t->setup.texctl2 &= ~TMC_decalblend_enable;
switch (ctx->Texture.Unit[0].EnvMode) {
case GL_REPLACE:
t->setup.texctl &= ~TMC_tmodulate_enable;
break;
case GL_MODULATE:
t->setup.texctl |= TMC_tmodulate_enable;
break;
case GL_DECAL:
t->setup.texctl &= ~TMC_tmodulate_enable;
t->setup.texctl2 |= TMC_decalblend_enable;
break;
case GL_BLEND:
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
break;
default:
break;
}
}
static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
GLuint source = mmesa->tmu_source[unit];
struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current;
GLenum format;
if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )
return;
format = tObj->Image[tObj->BaseLevel]->Format;
switch (ctx->Texture.Unit[source].EnvMode) {
case GL_REPLACE:
if (format == GL_RGB || format == GL_LUMINANCE) {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else if (format == GL_ALPHA) {
*reg = (TD0_color_sel_arg2 |
TD0_color_arg2_diffuse |
TD0_alpha_sel_arg1 );
}
else {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_sel_arg1 );
}
break;
case GL_MODULATE:
if (unit == 0) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
break;
case GL_DECAL:
if (format == GL_RGB) {
if (unit == 0) {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2 );
}
}
else if ( format == GL_RGBA ) {
#if 0
if (unit == 0) {
/* this doesn't work */
*reg = (TD0_color_arg2_diffuse |
TD0_color_alpha_currtex |
TD0_color_alpha2inv_enable |
TD0_color_arg2mul_alpha2 |
TD0_color_arg1mul_alpha1 |
TD0_color_blend_enable |
TD0_color_arg1add_mulout |
TD0_color_arg2add_mulout |
TD0_color_add_add |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else {
*reg = (TD0_color_arg2_prevstage |
TD0_color_alpha_currtex |
TD0_color_alpha2inv_enable |
TD0_color_arg2mul_alpha2 |
TD0_color_arg1mul_alpha1 |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2 );
}
#else
/* s/w fallback, pretty sure we can't do in h/w */
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n",
unit );
#endif
}
else {
if (unit == 0) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_sel_arg2 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2);
}
}
break;
case GL_ADD:
if (unit == 0) {
if (format == GL_INTENSITY)
*reg = ( TD0_color_arg2_diffuse |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
TD0_alpha_add_enable |
TD0_alpha_sel_add);
else if (format == GL_ALPHA)
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
else
*reg = ( TD0_color_arg2_diffuse |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
if (format == GL_INTENSITY) {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_add_enable |
TD0_alpha_sel_add);
}
else if (format == GL_ALPHA) {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
}
break;
case GL_BLEND:
if (format == GL_ALPHA) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n",
mmesa->envcolor );
/* Do singletexture GL_BLEND with 'all ones' env-color
* by using both texture units. Multitexture gl_blend
* is a fallback.
*/
if (unit == 0) {
/* Part 1: R1 = Rf ( 1 - Rt )
* A1 = Af At
*/
*reg = ( TD0_color_arg2_diffuse |
TD0_color_arg1_inv_enable |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg1);
} else {
/* Part 2: R2 = R1 + Rt
* A2 = A1
*/
*reg = ( TD0_color_arg2_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2);
}
}
break;
default:
break;
}
}
static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit )
{
mgaTextureObjectPtr t;
struct gl_texture_object *tObj;
GLuint enabled;
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint gl_unit = mmesa->tmu_source[hw_unit];
enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled;
tObj = ctx->Texture.Unit[gl_unit]._Current;
if (enabled != TEXTURE_2D_BIT) {
if (enabled)
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
return;
}
if (tObj->Image[tObj->BaseLevel]->Border > 0) {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: texture border\n" );
return;
}
if ( !tObj->DriverData ) {
mgaCreateTexObj( mmesa, tObj );
if ( !tObj->DriverData ) {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
return;
}
}
t = (mgaTextureObjectPtr)tObj->DriverData;
if (t->dirty_images)
mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit);
mmesa->CurrentTexObj[hw_unit] = t;
t->bound |= hw_unit+1;
/* if (t->MemBlock) */
/* mgaUpdateTexLRU( mmesa, t ); */
t->setup.texctl2 &= ~TMC_dualtex_enable;
if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT))
t->setup.texctl2 |= TMC_dualtex_enable;
t->setup.texctl2 &= ~TMC_specen_enable;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
t->setup.texctl2 |= TMC_specen_enable;
}
/* The G400 is now programmed quite differently wrt texture environment.
*/
void mgaUpdateTextureState( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE );
if (mmesa->CurrentTexObj[0]) {
mmesa->CurrentTexObj[0]->bound = 0;
mmesa->CurrentTexObj[0] = 0;
}
if (mmesa->CurrentTexObj[1]) {
mmesa->CurrentTexObj[1]->bound = 0;
mmesa->CurrentTexObj[1] = 0;
}
if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
mmesa->tmu_source[0] = 1;
} else {
mmesa->tmu_source[0] = 0;
}
if (MGA_IS_G400(mmesa)) {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureEnvG400( ctx, 0 );
mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
mgaUpdateTextureObject( ctx, 1 );
mgaUpdateTextureEnvG400( ctx, 1 );
mmesa->dirty |= MGA_UPLOAD_TEX1;
}
} else {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureEnvG200( ctx );
}
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0;
mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= (ctx->Texture.Unit[0]._ReallyEnabled
? DC_opcod_texture_trap
: DC_opcod_trap);
}
static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (pname == GL_TEXTURE_ENV_MODE) {
/* force the texture state to be updated */
FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE |
MGA_NEW_ALPHA);
}
else if (pname == GL_TEXTURE_ENV_COLOR)
{
struct gl_texture_unit *texUnit =
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
GLfloat *fc = texUnit->EnvColor;
GLubyte c[4];
GLuint col;
COPY_4V(c, fc);
col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
if (mmesa->setup.fcol != col) {
FLUSH_BATCH(mmesa);
mmesa->setup.fcol = col;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
/* Actually just require all four components to be
* equal. This permits a single-pass GL_BLEND.
*
* More complex multitexture/multipass fallbacks
* for blend can be done later.
*/
if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff)
mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
}
}
}
static void mgaTexImage2D( 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 )
{
mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
if (t) {
mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
texObj->DriverData = 0;
}
_mesa_store_teximage2d( ctx, target, level, internalFormat,
width, height, border, format, type,
pixels, packing, texObj, texImage );
}
static void mgaTexSubImage2D( GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
if (t) {
mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
texObj->DriverData = 0;
}
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
texImage);
}
/*
* mgaTexParameter
* This just changes variables and flags for a state update, which
* will happen at the next mgaUpdateTextureState
*/
static void
mgaDDTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;
t = (mgaTextureObjectPtr) tObj->DriverData;
/* if we don't have a hardware texture, it will be automatically
created with current state before it is used, so we don't have
to do anything now */
if ( !t || !t->bound || target != GL_TEXTURE_2D ) {
return;
}
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
FLUSH_BATCH(mmesa);
mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;
case GL_TEXTURE_BORDER_COLOR:
FLUSH_BATCH(mmesa);
mgaSetTexBorderColor(t,tObj->_BorderChan);
break;
default:
return;
}
mmesa->new_state |= MGA_NEW_TEXTURE;
}
static void
mgaDDBindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
int unit = ctx->Texture.CurrentUnit;
FLUSH_BATCH(mmesa);
if (mmesa->CurrentTexObj[unit]) {
mmesa->CurrentTexObj[unit]->bound &= ~(unit+1);
mmesa->CurrentTexObj[unit] = 0;
}
/* force the texture state to be updated
*/
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
static void
mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;
if ( t ) {
if (mmesa) {
if (t->bound) {
FLUSH_BATCH(mmesa);
if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
}
mmesa->new_state |= MGA_NEW_TEXTURE;
}
mgaDestroyTexObj( mmesa, t );
}
}
static GLboolean
mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
{
mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData;
return mt && mt->MemBlock;
}
void
mgaDDInitTextureFuncs( GLcontext *ctx )
{
ctx->Driver.TexEnv = mgaDDTexEnv;
ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
ctx->Driver.TexImage1D = _mesa_store_teximage1d;
ctx->Driver.TexImage2D = mgaTexImage2D;
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
ctx->Driver.TexSubImage2D = mgaTexSubImage2D;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
ctx->Driver.BindTexture = mgaDDBindTexture;
ctx->Driver.DeleteTexture = mgaDDDeleteTexture;
ctx->Driver.TexParameter = mgaDDTexParameter;
ctx->Driver.UpdateTexturePalette = 0;
ctx->Driver.IsTextureResident = mgaDDIsTextureResident;
}

View File

@@ -0,0 +1,62 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.7 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef MGATEX_INC
#define MGATEX_INC
#include "mgacontext.h"
typedef struct mga_texture_object_s *mgaTextureObjectPtr;
/* Called before a primitive is rendered to make sure the texture
* state is properly setup. Texture residence is checked later
* when we grab the lock.
*/
void mgaUpdateTextureState( GLcontext *ctx );
void mgaConvertTexture( GLuint *dest, int texelBytes,
struct gl_texture_image *image,
int x, int y, int width, int height );
void mgaUploadSubImageLocked( mgaContextPtr mmesa,
mgaTextureObjectPtr t,
int level,
int x, int y, int width, int height );
int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t );
void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t );
void mgaAgeTextures( mgaContextPtr mmesa, int heap );
void mgaDDInitTextureFuncs( GLcontext *ctx );
#endif

View File

@@ -0,0 +1,256 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include <stdlib.h>
#include <stdio.h>
#include <GL/gl.h>
#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"
/*
* mgaConvertTexture
* Converts a mesa format texture to the apropriate hardware format
* Note that sometimes width may be larger than the texture, like 64x1
* for an 8x8 texture. This happens when we have to crutch the pitch
* limits of the mga by uploading a block of texels as a single line.
*/
void mgaConvertTexture( GLuint *destPtr, int texelBytes,
struct gl_texture_image *image,
int x, int y, int width, int height )
{
register int i, j;
GLubyte *src;
int stride;
if (0)
fprintf(stderr, "texture image %p\n", image->Data);
if (image->Data == 0)
return;
/* FIXME: g400 luminance_alpha internal format */
switch (texelBytes) {
case 1:
switch (image->Format) {
case GL_COLOR_INDEX:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 2 ; j ; j-- ) {
*destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 );
src += 4;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
case 2:
switch (image->Format) {
case GL_RGB:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3;
stride = (image->Width - width) * 3;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) |
( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 );
src += 6;
}
src += stride;
}
break;
case GL_RGBA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4;
stride = (image->Width - width) * 4;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) |
( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 );
src += 8;
}
src += stride;
}
break;
case GL_LUMINANCE:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
/* FIXME: should probably use 555 texture to get true grey */
*destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) |
( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_INTENSITY:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) |
( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) |
( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_LUMINANCE_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
stride = (image->Width - width) * 2;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) |
( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 );
src += 4;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
case 4:
switch (image->Format) {
case GL_RGB:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3;
stride = (image->Width - width) * 3;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255);
src += 3;
}
src += stride;
}
break;
case GL_RGBA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4;
stride = (image->Width - width) * 4;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]);
src += 4;
}
src += stride;
}
break;
case GL_LUMINANCE:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255);
src += 1;
}
src += stride;
}
break;
case GL_INTENSITY:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]);
src += 1;
}
src += stride;
}
break;
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]);
src += 1;
}
src += stride;
}
break;
case GL_LUMINANCE_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
stride = (image->Width - width) * 2;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {
*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],
src[0],src[1]);
src += 2;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
default:
goto format_error;
}
return;
format_error:
fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n",
(int)texelBytes, (int)image->Format );
}

View File

@@ -0,0 +1,564 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.7 2002/10/30 12:51:36 alanh Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include <GL/gl.h>
#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"
#include "mgaregs.h"
#include "mgaioctl.h"
//#include "mem.h"
#include "simple_list.h"
static void
mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
{
if (t->MemBlock) {
mmFreeMem(t->MemBlock);
t->MemBlock = 0;
if (t->age > mmesa->dirtyAge)
mmesa->dirtyAge = t->age;
}
t->dirty_images = ~0;
move_to_tail(&(mmesa->SwappedOut), t);
}
static void
mgaPrintLocalLRU( mgaContextPtr mmesa, int heap )
{
mgaTextureObjectPtr t;
int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
fprintf(stderr, "\nLocal LRU, heap %d:\n", heap);
foreach( t, &(mmesa->TexObjList[heap]) ) {
if (!t->tObj)
fprintf(stderr, "Placeholder %d at %x sz %x\n",
t->MemBlock->ofs / sz,
t->MemBlock->ofs,
t->MemBlock->size);
else
fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
t->bound,
t->MemBlock->ofs,
t->MemBlock->size);
}
fprintf(stderr, "\n\n");
}
static void
mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap )
{
int i, j;
drmTextureRegion *list = mmesa->sarea->texList[heap];
fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list);
for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_NR_TEX_REGIONS ; i++) {
fprintf(stderr, "list[%d] age %d next %d prev %d\n",
j, list[j].age, list[j].next, list[j].prev);
j = list[j].next;
if (j == MGA_NR_TEX_REGIONS) break;
}
if (j != MGA_NR_TEX_REGIONS) {
fprintf(stderr, "Loop detected in global LRU\n\n\n");
for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) {
fprintf(stderr, "list[%d] age %d next %d prev %d\n",
i, list[i].age, list[i].next, list[i].prev);
}
}
fprintf(stderr, "\n\n");
}
static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap )
{
drmTextureRegion *list = mmesa->sarea->texList[heap];
int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap];
int i;
mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap);
/* (Re)initialize the global circular LRU list. The last element
* in the array (MGA_NR_TEX_REGIONS) is the sentinal. Keeping it
* at the end of the array allows it to be addressed rationally
* when looking up objects at a particular location in texture
* memory.
*/
for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) {
list[i].prev = i-1;
list[i].next = i+1;
list[i].age = mmesa->sarea->texAge[heap];
}
i--;
list[0].prev = MGA_NR_TEX_REGIONS;
list[i].prev = i-1;
list[i].next = MGA_NR_TEX_REGIONS;
list[MGA_NR_TEX_REGIONS].prev = i;
list[MGA_NR_TEX_REGIONS].next = 0;
}
static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
int i;
int heap = t->heap;
int logsz = mmesa->mgaScreen->logTextureGranularity[heap];
int start = t->MemBlock->ofs >> logsz;
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
drmTextureRegion *list = mmesa->sarea->texList[heap];
mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
if (!t->MemBlock) {
fprintf(stderr, "no memblock\n\n");
return;
}
/* Update our local LRU
*/
move_to_head( &(mmesa->TexObjList[heap]), t );
if (0)
fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list);
/* Update the global LRU
*/
for (i = start ; i <= end ; i++) {
list[i].in_use = 1;
list[i].age = mmesa->texAge[heap];
/* remove_from_list(i)
*/
list[(unsigned)list[i].next].prev = list[i].prev;
list[(unsigned)list[i].prev].next = list[i].next;
/* insert_at_head(list, i)
*/
list[i].prev = MGA_NR_TEX_REGIONS;
list[i].next = list[MGA_NR_TEX_REGIONS].next;
list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i;
list[MGA_NR_TEX_REGIONS].next = i;
}
if (0) {
mgaPrintGlobalLRU(mmesa, t->heap);
mgaPrintLocalLRU(mmesa, t->heap);
}
}
/* Called for every shared texture region which has increased in age
* since we last held the lock.
*
* Figures out which of our textures have been ejected by other clients,
* and pushes a placeholder texture onto the LRU list to represent
* the other client's textures.
*/
static void mgaTexturesGone( mgaContextPtr mmesa,
GLuint heap,
GLuint offset,
GLuint size,
GLuint in_use )
{
mgaTextureObjectPtr t, tmp;
foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) {
if (t->MemBlock->ofs >= offset + size ||
t->MemBlock->ofs + t->MemBlock->size <= offset)
continue;
/* It overlaps - kick it off. Need to hold onto the currently bound
* objects, however.
*/
if (t->bound)
mgaSwapOutTexObj( mmesa, t );
else
mgaDestroyTexObj( mmesa, t );
}
if (in_use) {
t = (mgaTextureObjectPtr) calloc(1, sizeof(*t));
if (!t) return;
t->heap = heap;
t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset);
if (!t->MemBlock) {
fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
(int)size, (int)offset);
mmDumpMemInfo( mmesa->texHeap[heap]);
return;
}
insert_at_head( &(mmesa->TexObjList[heap]), t );
}
}
void mgaAgeTextures( mgaContextPtr mmesa, int heap )
{
MGASAREAPrivPtr sarea = mmesa->sarea;
int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
int idx, nr = 0;
/* Have to go right round from the back to ensure stuff ends up
* LRU in our local list... Fix with a cursor pointer.
*/
for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ;
idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
idx = sarea->texList[heap][idx].prev, nr++)
{
/* If switching texturing schemes, then the SAREA might not
* have been properly cleared, so we need to reset the
* global texture LRU.
*/
if ( idx * sz > mmesa->mgaScreen->textureSize[heap] ) {
nr = MGA_NR_TEX_REGIONS;
break;
}
if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) {
mgaTexturesGone(mmesa, heap, idx * sz, sz,
sarea->texList[heap][idx].in_use);
}
}
if (nr == MGA_NR_TEX_REGIONS) {
mgaTexturesGone(mmesa, heap, 0,
mmesa->mgaScreen->textureSize[heap], 0);
mgaResetGlobalLRU( mmesa, heap );
}
if (0) {
mgaPrintGlobalLRU( mmesa, heap );
mgaPrintLocalLRU( mmesa, heap );
}
mmesa->texAge[heap] = sarea->texAge[heap];
mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
}
/*
* mgaUploadSubImageLocked
*
* Perform an iload based update of a resident buffer. This is used for
* both initial loading of the entire image, and texSubImage updates.
*
* Performed with the hardware lock held.
*/
void mgaUploadSubImageLocked( mgaContextPtr mmesa,
mgaTextureObjectPtr t,
int level,
int x, int y, int width, int height )
{
int x2;
int dwords;
int offset;
struct gl_texture_image *image;
int texelBytes, texelsPerDword, texelMaccess, length;
if ( level < 0 || level >= MGA_TEX_MAXLEVELS )
return;
image = t->tObj->Image[level];
if ( !image ) return;
if (image->Data == 0) {
fprintf(stderr, "null texture image data tObj %p level %d\n",
t->tObj, level);
return;
}
/* find the proper destination offset for this level */
offset = (t->MemBlock->ofs +
t->offsets[level]);
texelBytes = t->texelBytes;
switch( texelBytes ) {
case 1:
texelsPerDword = 4;
texelMaccess = 0;
break;
case 2:
texelsPerDword = 2;
texelMaccess = 1;
break;
case 4:
texelsPerDword = 1;
texelMaccess = 2;
break;
default:
return;
}
/* We can't do a subimage update if pitch is < 32 texels due
* to hardware XY addressing limits, so we will need to
* linearly upload all modified rows.
*/
if ( image->Width < 32 ) {
x = 0;
width = image->Width * height;
height = 1;
/* Assume that 1x1 textures aren't going to cause a
* bus error if we read up to four texels from that
* location:
*/
/* if ( width < texelsPerDword ) { */
/* width = texelsPerDword; */
/* } */
} else {
/* pad the size out to dwords. The image is a pointer
to the entire image, so we can safely reference
outside the x,y,width,height bounds if we need to */
x2 = x + width;
x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1);
x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1);
width = x2 - x;
}
/* we may not be able to upload the entire texture in one
batch due to register limits or dma buffer limits.
Recursively split it up. */
while ( 1 ) {
dwords = height * width / texelsPerDword;
if ( dwords * 4 <= MGA_BUFFER_SIZE ) {
break;
}
mgaUploadSubImageLocked( mmesa, t, level, x, y,
width, height >> 1 );
y += ( height >> 1 );
height -= ( height >> 1 );
}
length = dwords * 4;
/* Fill in the secondary buffer with properly converted texels
* from the mesa buffer. */
/* FIXME: the sync for direct copy reduces speed.. */
if(t->heap == MGA_CARD_HEAP ) {
mgaGetILoadBufferLocked( mmesa );
mgaConvertTexture( (GLuint *)mmesa->iload_buffer->address,
texelBytes, image, x, y, width, height );
if(length < 64) length = 64;
if (0)
fprintf(stderr, "TexelBytes : %d, offset: %d, length : %d\n",
texelBytes,
mmesa->mgaScreen->textureOffset[t->heap] +
offset +
y * width * 4/texelsPerDword,
length);
mgaFireILoadLocked( mmesa,
mmesa->mgaScreen->textureOffset[t->heap] +
offset +
y * width * 4/texelsPerDword,
length);
} else {
/* This works, is slower for uploads to card space and needs
* additional synchronization with the dma stream.
*/
UPDATE_LOCK(mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT);
mgaConvertTexture( (GLuint *)
(mmesa->mgaScreen->texVirtual[t->heap] +
offset +
y * width * 4/texelsPerDword),
texelBytes, image, x, y, width, height );
}
}
static void mgaUploadTexLevel( mgaContextPtr mmesa,
mgaTextureObjectPtr t,
int l )
{
mgaUploadSubImageLocked( mmesa,
t,
l,
0, 0,
t->tObj->Image[l]->Width,
t->tObj->Image[l]->Height);
}
#if 0
static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
/* NOT DONE */
}
#endif
static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
int freeagp, freecard;
int fitincard, fitinagp;
int totalcard, totalagp;
TMemBlock *b;
totalcard = totalagp = fitincard = fitinagp = freeagp = freecard = 0;
b = mmesa->texHeap[0];
while(b)
{
totalcard += b->size;
if(b->free) if(t->totalSize <= b->size)fitincard = 1;
b = b->next;
}
b = mmesa->texHeap[1];
while(b)
{
totalagp += b->size;
if(b->free) if(t->totalSize <= b->size)fitinagp = 1;
b = b->next;
}
if(fitincard)return 0;
if(fitinagp)return 1;
if(totalcard && totalagp)
{
int ages;
int ratio = (totalcard > totalagp) ? totalcard / totalagp : totalagp / totalcard;
ages = mmesa->sarea->texAge[0] + mmesa->sarea->texAge[1];
if( (ages % ratio) == 0)return totalcard > totalagp ? 1 : 0;
else return totalcard > totalagp ? 0 : 1;
}
if(totalagp) return 1;
return 0;
}
int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
int heap;
int i;
int ofs;
heap = t->heap = mgaChooseTexHeap( mmesa, t );
/* Do we need to eject LRU texture objects?
*/
if (!t->MemBlock) {
while (1)
{
mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev;
t->MemBlock = mmAllocMem( mmesa->texHeap[heap],
t->totalSize,
6, 0 );
if (t->MemBlock)
break;
if (mmesa->TexObjList[heap].prev->bound) {
fprintf(stderr, "Hit bound texture in upload\n");
return -1;
}
if (mmesa->TexObjList[heap].prev ==
&(mmesa->TexObjList[heap]))
{
fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
mmDumpMemInfo( mmesa->texHeap[heap] );
return -1;
}
mgaDestroyTexObj( mmesa, tmp );
}
ofs = t->MemBlock->ofs
+ mmesa->mgaScreen->textureOffset[heap]
;
t->setup.texorg = ofs;
t->setup.texorg1 = ofs + t->offsets[1];
t->setup.texorg2 = ofs + t->offsets[2];
t->setup.texorg3 = ofs + t->offsets[3];
t->setup.texorg4 = ofs + t->offsets[4];
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
/* Let the world know we've used this memory recently.
*/
mgaUpdateTexLRU( mmesa, t );
if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge);
if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa))
mgaWaitAgeLocked( mmesa, mmesa->dirtyAge );
if (t->dirty_images) {
if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
fprintf(stderr, "*");
for (i = 0 ; i <= t->lastLevel ; i++)
if (t->dirty_images & (1<<i))
mgaUploadTexLevel( mmesa, t, i );
}
t->dirty_images = 0;
return 0;
}

View File

@@ -0,0 +1,915 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.10 2002/10/30 12:51:36 alanh Exp $ */
#include <stdio.h>
#include <math.h>
#include "mtypes.h"
#include "macros.h"
#include "colormac.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "mm.h"
#include "mgacontext.h"
#include "mgaioctl.h"
#include "mgatris.h"
#include "mgavb.h"
#include "mgastate.h"
static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim );
/***********************************************************************
* Functions to draw basic primitives *
***********************************************************************/
#if defined (USE_X86_ASM)
#define EMIT_VERT( j, vb, vertex_size, v ) \
do { int __tmp; \
__asm__ __volatile__( "rep ; movsl" \
: "=%c" (j), "=D" (vb), "=S" (__tmp) \
: "0" (vertex_size), \
"D" ((long)vb), \
"S" ((long)v)); \
} while (0)
#else
#define EMIT_VERT( j, vb, vertex_size, v ) \
do { \
for ( j = 0 ; j < vertex_size ; j++ ) \
vb[j] = (v)->ui[j]; \
vb += vertex_size; \
} while (0)
#endif
static void __inline__ mga_draw_triangle( mgaContextPtr mmesa,
mgaVertexPtr v0,
mgaVertexPtr v1,
mgaVertexPtr v2 )
{
GLuint vertex_size = mmesa->vertex_size;
GLuint *vb = mgaAllocDmaLow( mmesa, 3 * 4 * vertex_size );
int j;
EMIT_VERT( j, vb, vertex_size, v0 );
EMIT_VERT( j, vb, vertex_size, v1 );
EMIT_VERT( j, vb, vertex_size, v2 );
}
static void __inline__ mga_draw_quad( mgaContextPtr mmesa,
mgaVertexPtr v0,
mgaVertexPtr v1,
mgaVertexPtr v2,
mgaVertexPtr v3 )
{
GLuint vertex_size = mmesa->vertex_size;
GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
int j;
EMIT_VERT( j, vb, vertex_size, v0 );
EMIT_VERT( j, vb, vertex_size, v1 );
EMIT_VERT( j, vb, vertex_size, v3 );
EMIT_VERT( j, vb, vertex_size, v1 );
EMIT_VERT( j, vb, vertex_size, v2 );
EMIT_VERT( j, vb, vertex_size, v3 );
}
static __inline__ void mga_draw_point( mgaContextPtr mmesa,
mgaVertexPtr tmp )
{
GLfloat sz = mmesa->glCtx->Point._Size * .5;
int vertex_size = mmesa->vertex_size;
GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
int j;
#if 0
v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET;
v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET;
#endif
/* Draw a point as two triangles.
*/
*(float *)&vb[0] = tmp->v.x - sz;
*(float *)&vb[1] = tmp->v.y - sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
vb += vertex_size;
*(float *)&vb[0] = tmp->v.x + sz;
*(float *)&vb[1] = tmp->v.y - sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
vb += vertex_size;
*(float *)&vb[0] = tmp->v.x + sz;
*(float *)&vb[1] = tmp->v.y + sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
vb += vertex_size;
*(float *)&vb[0] = tmp->v.x + sz;
*(float *)&vb[1] = tmp->v.y + sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
vb += vertex_size;
*(float *)&vb[0] = tmp->v.x - sz;
*(float *)&vb[1] = tmp->v.y + sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
vb += vertex_size;
*(float *)&vb[0] = tmp->v.x - sz;
*(float *)&vb[1] = tmp->v.y - sz;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = tmp->ui[j];
#if 0
v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET;
v0->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET;
#endif
}
static __inline__ void mga_draw_line( mgaContextPtr mmesa,
mgaVertexPtr v0,
mgaVertexPtr v1 )
{
GLuint vertex_size = mmesa->vertex_size;
GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
GLfloat dx, dy, ix, iy;
GLfloat width = mmesa->glCtx->Line._Width;
GLint j;
#if 0
v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
#endif
dx = v0->v.x - v1->v.x;
dy = v0->v.y - v1->v.y;
ix = width * .5; iy = 0;
if (dx * dx > dy * dy) {
iy = ix; ix = 0;
}
*(float *)&vb[0] = v0->v.x - ix;
*(float *)&vb[1] = v0->v.y - iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v0->ui[j];
vb += vertex_size;
*(float *)&vb[0] = v1->v.x + ix;
*(float *)&vb[1] = v1->v.y + iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v1->ui[j];
vb += vertex_size;
*(float *)&vb[0] = v0->v.x + ix;
*(float *)&vb[1] = v0->v.y + iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v0->ui[j];
vb += vertex_size;
*(float *)&vb[0] = v0->v.x - ix;
*(float *)&vb[1] = v0->v.y - iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v0->ui[j];
vb += vertex_size;
*(float *)&vb[0] = v1->v.x - ix;
*(float *)&vb[1] = v1->v.y - iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v1->ui[j];
vb += vertex_size;
*(float *)&vb[0] = v1->v.x + ix;
*(float *)&vb[1] = v1->v.y + iy;
for (j = 2 ; j < vertex_size ; j++)
vb[j] = v1->ui[j];
vb += vertex_size;
#if 0
v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
#endif
}
/***********************************************************************
* Macros for t_dd_tritmp.h to draw basic primitives *
***********************************************************************/
#define TRI( a, b, c ) \
do { \
if (DO_FALLBACK) \
mmesa->draw_tri( mmesa, a, b, c ); \
else \
mga_draw_triangle( mmesa, a, b, c ); \
} while (0)
#define QUAD( a, b, c, d ) \
do { \
if (DO_FALLBACK) { \
mmesa->draw_tri( mmesa, a, b, d ); \
mmesa->draw_tri( mmesa, b, c, d ); \
} else { \
mga_draw_quad( mmesa, a, b, c, d ); \
} \
} while (0)
#define LINE( v0, v1 ) \
do { \
if (DO_FALLBACK) \
mmesa->draw_line( mmesa, v0, v1 ); \
else { \
mga_draw_line( mmesa, v0, v1 ); \
} \
} while (0)
#define POINT( v0 ) \
do { \
if (DO_FALLBACK) \
mmesa->draw_point( mmesa, v0 ); \
else { \
mga_draw_point( mmesa, v0 ); \
} \
} while (0)
/***********************************************************************
* Fallback to swrast for basic primitives *
***********************************************************************/
/* This code is hit only when a mix of accelerated and unaccelerated
* primitives are being drawn, and only for the unaccelerated
* primitives.
*/
static void
mga_fallback_tri( mgaContextPtr mmesa,
mgaVertex *v0,
mgaVertex *v1,
mgaVertex *v2 )
{
GLcontext *ctx = mmesa->glCtx;
SWvertex v[3];
mga_translate_vertex( ctx, v0, &v[0] );
mga_translate_vertex( ctx, v1, &v[1] );
mga_translate_vertex( ctx, v2, &v[2] );
_swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
}
static void
mga_fallback_line( mgaContextPtr mmesa,
mgaVertex *v0,
mgaVertex *v1 )
{
GLcontext *ctx = mmesa->glCtx;
SWvertex v[2];
mga_translate_vertex( ctx, v0, &v[0] );
mga_translate_vertex( ctx, v1, &v[1] );
_swrast_Line( ctx, &v[0], &v[1] );
}
static void
mga_fallback_point( mgaContextPtr mmesa,
mgaVertex *v0 )
{
GLcontext *ctx = mmesa->glCtx;
SWvertex v[1];
mga_translate_vertex( ctx, v0, &v[0] );
_swrast_Point( ctx, &v[0] );
}
/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/
#define MGA_UNFILLED_BIT 0x1
#define MGA_OFFSET_BIT 0x2
#define MGA_TWOSIDE_BIT 0x4
#define MGA_FLAT_BIT 0x8 /* mga can't flatshade? */
#define MGA_FALLBACK_BIT 0x10
#define MGA_MAX_TRIFUNC 0x20
static struct {
points_func points;
line_func line;
triangle_func triangle;
quad_func quad;
} rast_tab[MGA_MAX_TRIFUNC];
#define DO_FALLBACK (IND & MGA_FALLBACK_BIT)
#define DO_OFFSET (IND & MGA_OFFSET_BIT)
#define DO_UNFILLED (IND & MGA_UNFILLED_BIT)
#define DO_TWOSIDE (IND & MGA_TWOSIDE_BIT)
#define DO_FLAT (IND & MGA_FLAT_BIT)
#define DO_TRI 1
#define DO_QUAD 1
#define DO_LINE 1
#define DO_POINTS 1
#define DO_FULL_QUAD 1
#define HAVE_RGBA 1
#define HAVE_BACK_COLORS 0
#define HAVE_SPEC 1
#define HAVE_HW_FLATSHADE 0
#define VERTEX mgaVertex
#define TAB rast_tab
#define MGA_COLOR( dst, src ) \
do { \
dst[0] = src[2]; \
dst[1] = src[1]; \
dst[2] = src[0]; \
dst[3] = src[3]; \
} while (0)
#define MGA_SPEC( dst, src ) \
do { \
dst[0] = src[2]; \
dst[1] = src[1]; \
dst[2] = src[0]; \
} while (0)
#define DEPTH_SCALE mmesa->depth_scale
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define VERT_X(_v) _v->v.x
#define VERT_Y(_v) _v->v.y
#define VERT_Z(_v) _v->v.z
#define AREA_IS_CCW( a ) (a > 0)
#define GET_VERTEX(e) (mmesa->verts + (e<<mmesa->vertex_stride_shift))
#define VERT_SET_RGBA( v, c ) MGA_COLOR( v->ub4[4], c )
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
#define VERT_SET_SPEC( v, c ) MGA_SPEC( v->ub4[5], c )
#define VERT_COPY_SPEC( v0, v1 ) COPY_3V(v0->ub4[5], v1->ub4[5])
#define VERT_SAVE_SPEC( idx ) spec[idx] = v[idx]->ui[5]
#define VERT_RESTORE_SPEC( idx ) v[idx]->ui[5] = spec[idx]
#define LOCAL_VARS(n) \
mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
GLuint color[n], spec[n]; \
(void) color; (void) spec;
/***********************************************************************
* Functions to draw basic unfilled primitives *
***********************************************************************/
#define RASTERIZE(x) if (mmesa->raster_primitive != x) \
mgaRasterPrimitive( ctx, x, MGA_WA_TRIANGLES )
#define RENDER_PRIMITIVE mmesa->render_primitive
#define IND MGA_FALLBACK_BIT
#define TAG(x) x
#include "tnl_dd/t_dd_unfilled.h"
#undef IND
/***********************************************************************
* Functions to draw GL primitives *
***********************************************************************/
#define IND (0)
#define TAG(x) x
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT)
#define TAG(x) x##_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT)
#define TAG(x) x##_twoside_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
#define TAG(x) x##_twoside_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_FALLBACK_BIT)
#define TAG(x) x##_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_twoside_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
#define TAG(x) x##_twoside_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
MGA_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
/* Mga doesn't support provoking-vertex flat-shading?
*/
#define IND (MGA_FLAT_BIT)
#define TAG(x) x##_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_offset_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_offset_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_UNFILLED_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_unfilled_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_offset_unfilled_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_unfilled_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_offset_unfilled_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_offset_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_offset_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_unfilled_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_offset_unfilled_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_unfilled_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
MGA_FALLBACK_BIT|MGA_FLAT_BIT)
#define TAG(x) x##_twoside_offset_unfilled_fallback_flat
#include "tnl_dd/t_dd_tritmp.h"
static void init_rast_tab( void )
{
init();
init_offset();
init_twoside();
init_twoside_offset();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_twoside_offset_unfilled();
init_fallback();
init_offset_fallback();
init_twoside_fallback();
init_twoside_offset_fallback();
init_unfilled_fallback();
init_offset_unfilled_fallback();
init_twoside_unfilled_fallback();
init_twoside_offset_unfilled_fallback();
init_flat();
init_offset_flat();
init_twoside_flat();
init_twoside_offset_flat();
init_unfilled_flat();
init_offset_unfilled_flat();
init_twoside_unfilled_flat();
init_twoside_offset_unfilled_flat();
init_fallback_flat();
init_offset_fallback_flat();
init_twoside_fallback_flat();
init_twoside_offset_fallback_flat();
init_unfilled_fallback_flat();
init_offset_unfilled_fallback_flat();
init_twoside_unfilled_fallback_flat();
init_twoside_offset_unfilled_fallback_flat();
}
/**********************************************************************/
/* Render whole begin/end objects */
/**********************************************************************/
#define VERT(x) (mgaVertex *)(vertptr + ((x)<<vertshift))
#define RENDER_POINTS( start, count ) \
for ( ; start < count ; start++) \
mga_draw_point( mmesa, VERT(ELT(start)) );
#define RENDER_LINE( v0, v1 ) \
mga_draw_line( mmesa, VERT(v0), VERT(v1) )
#define RENDER_TRI( v0, v1, v2 ) \
mga_draw_triangle( mmesa, VERT(v0), VERT(v1), VERT(v2) )
#define RENDER_QUAD( v0, v1, v2, v3 ) \
mga_draw_quad( mmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
#define INIT(x) mgaRenderPrimitive( ctx, x )
#undef LOCAL_VARS
#define LOCAL_VARS \
mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
GLubyte *vertptr = (GLubyte *)mmesa->verts; \
const GLuint vertshift = mmesa->vertex_stride_shift; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
(void) elt;
#define RESET_STIPPLE
#define RESET_OCCLUSION
#define PRESERVE_VB_DEFS
#define ELT(x) x
#define TAG(x) mga_##x##_verts
#include "tnl/t_vb_rendertmp.h"
#undef ELT
#undef TAG
#define TAG(x) mga_##x##_elts
#define ELT(x) elt[x]
#include "tnl/t_vb_rendertmp.h"
/**********************************************************************/
/* Render clipped primitives */
/**********************************************************************/
static void mgaRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint prim = mmesa->render_primitive;
/* Render the new vertices as an unclipped polygon.
*/
{
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
VB->Elts = tmp;
}
/* Restore the render primitive
*/
if (prim != GL_POLYGON)
tnl->Driver.Render.PrimitiveNotify( ctx, prim );
}
static void mgaRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line( ctx, ii, jj );
}
static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint vertex_size = mmesa->vertex_size;
GLuint *vb = mgaAllocDmaLow( mmesa, (n-2) * 3 * 4 * vertex_size );
GLubyte *vertptr = (GLubyte *)mmesa->verts;
const GLuint vertshift = mmesa->vertex_stride_shift;
const GLuint *start = (const GLuint *)VERT(elts[0]);
int i,j;
for (i = 2 ; i < n ; i++) {
EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i-1]) );
EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i]) );
EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start );
}
}
/**********************************************************************/
/* Choose render functions */
/**********************************************************************/
#define _MGA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_DD_NEW_TRI_OFFSET | \
_DD_NEW_TRI_STIPPLE | \
_NEW_POLYGONSTIPPLE)
#define POINT_FALLBACK (DD_POINT_SMOOTH)
#define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE)
#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED)
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK| \
DD_TRI_STIPPLE)
#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \
DD_TRI_UNFILLED)
static void mgaChooseRenderState(GLcontext *ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint index = 0;
if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
if (flags & ANY_RASTER_FLAGS) {
if (flags & DD_TRI_LIGHT_TWOSIDE) index |= MGA_TWOSIDE_BIT;
if (flags & DD_TRI_OFFSET) index |= MGA_OFFSET_BIT;
if (flags & DD_TRI_UNFILLED) index |= MGA_UNFILLED_BIT;
if (flags & DD_FLATSHADE) index |= MGA_FLAT_BIT;
}
mmesa->draw_point = mga_draw_point;
mmesa->draw_line = mga_draw_line;
mmesa->draw_tri = mga_draw_triangle;
/* Hook in fallbacks for specific primitives.
*/
if (flags & ANY_FALLBACK_FLAGS)
{
if (flags & POINT_FALLBACK)
mmesa->draw_point = mga_fallback_point;
if (flags & LINE_FALLBACK)
mmesa->draw_line = mga_fallback_line;
if (flags & TRI_FALLBACK)
mmesa->draw_tri = mga_fallback_tri;
if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple)
mmesa->draw_tri = mga_fallback_tri;
index |= MGA_FALLBACK_BIT;
}
}
if (mmesa->RenderIndex != index) {
mmesa->RenderIndex = index;
tnl->Driver.Render.Points = rast_tab[index].points;
tnl->Driver.Render.Line = rast_tab[index].line;
tnl->Driver.Render.Triangle = rast_tab[index].triangle;
tnl->Driver.Render.Quad = rast_tab[index].quad;
if (index == 0) {
tnl->Driver.Render.PrimTabVerts = mga_render_tab_verts;
tnl->Driver.Render.PrimTabElts = mga_render_tab_elts;
tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
tnl->Driver.Render.ClippedPolygon = mgaFastRenderClippedPoly;
} else {
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ClippedLine = mgaRenderClippedLine;
tnl->Driver.Render.ClippedPolygon = mgaRenderClippedPoly;
}
}
}
/**********************************************************************/
/* Runtime render state and callbacks */
/**********************************************************************/
static void mgaRunPipeline( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (mmesa->new_state) {
mgaDDUpdateHwState( ctx );
}
if (!mmesa->Fallback && mmesa->new_gl_state) {
if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP)
mgaChooseVertexState( ctx );
if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE)
mgaChooseRenderState( ctx );
mmesa->new_gl_state = 0;
/* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback,
* but mgaChooseVertexState can affect mmesa->new_state. Hence
* the second check. (Fix this...)
*/
if (mmesa->new_state) {
mgaDDUpdateHwState( ctx );
}
}
_tnl_run_pipeline( ctx );
}
static GLenum reduced_prim[GL_POLYGON+1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
/* Always called between RenderStart and RenderFinish --> We already
* hold the lock.
*/
void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
FLUSH_BATCH( mmesa );
mmesa->raster_primitive = prim;
/* mmesa->hw_primitive = hwprim; */
mmesa->hw_primitive = MGA_WA_TRIANGLES; /* disable mgarender.c for now */
mgaUpdateCull(ctx);
if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple)
{
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
if (mmesa->raster_primitive == GL_TRIANGLES)
mmesa->setup.dwgctl |= mmesa->poly_stipple;
else
mmesa->setup.dwgctl &= ~(0xf<<20);
}
}
/* Determine the rasterized primitive when not drawing unfilled
* polygons.
*
* Used only for the default render stage which always decomposes
* primitives to trianges/lines/points. For the accelerated stage,
* which renders strips as strips, the equivalent calculations are
* performed in mgarender.c.
*/
static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint rprim = reduced_prim[prim];
mmesa->render_primitive = prim;
if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
if (mmesa->raster_primitive != rprim) {
mgaRasterPrimitive( ctx, rprim, MGA_WA_TRIANGLES );
}
}
static void mgaRenderFinish( GLcontext *ctx )
{
if (MGA_CONTEXT(ctx)->RenderIndex & MGA_FALLBACK_BIT)
_swrast_flush( ctx );
}
/**********************************************************************/
/* Manage total rasterization fallbacks */
/**********************************************************************/
void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint oldfallback = mmesa->Fallback;
if (mode) {
mmesa->Fallback |= bit;
if (oldfallback == 0) {
FLUSH_BATCH(mmesa);
_swsetup_Wakeup( ctx );
mmesa->RenderIndex = ~0;
}
}
else {
mmesa->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
tnl->Driver.Render.Start = mgaCheckTexSizes;
tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive;
tnl->Driver.Render.Finish = mgaRenderFinish;
tnl->Driver.Render.BuildVertices = mgaBuildVertices;
mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE |
_MGA_NEW_RASTERSETUP);
}
}
}
void mgaDDInitTriFuncs( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
static int firsttime = 1;
if (firsttime) {
init_rast_tab();
firsttime = 0;
}
mmesa->RenderIndex = ~0;
tnl->Driver.RunPipeline = mgaRunPipeline;
tnl->Driver.Render.Start = mgaCheckTexSizes;
tnl->Driver.Render.Finish = mgaRenderFinish;
tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.BuildVertices = mgaBuildVertices;
tnl->Driver.Render.Multipass = NULL;
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.10 2002/10/30 12:51:36 alanh Exp $ */
#ifndef MGATRIS_INC
#define MGATRIS_INC
#include "mtypes.h"
extern void mgaDDInitTriFuncs( GLcontext *ctx );
extern void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim );
extern void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( ctx, bit, mode ) mgaFallback( ctx, bit, mode )
#endif

View File

@@ -0,0 +1,497 @@
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.15 2003/03/26 20:43:49 tsi Exp $ */
#include "mgacontext.h"
#include "mgavb.h"
#include "mgatris.h"
#include "mgaioctl.h"
#include "mga_xmesa.h"
#include "glheader.h"
#include "mtypes.h"
//#include "mem.h"
#include "macros.h"
#include "colormac.h"
#include "mmath.h"
#include "tnl/t_context.h"
#include "swrast_setup/swrast_setup.h"
#include "swrast/swrast.h"
#include <stdio.h>
#include <stdlib.h>
#define MGA_TEX1_BIT 0x1
#define MGA_TEX0_BIT 0x2
#define MGA_RGBA_BIT 0x4
#define MGA_SPEC_BIT 0x8
#define MGA_FOG_BIT 0x10
#define MGA_XYZW_BIT 0x20
#define MGA_PTEX_BIT 0x40
#define MGA_MAX_SETUP 0x80
static struct {
void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
interp_func interp;
copy_pv_func copy_pv;
GLboolean (*check_tex_sizes)( GLcontext *ctx );
GLuint vertex_size;
GLuint vertex_stride_shift;
GLuint vertex_format;
} setup_tab[MGA_MAX_SETUP];
#define TINY_VERTEX_FORMAT 0
#define NOTEX_VERTEX_FORMAT 0
#define TEX0_VERTEX_FORMAT (MGA_A|MGA_S|MGA_F)
#define TEX1_VERTEX_FORMAT (MGA_A|MGA_S|MGA_F|MGA_T2)
#define PROJ_TEX1_VERTEX_FORMAT 0
#define TEX2_VERTEX_FORMAT 0
#define TEX3_VERTEX_FORMAT 0
#define PROJ_TEX3_VERTEX_FORMAT 0
#define DO_XYZW (IND & MGA_XYZW_BIT)
#define DO_RGBA (IND & MGA_RGBA_BIT)
#define DO_SPEC (IND & MGA_SPEC_BIT)
#define DO_FOG (IND & MGA_FOG_BIT)
#define DO_TEX0 (IND & MGA_TEX0_BIT)
#define DO_TEX1 (IND & MGA_TEX1_BIT)
#define DO_TEX2 0
#define DO_TEX3 0
#define DO_PTEX (IND & MGA_PTEX_BIT)
#define VERTEX mgaVertex
#define VERTEX_COLOR mga_color_t
#define LOCALVARS mgaContextPtr mmesa = MGA_CONTEXT(ctx);
#define GET_VIEWPORT_MAT() mmesa->hw_viewport
#define GET_TEXSOURCE(n) mmesa->tmu_source[n]
#define GET_VERTEX_FORMAT() mmesa->vertex_format
#define GET_VERTEX_STORE() ((GLubyte *)mmesa->verts)
#define GET_VERTEX_STRIDE_SHIFT() mmesa->vertex_stride_shift
#define GET_UBYTE_COLOR_STORE() &mmesa->UbyteColor
#define GET_UBYTE_SPEC_COLOR_STORE() &mmesa->UbyteSecondaryColor
#define HAVE_HW_VIEWPORT 0
#define HAVE_HW_DIVIDE 0
#define HAVE_RGBA_COLOR 0
#define HAVE_TINY_VERTICES 0
#define HAVE_NOTEX_VERTICES 0
#define HAVE_TEX0_VERTICES 1
#define HAVE_TEX1_VERTICES 1
#define HAVE_TEX2_VERTICES 0
#define HAVE_TEX3_VERTICES 0
#define HAVE_PTEX_VERTICES 0
#define UNVIEWPORT_VARS \
const GLfloat dx = - mmesa->drawX - SUBPIXEL_X; \
const GLfloat dy = (mmesa->driDrawable->h + \
mmesa->drawY + SUBPIXEL_Y); \
const GLfloat sz = 1.0 / mmesa->depth_scale
#define UNVIEWPORT_X(x) x + dx;
#define UNVIEWPORT_Y(y) - y + dy;
#define UNVIEWPORT_Z(z) z * sz;
#define PTEX_FALLBACK() FALLBACK(ctx, MGA_FALLBACK_TEXTURE, 1)
#define IMPORT_FLOAT_COLORS mga_import_float_colors
#define IMPORT_FLOAT_SPEC_COLORS mga_import_float_spec_colors
#define INTERP_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].interp
#define COPY_PV_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].copy_pv
/***********************************************************************
* Generate pv-copying and translation functions *
***********************************************************************/
#define TAG(x) mga_##x
#include "tnl_dd/t_dd_vb.c"
/***********************************************************************
* Generate vertex emit and interp functions *
***********************************************************************/
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT)
#define TAG(x) x##_wg
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT)
#define TAG(x) x##_wgs
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_wgt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_wgt0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
#define TAG(x) x##_wgpt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_wgst0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_wgst0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
#define TAG(x) x##_wgspt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT)
#define TAG(x) x##_wgf
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT)
#define TAG(x) x##_wgfs
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_wgft0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_wgft0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
#define TAG(x) x##_wgfpt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_wgfst0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_wgfst0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
#define TAG(x) x##_wgfspt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_TEX0_BIT)
#define TAG(x) x##_t0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_t0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_FOG_BIT)
#define TAG(x) x##_f
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_FOG_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_ft0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_ft0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT)
#define TAG(x) x##_g
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT)
#define TAG(x) x##_gs
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_gt0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_gt0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_gst0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_gst0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT)
#define TAG(x) x##_gf
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT)
#define TAG(x) x##_gfs
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_gft0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_gft0t1
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
#define TAG(x) x##_gfst0
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
#define TAG(x) x##_gfst0t1
#include "tnl_dd/t_dd_vbtmp.h"
static void init_setup_tab( void )
{
init_wg();
init_wgs();
init_wgt0();
init_wgt0t1();
init_wgpt0();
init_wgst0();
init_wgst0t1();
init_wgspt0();
init_wgf();
init_wgfs();
init_wgft0();
init_wgft0t1();
init_wgfpt0();
init_wgfst0();
init_wgfst0t1();
init_wgfspt0();
init_t0();
init_t0t1();
init_f();
init_ft0();
init_ft0t1();
init_g();
init_gs();
init_gt0();
init_gt0t1();
init_gst0();
init_gst0t1();
init_gf();
init_gfs();
init_gft0();
init_gft0t1();
init_gfst0();
init_gfst0t1();
}
void mgaPrintSetupFlags(char *msg, GLuint flags )
{
fprintf(stderr, "%s: %d %s%s%s%s%s%s\n",
msg,
(int)flags,
(flags & MGA_XYZW_BIT) ? " xyzw," : "",
(flags & MGA_RGBA_BIT) ? " rgba," : "",
(flags & MGA_SPEC_BIT) ? " spec," : "",
(flags & MGA_FOG_BIT) ? " fog," : "",
(flags & MGA_TEX0_BIT) ? " tex-0," : "",
(flags & MGA_TEX1_BIT) ? " tex-1," : "");
}
void mgaCheckTexSizes( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
/*fprintf(stderr, "%s\n", __FUNCTION__);*/
if (!setup_tab[mmesa->SetupIndex].check_tex_sizes(ctx)) {
mmesa->SetupIndex |= MGA_PTEX_BIT;
mmesa->SetupNewInputs = ~0;
if (!mmesa->Fallback &&
!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
tnl->Driver.Render.Interp = setup_tab[mmesa->SetupIndex].interp;
tnl->Driver.Render.CopyPV = setup_tab[mmesa->SetupIndex].copy_pv;
}
}
}
void mgaBuildVertices( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLubyte *v = ((GLubyte *)mmesa->verts + (start<<mmesa->vertex_stride_shift));
GLuint stride = 1<<mmesa->vertex_stride_shift;
newinputs |= mmesa->SetupNewInputs;
mmesa->SetupNewInputs = 0;
if (!newinputs)
return;
if (newinputs & VERT_BIT_CLIP) {
setup_tab[mmesa->SetupIndex].emit( ctx, start, count, v, stride );
} else {
GLuint ind = 0;
if (newinputs & VERT_BIT_COLOR0)
ind |= MGA_RGBA_BIT;
if (newinputs & VERT_BIT_COLOR1)
ind |= MGA_SPEC_BIT;
if (newinputs & VERT_BIT_TEX0)
ind |= MGA_TEX0_BIT;
if (newinputs & VERT_BIT_TEX1)
ind |= MGA_TEX0_BIT|MGA_TEX1_BIT;
if (newinputs & VERT_BIT_FOG)
ind |= MGA_FOG_BIT;
if (mmesa->SetupIndex & MGA_PTEX_BIT)
ind = ~0;
ind &= mmesa->SetupIndex;
if (ind) {
setup_tab[ind].emit( ctx, start, count, v, stride );
}
}
}
void mgaChooseVertexState( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint ind = MGA_XYZW_BIT|MGA_RGBA_BIT;
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
ind |= MGA_SPEC_BIT;
if (ctx->Fog.Enabled)
ind |= MGA_FOG_BIT;
if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
ind |= MGA_TEX1_BIT|MGA_TEX0_BIT;
}
else {
ind |= MGA_TEX0_BIT;
}
}
else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
ind |= MGA_TEX0_BIT;
}
mmesa->SetupIndex = ind;
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = mga_interp_extras;
tnl->Driver.Render.CopyPV = mga_copy_pv_extras;
} else {
tnl->Driver.Render.Interp = setup_tab[ind].interp;
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
}
if (setup_tab[ind].vertex_format != mmesa->vertex_format) {
FLUSH_BATCH(mmesa);
mmesa->new_state |= MGA_NEW_WARP;
mmesa->dirty |= MGA_UPLOAD_PIPE;
mmesa->vertex_format = setup_tab[ind].vertex_format;
mmesa->vertex_size = setup_tab[ind].vertex_size;
mmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
}
}
void mga_emit_contiguous_verts( GLcontext *ctx,
GLuint start,
GLuint count )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint vertex_size = mmesa->vertex_size * 4;
GLuint *dest = mgaAllocDmaLow( mmesa, (count-start) * vertex_size);
setup_tab[mmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
}
void mgaInitVB( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
mmesa->verts = (char *)ALIGN_MALLOC(size * sizeof(mgaVertex), 32);
{
static int firsttime = 1;
if (firsttime) {
init_setup_tab();
firsttime = 0;
}
}
mmesa->new_state |= MGA_NEW_WARP;
mmesa->dirty |= MGA_UPLOAD_PIPE;
mmesa->vertex_format = setup_tab[0].vertex_format;
mmesa->vertex_size = setup_tab[0].vertex_size;
mmesa->vertex_stride_shift = setup_tab[0].vertex_stride_shift;
}
void mgaFreeVB( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
if (mmesa->verts) {
ALIGN_FREE(mmesa->verts);
mmesa->verts = 0;
}
if (mmesa->UbyteSecondaryColor.Ptr) {
ALIGN_FREE(mmesa->UbyteSecondaryColor.Ptr);
mmesa->UbyteSecondaryColor.Ptr = 0;
}
if (mmesa->UbyteColor.Ptr) {
ALIGN_FREE(mmesa->UbyteColor.Ptr);
mmesa->UbyteColor.Ptr = 0;
}
}

View File

@@ -0,0 +1,65 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.8 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 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
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef MGAVB_INC
#define MGAVB_INC
#include "mtypes.h"
#include "mgacontext.h"
#include "swrast/swrast.h"
#define _MGA_NEW_RASTERSETUP (_NEW_TEXTURE | \
_DD_NEW_SEPARATE_SPECULAR | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_NEW_FOG)
extern void mgaChooseVertexState( GLcontext *ctx );
extern void mgaCheckTexSizes( GLcontext *ctx );
extern void mgaBuildVertices( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs );
extern void mgaPrintSetupFlags(char *msg, GLuint flags );
extern void mgaInitVB( GLcontext *ctx );
extern void mgaFreeVB( GLcontext *ctx );
extern void mga_emit_contiguous_verts( GLcontext *ctx,
GLuint start,
GLuint count );
extern void mga_translate_vertex(GLcontext *ctx,
const mgaVertex *src,
SWvertex *dst);
extern void mga_print_vertex( GLcontext *ctx, const mgaVertex *v );
#endif

View File

@@ -0,0 +1,114 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.85 2002/12/16 16:19:17 dawes Exp $ */
/*
* MGA Millennium (MGA2064W) functions
*
* Copyright 1996 The XFree86 Project, Inc.
*
* Authors
* Dirk Hohndel
* hohndel@XFree86.Org
* David Dawes
* dawes@XFree86.Org
*/
#ifndef MGA_H
#define MGA_H
#include "xf86drm.h"
#define PCI_CHIP_MGA2085 0x0518
#define PCI_CHIP_MGA2064 0x0519
#define PCI_CHIP_MGA1064 0x051A
#define PCI_CHIP_MGA2164 0x051B
#define PCI_CHIP_MGA2164_AGP 0x051F
#define PCI_CHIP_MGAG200_PCI 0x0520
#define PCI_CHIP_MGAG200 0x0521
#define PCI_CHIP_MGAG400 0x0525
#define PCI_CHIP_MGAG550 0x2527
#define PCI_CHIP_MGAG100_PCI 0x1000
#define PCI_CHIP_MGAG100 0x1001
# define MMIO_IN8(base, offset) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset))
# define MMIO_IN16(base, offset) \
*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset))
# define MMIO_IN32(base, offset) \
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset))
# define MMIO_OUT8(base, offset, val) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val)
# define MMIO_OUT16(base, offset, val) \
*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) = (val)
# define MMIO_OUT32(base, offset, val) \
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = (val)
#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr)
#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr)
#define INREG(addr) MMIO_IN32(pMga->IOBase, addr)
#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val)
#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val)
#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val)
#define MGAIOMAPSIZE 0x00004000
typedef struct {
int Chipset; /**< \brief Chipset number */
int irq; /**< \brief IRQ number */
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 logTextureGranularity;
/**
* \name AGP
*/
/*@{*/
drmSize agpSize; /**< \brief AGP map size */
int agpMode; /**< \brief AGP mode */
/*@}*/
drmRegion agp;
/* PCI mappings */
drmRegion registers;
drmRegion status;
/* AGP mappings */
drmRegion warp;
drmRegion primary;
drmRegion buffers;
drmRegion agpTextures;
drmBufMapPtr drmBuffers;
unsigned long IOAddress;
unsigned char *IOBase;
int HasSDRAM;
__u32 reg_ien;
} MGARec, *MGAPtr;
#define MGA_FRONT 0x1
#define MGA_BACK 0x2
#define MGA_DEPTH 0x4
#define MGA_AGP_1X_MODE 0x01
#define MGA_AGP_2X_MODE 0x02
#define MGA_AGP_4X_MODE 0x04
#define MGA_AGP_MODE_MASK 0x07
#endif

View File

@@ -0,0 +1,143 @@
/* $XConsortium: mga_bios.h /main/2 1996/10/28 04:48:23 kaleb $ */
#ifndef MGA_BIOS_H
#define MGA_BIOS_H
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h,v 1.3 1998/07/25 16:55:51 dawes Exp $ */
/*
* MGABiosInfo - This struct describes the video BIOS info block.
*
* DESCRIPTION
* Do not mess with this, unless you know what you are doing.
* The data lengths and types are critical.
*
* HISTORY
* October 7, 1996 - [aem] Andrew E. Mileski
* This struct was shamelessly stolen from the MGA DDK.
* It has been reformatted, and the data types changed.
*/
typedef struct {
/* Length of this structure in bytes */
__u16 StructLen;
/*
* Unique number identifying the product type
* 0 : MGA-S1P20 (2MB base with 175MHz Ramdac)
* 1 : MGA-S1P21 (2MB base with 220MHz Ramdac)
* 2 : Reserved
* 3 : Reserved
* 4 : MGA-S1P40 (4MB base with 175MHz Ramdac)
* 5 : MGA-S1P41 (4MB base with 220MHz Ramdac)
*/
__u16 ProductID;
/* Serial number of the board */
__u8 SerNo[ 10 ];
/*
* Manufacturing date of the board (at product test)
* Format: yyyy yyym mmmd dddd
*/
__u16 ManufDate;
/* Identification of manufacturing site */
__u16 ManufId;
/*
* Number and revision level of the PCB
* Format: nnnn nnnn nnnr rrrr
* n = PCB number ex:576 (from 0->2047)
* r = PCB revision (from 0->31)
*/
__u16 PCBInfo;
/* Identification of any PMBs */
__u16 PMBInfo;
/*
* Bit 0-7 : Ramdac speed (0=175MHz, 1=220MHz)
* Bit 8-15 : Ramdac type (0=TVP3026, 1=TVP3027)
*/
__u16 RamdacType;
/* Maximum PCLK of the ramdac */
__u16 PclkMax;
/* Maximum LDCLK supported by the WRAM memory */
__u16 LclkMax;
/* Maximum MCLK of base board */
__u16 ClkBase;
/* Maximum MCLK of 4Mb board */
__u16 Clk4MB;
/* Maximum MCLK of 8Mb board */
__u16 Clk8MB;
/* Maximum MCLK of board with multimedia module */
__u16 ClkMod;
/* Diagnostic test pass frequency */
__u16 TestClk;
/* Default VGA mode1 pixel frequency */
__u16 VGAFreq1;
/* Default VGA mode2 pixel frequency */
__u16 VGAFreq2;
/* Date of last BIOS programming/update */
__u16 ProgramDate;
/* Number of times BIOS has been programmed */
__u16 ProgramCnt;
/* Support for up to 32 hardware/software options */
__u32 Options;
/* Support for up to 32 hardware/software features */
__u32 FeatFlag;
/* Definition of VGA mode MCLK */
__u16 VGAClk;
/* Indicate the revision level of this header struct */
__u16 StructRev;
__u16 Reserved[ 3 ];
} MGABiosInfo;
/* from the PINS structure, refer pins info from MGA */
typedef struct tagParamMGA {
__u16 PinID; /* 0 */
__u8 StructLen; /* 2 */
__u8 Rsvd1; /* 3 */
__u16 StructRev; /* 4 */
__u16 ProgramDate; /* 6 */
__u16 ProgramCnt; /* 8 */
__u16 ProductID; /* 10 */
__u8 SerNo[16]; /* 12 */
__u8 PLInfo[6]; /* 28 */
__u16 PCBInfo; /* 34 */
__u32 FeatFlag; /* 36 */
__u8 RamdacType; /* 40 */
__u8 RamdacSpeed; /* 41 */
__u8 PclkMax; /* 42 */
__u8 ClkGE; /* 43 */
__u8 ClkMem; /* 44 */
__u8 Clk4MB; /* 45 */
__u8 Clk8MB; /* 46 */
__u8 ClkMod; /* 47 */
__u8 TestClk; /* 48 */
__u8 VGAFreq1; /* 49 */
__u8 VGAFreq2; /* 50 */
__u8 MCTLWTST; /* 51 */
__u8 VidCtrl; /* 52 */
__u8 Clk12MB; /* 53 */
__u8 Clk16MB; /* 54 */
__u8 Reserved[8]; /* 55-62 */
__u8 PinCheck; /* 63 */
} MGABios2Info;
#endif

View File

@@ -0,0 +1,152 @@
/* mga_common.h -- common header definitions for MGA 2D/3D/DRM suite
*
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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.
*
* Converted to common header format:
* Jens Owen <jens@tungstengraphics.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h,v 1.2 2002/12/16 16:19:18 dawes Exp $
*
*/
#ifndef _MGA_COMMON_H_
#define _MGA_COMMON_H_
/*
* WARNING: If you change any of these defines, make sure to change
* the kernel include file as well (mga_drm.h)
*/
#define DRM_MGA_IDLE_RETRY 2048
#define DRM_MGA_NR_TEX_HEAPS 2
typedef struct {
int installed;
unsigned long phys_addr;
int size;
} drmMGAWarpIndex;
/* Driver specific DRM command indices
* NOTE: these are not OS specific, but they are driver specific
*/
#define DRM_MGA_INIT 0x00
#define DRM_MGA_FLUSH 0x01
#define DRM_MGA_RESET 0x02
#define DRM_MGA_SWAP 0x03
#define DRM_MGA_CLEAR 0x04
#define DRM_MGA_VERTEX 0x05
#define DRM_MGA_INDICES 0x06
#define DRM_MGA_ILOAD 0x07
#define DRM_MGA_BLIT 0x08
#define DRM_MGA_GETPARAM 0x09
typedef struct {
enum {
MGA_INIT_DMA = 0x01,
MGA_CLEANUP_DMA = 0x02
} func;
unsigned long sarea_priv_offset;
int chipset;
int sgram;
unsigned int maccess;
unsigned int fb_cpp;
unsigned int front_offset, front_pitch;
unsigned int back_offset, back_pitch;
unsigned int depth_cpp;
unsigned int depth_offset, depth_pitch;
unsigned int texture_offset[DRM_MGA_NR_TEX_HEAPS];
unsigned int texture_size[DRM_MGA_NR_TEX_HEAPS];
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long status_offset;
unsigned long warp_offset;
unsigned long primary_offset;
unsigned long buffers_offset;
} drmMGAInit;
typedef enum {
DRM_MGA_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
DRM_MGA_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
DRM_MGA_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
DRM_MGA_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_MGA_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
DRM_MGA_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
} drmMGALockFlags;
typedef struct {
int context;
drmMGALockFlags flags;
} drmMGALock;
typedef struct {
int idx;
unsigned int dstorg;
unsigned int length;
} drmMGAIload;
typedef struct {
unsigned int flags;
unsigned int clear_color;
unsigned int clear_depth;
unsigned int color_mask;
unsigned int depth_mask;
} drmMGAClearRec;
typedef struct {
int idx; /* buffer to queue */
int used; /* bytes in use */
int discard; /* client finished with buffer? */
} drmMGAVertex;
typedef struct {
unsigned int planemask;
unsigned int srcorg;
unsigned int dstorg;
int src_pitch, dst_pitch;
int delta_sx, delta_sy;
int delta_dx, delta_dy;
int height, ydir; /* flip image vertically */
int source_pitch, dest_pitch;
} drmMGABlit;
/* 3.1: An ioctl to get parameters that aren't available to the 3d
* client any other way.
*/
#define MGA_PARAM_IRQ_NR 1
typedef struct {
int param;
int *value;
} drmMGAGetParam;
#endif

Some files were not shown because too many files have changed in this diff Show More