Compare commits
84 Commits
embedded-1
...
embedded-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f331ef4d | ||
|
|
ca81dd07b7 | ||
|
|
8dbdb74d8a | ||
|
|
1b3edffdd1 | ||
|
|
12ee43bd7c | ||
|
|
1303475d38 | ||
|
|
56d99c8cdb | ||
|
|
f29b41f2ed | ||
|
|
89d52a0de4 | ||
|
|
b6fb04a81d | ||
|
|
7d55e9abf6 | ||
|
|
1ac609a7df | ||
|
|
00affe74c1 | ||
|
|
f221b8df75 | ||
|
|
45bd335b1c | ||
|
|
6127672e26 | ||
|
|
bb3752a434 | ||
|
|
56c896a2b8 | ||
|
|
afc72872be | ||
|
|
e511f40795 | ||
|
|
a53f53ece3 | ||
|
|
24812b3eaa | ||
|
|
42e0f2ec95 | ||
|
|
e4fcab7a35 | ||
|
|
cd6d79a82c | ||
|
|
a428744286 | ||
|
|
ccc6ef28ca | ||
|
|
3100749dd0 | ||
|
|
980e98d324 | ||
|
|
2204d5bb46 | ||
|
|
67d3c57c46 | ||
|
|
9e24ff7a0a | ||
|
|
e014d794f2 | ||
|
|
a9bd5a6860 | ||
|
|
94643c4780 | ||
|
|
993502aebc | ||
|
|
932e26e8f4 | ||
|
|
54f4c8d1a3 | ||
|
|
277d7a2a85 | ||
|
|
0a98671051 | ||
|
|
a47745e9fd | ||
|
|
69ce6b7db0 | ||
|
|
5d3ab07110 | ||
|
|
1613d48989 | ||
|
|
5a610a1974 | ||
|
|
afb339bf75 | ||
|
|
16ca6f8e93 | ||
|
|
41b5963f8d | ||
|
|
99199c0ece | ||
|
|
368d95a7dc | ||
|
|
0218da1433 | ||
|
|
6cb2411250 | ||
|
|
0d3a504b94 | ||
|
|
bde16645ca | ||
|
|
301f7e4408 | ||
|
|
173441d1a6 | ||
|
|
64b3e2fa16 | ||
|
|
6919c50029 | ||
|
|
a8512f7dda | ||
|
|
70217c70be | ||
|
|
9d4857a816 | ||
|
|
3f00e34097 | ||
|
|
3e48e6fce4 | ||
|
|
d1fa9af224 | ||
|
|
c20d946424 | ||
|
|
ff6068b217 | ||
|
|
ed1b6e98e2 | ||
|
|
b52901eb89 | ||
|
|
cff70d16aa | ||
|
|
bafbdcb703 | ||
|
|
50d1c2c921 | ||
|
|
a1fd12ab84 | ||
|
|
360bec8a6f | ||
|
|
6440630d79 | ||
|
|
02a6f4b56a | ||
|
|
f828410458 | ||
|
|
7b7af467dd | ||
|
|
3101d43a76 | ||
|
|
d95443f030 | ||
|
|
be49c0fef2 | ||
|
|
61d31cab97 | ||
|
|
7067815785 | ||
|
|
ad79ba8208 | ||
|
|
b8cdeaae3a |
@@ -12,7 +12,7 @@
|
||||
<h2>
|
||||
<center>
|
||||
<h3>Tungsten Graphics, Inc.</h3>
|
||||
<h3>February 3, 2003<br>
|
||||
<h3>February 26, 2003<br>
|
||||
</h3>
|
||||
</center>
|
||||
</h2>
|
||||
@@ -623,34 +623,7 @@ Polygon culling is enabled and disabled with the commands <span
|
||||
style="font-weight: bold;">glDisable</span>(GL_CULL_FACE),
|
||||
respectively.<br>
|
||||
<br>
|
||||
<h3>4.3.3 Polygon Fill Mode</h3>
|
||||
The command<br>
|
||||
<br>
|
||||
<div style="margin-left: 40px;">void<span style="font-weight: bold;"><span
|
||||
style="font-weight: bold;"> </span><span style="font-weight: bold;"></span>glPolygonMode</span>(GLenum<span
|
||||
style="font-style: italic;">face</span>, GLenum <span
|
||||
style="font-style: italic;">mode</span>)<br>
|
||||
</div>
|
||||
<br>
|
||||
controls whether polygons are filled, outlined or drawn with a point at
|
||||
each vertex. The <span style="font-style: italic;">face</span>
|
||||
parameter must be GL_FRONT_AND_BACK. The values GL_FRONT and
|
||||
GL_BACK are not permitted by the subset.<br>
|
||||
<br>
|
||||
If <span style="font-style: italic;">mode</span> is GL_FILL then
|
||||
triangles, quadrilaterals and triangles will be filled (the default).
|
||||
If <span style="font-style: italic;">mode</span> is GL_LINE then
|
||||
triangles, quadrilaterals and polygons will be outlined with line
|
||||
segments instead of being filled.<span style="font-weight: bold;"></span>
|
||||
If <span style="font-style: italic;">mode</span> is GL_POINT then
|
||||
triangles, quadrilaterals and polygons will be rendered with a point at
|
||||
each vertex instead of being filled.<span style="font-weight: bold;"></span><br>
|
||||
<br>
|
||||
Any other values for <span style="font-style: italic;">face</span> or <span
|
||||
style="font-style: italic;">mode</span> will raise the error
|
||||
GL_INVALID_ENUM.<br>
|
||||
<br>
|
||||
<h3>4.3.4 Polygon Antialiasing</h3>
|
||||
<h3>4.3.3 Polygon Antialiasing</h3>
|
||||
Polygons may be antialiased in order to smooth their edges.
|
||||
Polygon antialiasing is enabled and disabled with the commands <span
|
||||
style="font-weight: bold;">glEnable</span>(GL_POLYGON_SMOOTH) and <span
|
||||
@@ -688,8 +661,8 @@ are linearly interpolated to produce the fragment colors.<br>
|
||||
<h2>4.5 Bitmap Rasterization</h2>
|
||||
A bitmap is a monochromatic, binary image in which each image element
|
||||
(or pixel) is represented by one bit. Fragments are only generated
|
||||
for the bits (pixels) which are set. Bitmaps are commonly used
|
||||
to draw text (glyphs) and markers.<br>
|
||||
for the bits (pixels) which are set. Bitmaps are commonly used to
|
||||
draw text (glyphs) and markers.<br>
|
||||
<br>
|
||||
A bitmap is drawn with the command<br>
|
||||
<br>
|
||||
@@ -844,6 +817,7 @@ the subset.<br>
|
||||
Polygon commands:<br>
|
||||
<div style="margin-left: 40px; font-weight: bold;">glPolygonStipple<br>
|
||||
glPolygonOffset<br>
|
||||
glPolygonMode<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2762,15 +2736,6 @@ name stack.<br>
|
||||
<td style="vertical-align: top;">Pixel packing row length.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">GL_POLYGON_MODE<br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">2<br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">Current front and back polygon
|
||||
modes: GL_POINT, GL_LINE or GL_FILL.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">GL_POLYGON_SMOOTH<br>
|
||||
</td>
|
||||
@@ -3456,7 +3421,7 @@ number of approaches to antialiasing have been summarized in email.<br>
|
||||
RECOMMENDATION: don't support edge flags. They don't effect
|
||||
polygon antialiasing.<br>
|
||||
<br>
|
||||
RESOLUTION: open<br>
|
||||
RESOLUTION: closed, as of 26 Feb 2003.<br>
|
||||
<br>
|
||||
<h2>A.3 glRasterPos vs. glWindowPos</h2>
|
||||
Should glRasterPos and/or glWindowPos commands be supported?<br>
|
||||
@@ -3601,6 +3566,12 @@ supported.<br>
|
||||
<br>
|
||||
RESOLUTION: open<br>
|
||||
<br>
|
||||
<h2>A.15 glPolygonMode</h2>
|
||||
Is <span style="font-weight: bold;">glPolygonMode</span> needed?<br>
|
||||
<br>
|
||||
RECOMMENDATION: No. Omit it.<br>
|
||||
<br>
|
||||
RESOLUTION: closed, as of 26 Feb 2003<br>
|
||||
<br>
|
||||
<br>
|
||||
<p> </p>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
*.tag
|
||||
array_cache
|
||||
core
|
||||
core_subset
|
||||
math
|
||||
math_subset
|
||||
miniglx
|
||||
radeon_subset
|
||||
swrast
|
||||
|
||||
@@ -6,4 +6,5 @@ See http://www.doxygen.org/ for more info.
|
||||
Either run 'make' (Unix) or 'doxy.bat' (Windows) to run doxygen
|
||||
and generate souce code documentation.
|
||||
|
||||
Then, load doxy/core/index.html into your web browser.
|
||||
Then, load either doxy/core/index.html or doxy/core_subset/index.html into
|
||||
your web browser.
|
||||
|
||||
@@ -55,7 +55,7 @@ INPUT = ../src/
|
||||
FILE_PATTERNS = *.c *.h
|
||||
RECURSIVE = NO
|
||||
EXCLUDE = ../src/glapitemp.h ../src/glapioffsets.h
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS = subset_*
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
@@ -132,13 +132,13 @@ GENERATE_AUTOGEN_DEF = NO
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = ../include/
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
PREDEFINED = _HAVE_FULL_GL=1
|
||||
EXPAND_AS_DEFINED = _glthread_DECLARE_STATIC_MUTEX
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
@@ -148,8 +148,7 @@ TAGFILES = tnl_dd.tag=../tnl_dd \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
miniglx.tag=../miniglx
|
||||
tnl.tag=../tnl
|
||||
GENERATE_TAGFILE = core.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
226
doxygen/core_subset.doxy
Normal file
226
doxygen/core_subset.doxy
Normal file
@@ -0,0 +1,226 @@
|
||||
# Doxyfile 0.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = "Mesa Core"
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = YES
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS = subset
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_FORMAT =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ../src/
|
||||
FILE_PATTERNS = \
|
||||
accum.h \
|
||||
attrib.h \
|
||||
blend.[ch] \
|
||||
buffers.[ch] \
|
||||
dd.h \
|
||||
debug.h \
|
||||
depth.h \
|
||||
dlist.h \
|
||||
context.[ch] \
|
||||
config.h \
|
||||
colormac.h \
|
||||
colortab.h \
|
||||
enable.h \
|
||||
enums.h \
|
||||
eval.h \
|
||||
extensions.h \
|
||||
feedback.[ch] \
|
||||
fog.h \
|
||||
get.h \
|
||||
glheader.h \
|
||||
glthread.h \
|
||||
hash.[ch] \
|
||||
hint.h \
|
||||
histogram.h \
|
||||
image.[ch] \
|
||||
imports.[ch] \
|
||||
lines.[ch] \
|
||||
light.h \
|
||||
matrix.[ch] \
|
||||
macros.h \
|
||||
mmath.h \
|
||||
mtypes.h \
|
||||
pixel.h \
|
||||
points.[ch] \
|
||||
polygon.[ch] \
|
||||
rastpos.[ch] \
|
||||
simple_list.h \
|
||||
state.[ch] \
|
||||
stencil.[ch] \
|
||||
subset_*.c \
|
||||
texformat.h \
|
||||
teximage.h \
|
||||
texstate.h \
|
||||
texstore.h \
|
||||
texobj.[ch] \
|
||||
texutil_tmp.h \
|
||||
varray.h
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = core_subset
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT =
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT =
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT =
|
||||
MAN_EXTENSION =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = ../include/
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = \
|
||||
math_subset.tag=../math_subset \
|
||||
miniglx.tag=../miniglx
|
||||
GENERATE_TAGFILE = core_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME =
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH =
|
||||
EXT_DOC_PATHS =
|
||||
@@ -3,12 +3,10 @@
|
||||
</head>
|
||||
<body><center>
|
||||
<a href="../core/index.html">Mesa Core</a>
|
||||
<a href="../miniglx/index.html">MiniGLX</a>
|
||||
<a href="../array_cache/index.html">array_cache</a>
|
||||
<a href="../math/index.html">math</a>
|
||||
<a href="../swrast/index.html">swrast</a>
|
||||
<a href="../swrast_setup/index.html">swrast_setup</a>
|
||||
<a href="../tnl/index.html">tnl</a>
|
||||
<a href="../tnl_dd/index.html">tnl_dd</a>
|
||||
<a href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</center>
|
||||
</center>
|
||||
|
||||
9
doxygen/header_subset.html
Normal file
9
doxygen/header_subset.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<html><head><title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body><center>
|
||||
<a href="../core_subset/index.html">Mesa Core</a>
|
||||
<a href="../math_subset/index.html">math</a>
|
||||
<a href="../miniglx/index.html">MiniGLX</a>
|
||||
<a href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</center>
|
||||
@@ -1,11 +1,12 @@
|
||||
default:
|
||||
default: subset
|
||||
|
||||
full:
|
||||
doxygen tnl_dd.doxy
|
||||
doxygen array_cache.doxy
|
||||
doxygen math.doxy
|
||||
doxygen swrast.doxy
|
||||
doxygen swrast_setup.doxy
|
||||
doxygen tnl.doxy
|
||||
doxygen miniglx.doxy
|
||||
doxygen core.doxy
|
||||
echo "Building again, to resolve tags"
|
||||
doxygen tnl_dd.doxy
|
||||
@@ -14,11 +15,30 @@ default:
|
||||
doxygen swrast.doxy
|
||||
doxygen swrast_setup.doxy
|
||||
doxygen tnl.doxy
|
||||
doxygen core.doxy
|
||||
|
||||
subset:
|
||||
doxygen core_subset.doxy
|
||||
doxygen math_subset.doxy
|
||||
doxygen miniglx.doxy
|
||||
echo "Building again, to resolve tags"
|
||||
doxygen core_subset.doxy
|
||||
doxygen math_subset.doxy
|
||||
doxygen miniglx.doxy
|
||||
doxygen radeon_subset.doxy
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx radeon_subset
|
||||
rm -rf \
|
||||
array_cache \
|
||||
core \
|
||||
core_subset \
|
||||
math \
|
||||
math_subset \
|
||||
swrast \
|
||||
swrast_setup \
|
||||
tnl_dd \
|
||||
tnl \
|
||||
miniglx \
|
||||
radeon_subset
|
||||
rm -rf *.tag
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ OUTPUT_DIRECTORY = .
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
177
doxygen/math_subset.doxy
Normal file
177
doxygen/math_subset.doxy
Normal file
@@ -0,0 +1,177 @@
|
||||
# Doxyfile 0.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = "Mesa math module"
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY = .
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_FORMAT =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ../src/math/
|
||||
FILE_PATTERNS = m_matrix.[ch]
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = math_subset
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT =
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT =
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT =
|
||||
MAN_EXTENSION =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core_subset.tag=../core_subset
|
||||
GENERATE_TAGFILE = math_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME =
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH =
|
||||
EXT_DOC_PATHS =
|
||||
@@ -80,7 +80,7 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = miniglx
|
||||
HTML_HEADER = header.html
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
@@ -143,14 +143,9 @@ SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core.tag=../core \
|
||||
tnl_dd.tag=../tnl_dd \
|
||||
array_cache.tag=../array_cache \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
array_cache.tag=array_cache
|
||||
TAGFILES = \
|
||||
core_subset.tag=../core_subset \
|
||||
math_subset.tag=../math_subset
|
||||
GENERATE_TAGFILE = miniglx.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
@@ -103,7 +103,7 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = radeon_subset
|
||||
HTML_HEADER = header.html
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
@@ -166,15 +166,10 @@ SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core.tag=../core \
|
||||
tnl_dd.tag=../tnl_dd \
|
||||
array_cache.tag=../array_cache \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
miniglx.tag=../miniglx \
|
||||
array_cache.tag=array_cache
|
||||
TAGFILES = \
|
||||
core_subset.tag=../core_subset \
|
||||
math_subset.tag=../math_subset \
|
||||
miniglx.tag=../miniglx
|
||||
GENERATE_TAGFILE = radeon_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/* $Id: gl.h,v 1.72 2002/10/17 19:39:31 kschultz Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 4.1
|
||||
* Version: 5.0.1
|
||||
*
|
||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -2646,6 +2645,13 @@ GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid
|
||||
#endif /* GL_APPLE_ycbcr_422 */
|
||||
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_ATI_texture_env_combine3 1
|
||||
#define GL_MODULATE_ADD_ATI 0x8744
|
||||
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
|
||||
#define GL_MODULATE_SUBTRACT_ATI 0x8746
|
||||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Begin system-specific stuff
|
||||
|
||||
@@ -2423,6 +2423,11 @@ extern "C" {
|
||||
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
|
||||
#endif
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_MODULATE_ADD_ATI 0x8744
|
||||
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
|
||||
#define GL_MODULATE_SUBTRACT_ATI 0x8746
|
||||
#endif
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
@@ -5016,6 +5021,9 @@ GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum);
|
||||
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
||||
#endif
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_ATI_texture_env_combine3 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
PROGS = gears \
|
||||
glinfo \
|
||||
texobj \
|
||||
isosurf \
|
||||
bounce \
|
||||
terrain
|
||||
|
||||
@@ -14,12 +15,12 @@ PROGS = gears \
|
||||
|
||||
# make executable from .c file:
|
||||
.c: $(LIB_DEP)
|
||||
gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lm -o $@
|
||||
gcc -I../include -I../util -g $< -L../lib -lglut -lGL -lGLU -lm -o $@
|
||||
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
|
||||
clean:
|
||||
-rm *.o *~
|
||||
-rm -f *.o *~ $(PROGS)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: bounce.c,v 1.3.8.1 2003/02/23 19:25:07 keithw Exp $ */
|
||||
/* $Id: bounce.c,v 1.3.8.2 2003/03/22 08:40:35 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Bouncing ball demo.
|
||||
@@ -115,15 +115,15 @@ draw(void)
|
||||
glColor3f(0, 1, 1);
|
||||
glBegin(GL_LINES);
|
||||
for (i = -5; i <= 5; i++) {
|
||||
glVertex2i(i, -5);
|
||||
glVertex2i(i, 5);
|
||||
glVertex2f(i, -5);
|
||||
glVertex2f(i, 5);
|
||||
}
|
||||
for (i = -5; i <= 5; i++) {
|
||||
glVertex2i(-5, i);
|
||||
glVertex2i(5, i);
|
||||
glVertex2f(-5, i);
|
||||
glVertex2f(5, i);
|
||||
}
|
||||
for (i = -5; i <= 5; i++) {
|
||||
glVertex2i(i, -5);
|
||||
glVertex2f(i, -5);
|
||||
glVertex2f(i * 1.15, -5.9);
|
||||
}
|
||||
glVertex2f(-5.3, -5.35);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isosurf.c,v 1.15.4.1 2003/02/23 21:04:25 keithw Exp $ */
|
||||
/* $Id: isosurf.c,v 1.15.4.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;
|
||||
}
|
||||
|
||||
@@ -680,18 +680,13 @@ loadpic(void)
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
(GLvoid *) (&terrainpic[0][0])))) {
|
||||
fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
|
||||
exit(-1);
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_RGBA, 256, 256, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, (GLvoid *) terrainpic);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: texobj.c,v 1.6.6.1 2003/02/23 19:25:07 keithw Exp $ */
|
||||
/* $Id: texobj.c,v 1.6.6.2 2003/03/22 08:40:35 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Example of using the 1.1 texture object functions.
|
||||
@@ -50,7 +50,7 @@ static void draw( void )
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
glCallList( TexObj[0] );
|
||||
/* glCallList( TexObj[0] ); */
|
||||
}
|
||||
glBegin( GL_POLYGON );
|
||||
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
|
||||
@@ -70,7 +70,7 @@ static void draw( void )
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
glCallList( TexObj[1] );
|
||||
/* glCallList( TexObj[1] ); */
|
||||
}
|
||||
glBegin( GL_POLYGON );
|
||||
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1.0, -1.0 );
|
||||
@@ -166,8 +166,8 @@ static void init( void )
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
TexObj[0] = glGenLists(2);
|
||||
TexObj[1] = TexObj[0]+1;
|
||||
/* TexObj[0] = glGenLists(2); */
|
||||
/* TexObj[1] = TexObj[0]+1; */
|
||||
}
|
||||
|
||||
/* setup first texture object */
|
||||
@@ -178,7 +178,7 @@ static void init( void )
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
glNewList( TexObj[0], GL_COMPILE );
|
||||
/* glNewList( TexObj[0], GL_COMPILE ); */
|
||||
}
|
||||
/* red on white */
|
||||
for (i=0;i<height;i++) {
|
||||
@@ -201,7 +201,7 @@ static void init( void )
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
if (!UseObj) {
|
||||
glEndList();
|
||||
/* glEndList(); */
|
||||
}
|
||||
/* end of texture object */
|
||||
|
||||
@@ -214,7 +214,7 @@ static void init( void )
|
||||
/* assert(!glIsTexture(TexObj[1] + 999)); */
|
||||
}
|
||||
else {
|
||||
glNewList( TexObj[1], GL_COMPILE );
|
||||
/* glNewList( TexObj[1], GL_COMPILE ); */
|
||||
}
|
||||
/* green on blue */
|
||||
for (i=0;i<height;i++) {
|
||||
@@ -235,7 +235,7 @@ static void init( void )
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
if (!UseObj) {
|
||||
glEndList();
|
||||
/* glEndList(); */
|
||||
}
|
||||
/* end texture object */
|
||||
|
||||
|
||||
30
progs/samples/Makefile
Normal file
30
progs/samples/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
PROGS = prim \
|
||||
star \
|
||||
line \
|
||||
point \
|
||||
depth \
|
||||
tri \
|
||||
bitmap1 \
|
||||
bitmap2
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c
|
||||
|
||||
|
||||
# make executable from .c file:
|
||||
.c: $(LIB_DEP)
|
||||
gcc -I../include -g $< -L../lib -lglut -lGL -lGLU -lm -o $@
|
||||
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
|
||||
clean: clean_here
|
||||
|
||||
clean_here:
|
||||
rm -f *.o *~ $(PROGS)
|
||||
|
||||
@@ -62,7 +62,7 @@ static void Init(void)
|
||||
GLint i;
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearIndex(0.0);
|
||||
/* glClearIndex(0.0); */
|
||||
|
||||
if (!rgb) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
@@ -71,7 +71,7 @@ static void Init(void)
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonStipple(stippleBits);
|
||||
/* glPolygonStipple(stippleBits); */
|
||||
|
||||
antiAlias = GL_FALSE;
|
||||
stipple = GL_FALSE;
|
||||
@@ -135,11 +135,11 @@ static void Draw(void)
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexi(ci1);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
glVertex3f( 0.9, -0.9, -30.0);
|
||||
glVertex3f( 0.9, 0.9, -30.0);
|
||||
glVertex3f(-0.9, 0.0, -30.0);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexi(ci2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
glVertex3f(-0.9, -0.9, -40.0);
|
||||
glVertex3f(-0.9, 0.9, -40.0);
|
||||
glVertex3f( 0.9, 0.0, -25.0);
|
||||
|
||||
@@ -141,7 +141,7 @@ static void Draw(void)
|
||||
for (i = 0; i < 360; i += 5) {
|
||||
glRotatef(5.0, 0,0,1);
|
||||
|
||||
(rgb) ? glColor3f(1.0, 1.0, 0.0) : glIndexi(ci);
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(pntA);
|
||||
glVertex3fv(pntB);
|
||||
@@ -199,7 +199,7 @@ int main(int argc, char **argv)
|
||||
|
||||
glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
|
||||
|
||||
windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
|
||||
windType = GLUT_RGB;
|
||||
windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
|
||||
glutInitDisplayMode(windType);
|
||||
|
||||
|
||||
@@ -153,9 +153,9 @@ static void Draw(void)
|
||||
|
||||
/* glPointSize(size); */
|
||||
if (mode) {
|
||||
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED);
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
} else {
|
||||
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_RED);
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
}
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3fv(point);
|
||||
|
||||
@@ -126,18 +126,18 @@ static void Point(void)
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
for (i = 1; i < 8; i++) {
|
||||
GLint j = i * 2;
|
||||
SetColor(COLOR_BLACK+i);
|
||||
glVertex2i(-j, -j);
|
||||
glVertex2i(-j, 0);
|
||||
glVertex2i(-j, j);
|
||||
glVertex2i(0, j);
|
||||
glVertex2i(j, j);
|
||||
glVertex2i(j, 0);
|
||||
glVertex2i(j, -j);
|
||||
glVertex2i(0, -j);
|
||||
glVertex2f(-j, -j);
|
||||
glVertex2f(-j, 0);
|
||||
glVertex2f(-j, j);
|
||||
glVertex2f(0, j);
|
||||
glVertex2f(j, j);
|
||||
glVertex2f(j, 0);
|
||||
glVertex2f(j, -j);
|
||||
glVertex2f(0, -j);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -152,8 +152,8 @@ static void Lines(void)
|
||||
for (i = 1; i < 8; i++) {
|
||||
SetColor(COLOR_BLACK+i);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
glTranslatef(4, 0, 0);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ static void Lines(void)
|
||||
glPopMatrix();
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ static void LineStrip(void)
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -218,11 +218,11 @@ static void LineLoop(void)
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -231,16 +231,16 @@ static void Bitmap(void)
|
||||
|
||||
glBegin(GL_LINES);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/2, 0);
|
||||
glVertex2i(boxW/2, 0);
|
||||
glVertex2i(0, -boxH/2);
|
||||
glVertex2i(0, boxH/2);
|
||||
glVertex2f(-boxW/2, 0);
|
||||
glVertex2f(boxW/2, 0);
|
||||
glVertex2f(0, -boxH/2);
|
||||
glVertex2f(0, boxH/2);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(0, -3);
|
||||
glVertex2i(0, -3+OPENGL_HEIGHT);
|
||||
glVertex2f(0, -3);
|
||||
glVertex2f(0, -3+OPENGL_HEIGHT);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -3);
|
||||
glVertex2i(OPENGL_WIDTH, -3);
|
||||
glVertex2f(0, -3);
|
||||
glVertex2f(OPENGL_WIDTH, -3);
|
||||
glEnd();
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
@@ -257,23 +257,23 @@ static void Triangles(void)
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, -boxH/16);
|
||||
glVertex2f(-boxW/8, -boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, -boxH/16);
|
||||
glVertex2f(boxW/8, -boxH/16);
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, boxH/16);
|
||||
glVertex2f(-boxW/8, boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, boxH/16);
|
||||
glVertex2f(boxW/8, boxH/16);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -282,28 +282,28 @@ static void TriangleStrip(void)
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -boxH/4);
|
||||
glVertex2f(0, -boxH/4);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, boxH/4);
|
||||
glVertex2f(0, boxH/4);
|
||||
SetColor(COLOR_CYAN);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
SetColor(COLOR_YELLOW);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void TriangleFan(void)
|
||||
{
|
||||
GLint vx[8][2];
|
||||
GLfloat vx[8][2];
|
||||
GLint x0, y0, x1, y1, x2, y2, x3, y3;
|
||||
GLint i;
|
||||
|
||||
@@ -327,16 +327,16 @@ static void TriangleFan(void)
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SetColor(COLOR_WHITE-i);
|
||||
glVertex2iv(vx[i]);
|
||||
glVertex2fv(vx[i]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ static void Rect(void)
|
||||
|
||||
static void PolygonFunc(void)
|
||||
{
|
||||
GLint vx[8][2];
|
||||
GLfloat vx[8][2];
|
||||
GLint x0, y0, x1, y1, x2, y2, x3, y3;
|
||||
GLint i;
|
||||
|
||||
@@ -374,13 +374,13 @@ static void PolygonFunc(void)
|
||||
glBegin(GL_POLYGON);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SetColor(COLOR_WHITE-i);
|
||||
glVertex2iv(vx[i]);
|
||||
glVertex2fv(vx[i]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -389,28 +389,28 @@ static void Quads(void)
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, -boxH/16);
|
||||
glVertex2f(-boxW/8, -boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, -boxH/16);
|
||||
glVertex2f(boxW/8, -boxH/16);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, boxH/16);
|
||||
glVertex2f(-boxW/8, boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, boxH/16);
|
||||
glVertex2f(boxW/8, boxH/16);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -419,29 +419,30 @@ static void QuadStrip(void)
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -boxH/4);
|
||||
glVertex2f(0, -boxH/4);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, boxH/4);
|
||||
glVertex2f(0, boxH/4);
|
||||
SetColor(COLOR_CYAN);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
SetColor(COLOR_YELLOW);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void Draw(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
glViewport(0, 0, windW, windH);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
|
||||
@@ -255,7 +255,6 @@ static void Key(unsigned char key, int x, int y)
|
||||
|
||||
void Draw(void)
|
||||
{
|
||||
|
||||
MoveStars();
|
||||
ShowStars();
|
||||
if (nitro > 0) {
|
||||
|
||||
@@ -26,8 +26,8 @@ static void SetColor(int c)
|
||||
{
|
||||
if (glutGet(GLUT_WINDOW_RGBA))
|
||||
glColor3fv(RGBMap[c]);
|
||||
else
|
||||
glIndexf(c);
|
||||
/* else */
|
||||
/* glIndexf(c); */
|
||||
}
|
||||
|
||||
static void InitMap(void)
|
||||
|
||||
@@ -278,11 +278,11 @@ static void Draw(void)
|
||||
EndPrim();
|
||||
|
||||
if (showVerticies) {
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
|
||||
glColor3fv(RGBMap[COLOR_RED]);
|
||||
/* glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2); */
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
/* glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2); */
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
/* glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2); */
|
||||
}
|
||||
|
||||
@@ -314,11 +314,11 @@ static void Draw(void)
|
||||
|
||||
SetColor(COLOR_RED);
|
||||
BeginPrim();
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
|
||||
glColor3fv(RGBMap[COLOR_RED]);
|
||||
glVertex3fv(p0);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
glVertex3fv(p1);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
glVertex3fv(p2);
|
||||
EndPrim();
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -I../include
|
||||
LIBS = -L../lib -lGL -lglut -lm
|
||||
LIBS = -L../lib -lGL -lGLU -lglut -lm
|
||||
|
||||
PROGS = miniglxtest miniglxsample manytex
|
||||
PROGS = miniglxtest miniglxsample manytex texline
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: manytex.c,v 1.4 2002/10/18 17:47:36 kschultz Exp $ */
|
||||
/* $Id: manytex.c,v 1.4.4.1 2003/03/22 08:46:22 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* test handling of many texture maps
|
||||
@@ -191,8 +191,8 @@ static void Init( void )
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, TextureID[i]);
|
||||
|
||||
if (i < LowPriorityCount)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
|
||||
/* if (i < LowPriorityCount) */
|
||||
/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); */
|
||||
|
||||
if (RandomSize) {
|
||||
#if 0
|
||||
|
||||
@@ -79,6 +79,8 @@ MakeWindow(Display * dpy, unsigned int width, unsigned int height)
|
||||
/* Bind the rendering context and window */
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: miniglxtest.c,v 1.1.4.7 2003/02/21 22:18:24 keithw Exp $ */
|
||||
/* $Id: miniglxtest.c,v 1.1.4.9 2003/03/24 18:46:57 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test the mini GLX interface.
|
||||
@@ -122,6 +122,8 @@ static Window make_rgb_db_window( Display *dpy,
|
||||
|
||||
glXMakeCurrent( dpy, win, ctx );
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
@@ -161,7 +163,6 @@ int foo( )
|
||||
|
||||
XMapWindow( dpy, win );
|
||||
|
||||
#if !USE_MINI_GLX
|
||||
{
|
||||
XEvent e;
|
||||
while (1) {
|
||||
@@ -171,8 +172,6 @@ int foo( )
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
event_loop( dpy, win );
|
||||
|
||||
|
||||
115
progs/tests/sample_server.c
Normal file
115
progs/tests/sample_server.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* $Id: sample_server.c,v 1.1.2.1 2003/04/16 09:34:56 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;
|
||||
}
|
||||
|
||||
/* How is vt switching communicated through the XNextEvent interface?
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: texline.c,v 1.4 2002/08/17 00:30:36 brianp Exp $ */
|
||||
/* $Id: texline.c,v 1.4.6.1 2003/03/22 08:46:22 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test textured lines.
|
||||
@@ -59,7 +59,7 @@ static void Display( void )
|
||||
y = t * 2.0 - 1.0;
|
||||
if (!Texture)
|
||||
glColor3f(1, 0, 1);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s);
|
||||
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t, s); */
|
||||
glTexCoord2f(s, t);
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
@@ -73,12 +73,12 @@ static void Display( void )
|
||||
if (!Texture)
|
||||
glColor3f(1, 0, 1);
|
||||
glTexCoord2f(t, 0.0);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t);
|
||||
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, t); */
|
||||
glVertex2f(x, -1.0);
|
||||
if (!Texture)
|
||||
glColor3f(0, 1, 0);
|
||||
glTexCoord2f(t, 1.0);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t);
|
||||
/* glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, t); */
|
||||
glVertex2f(x, 1.0);
|
||||
}
|
||||
glEnd();
|
||||
@@ -127,22 +127,22 @@ static void Key( unsigned char key, int x, int y )
|
||||
if (Texture > 2)
|
||||
Texture = 0;
|
||||
if (Texture == 0) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
|
||||
/* glDisable(GL_TEXTURE_2D); */
|
||||
}
|
||||
else if (Texture == 1) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
|
||||
/* glDisable(GL_TEXTURE_2D); */
|
||||
}
|
||||
else {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
/* glActiveTextureARB(GL_TEXTURE0_ARB); */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
/* glActiveTextureARB(GL_TEXTURE1_ARB); */
|
||||
/* glEnable(GL_TEXTURE_2D); */
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
@@ -212,8 +212,8 @@ static void SpecialKey( int key, int x, int y )
|
||||
static void Init( int argc, char *argv[] )
|
||||
{
|
||||
GLuint u;
|
||||
for (u = 0; u < 2; u++) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + u);
|
||||
for (u = 0; u < 1; u++) {
|
||||
/* glActiveTextureARB(GL_TEXTURE0_ARB + u); */
|
||||
glBindTexture(GL_TEXTURE_2D, 10+u);
|
||||
if (u == 0)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.1.2.1 2003/02/05 04:37:12 keithw Exp $
|
||||
# $Id: Makefile,v 1.1.2.2 2003/03/04 17:29:55 keithw Exp $
|
||||
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 5.0
|
||||
@@ -7,27 +7,18 @@
|
||||
|
||||
|
||||
MESA = ../..
|
||||
MESABUILDDIR = ..
|
||||
|
||||
default: dri.a
|
||||
include $(MESA)/Makefile.include
|
||||
|
||||
INCLUDES = -I/usr/X11R6/include -I/usr/X11R6/include/X11/extensions -I$(MESA)/include -I. -I..
|
||||
DEFINES =
|
||||
|
||||
CFLAGS = $(INCLUDES) $(DEFINES) -g -MD -Wall -Wpointer-arith \
|
||||
-Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wnested-externs
|
||||
|
||||
# The .a files for each mesa module required by this driver:
|
||||
#
|
||||
DRI_SOURCES = dri_glx.c \
|
||||
dri_util.c \
|
||||
xf86drm.c \
|
||||
xf86drmHash.c \
|
||||
xf86drmRandom.c \
|
||||
xf86drmSL.c
|
||||
|
||||
|
||||
C_SOURCES = $(DRI_SOURCES)
|
||||
C_SOURCES = dri_glx.c \
|
||||
dri_util.c \
|
||||
xf86drm.c \
|
||||
xf86drmHash.c \
|
||||
xf86drmRandom.c \
|
||||
xf86drmSL.c
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
@@ -36,32 +27,11 @@ OBJECTS = $(C_SOURCES:.c=.o) \
|
||||
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default: dri.a
|
||||
|
||||
dri.a: $(OBJECTS) Makefile
|
||||
rm -f $@ && ar rcv $@ $(OBJECTS) && ranlib $@
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ *.d .\#* *.so
|
||||
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` `find ../include`
|
||||
|
||||
##### DEPENDENCIES #####
|
||||
|
||||
-include $(C_SOURCES:.c=.d)
|
||||
|
||||
.SUFFIXES: .c .d
|
||||
|
||||
.c.d:
|
||||
$(CC) -M $(INCLUDES) $(DEFINES) $< > $@
|
||||
|
||||
7
src/glu/mini/.cvsignore
Normal file
7
src/glu/mini/.cvsignore
Normal file
@@ -0,0 +1,7 @@
|
||||
.deps
|
||||
.libs
|
||||
Makefile.in
|
||||
*.lo
|
||||
*.o
|
||||
*.la
|
||||
depend
|
||||
46
src/glu/mini/Makefile
Normal file
46
src/glu/mini/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
MESA = ../..
|
||||
default: libGLU.so.1.1 install
|
||||
include $(MESA)/Makefile.include
|
||||
|
||||
LIBDIR = $(MESA)/lib
|
||||
|
||||
INCLUDES = -I$(MESA)/include
|
||||
CFLAGS = -c -g $(INCLUDES) -MD
|
||||
|
||||
SOURCES = glu.c \
|
||||
mipmap.c \
|
||||
nurbs.c \
|
||||
polytest.c \
|
||||
project.c \
|
||||
quadric.c \
|
||||
tess.c \
|
||||
tesselat.c
|
||||
|
||||
|
||||
OBJS = $(addsuffix .o,$(basename $(SOURCES)))
|
||||
|
||||
LIBS=-L$(MESA)/lib -lGL -lm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
libGLU.so.1.1: $(OBJS) Makefile
|
||||
gcc -shared -Wl,-soname,libGLU.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@
|
||||
|
||||
install:
|
||||
rm -f $(MESA)/lib/libGLU.so*
|
||||
install -D libGLU.so.1.1 $(MESA)/lib/libGLU.so.1.1
|
||||
ln -s libGLU.so.1.1 $(MESA)/lib/libGLU.so.1
|
||||
ln -s libGLU.so.1 $(MESA)/lib/libGLU.so
|
||||
|
||||
|
||||
clean: clean_here
|
||||
|
||||
clean_here:
|
||||
rm -f ../lib/libGLU.so*
|
||||
|
||||
|
||||
-include $(SOURCES:.c=.d)
|
||||
55
src/glu/mini/all.h
Normal file
55
src/glu/mini/all.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* $Id: all.h,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file includes all .h files needed for the GLU source code for
|
||||
* the purpose of precompiled headers.
|
||||
*
|
||||
* If the preprocessor symbol PCH is defined at compile time then each
|
||||
* of the .c files will #include "all.h" only, instead of a bunch of
|
||||
* individual .h files.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GLU_ALL_H
|
||||
#define GLU_ALL_H
|
||||
|
||||
|
||||
#ifndef PC_HEADER
|
||||
This is an error. all.h should be included only if PCH is defined.
|
||||
#endif
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "GL/gl.h"
|
||||
#include "GL/glu.h"
|
||||
#include "gluP.h"
|
||||
#include "nurbs.h"
|
||||
#include "tess.h"
|
||||
|
||||
|
||||
#endif /*GLU_ALL_H */
|
||||
417
src/glu/mini/glu.c
Normal file
417
src/glu/mini/glu.c
Normal file
@@ -0,0 +1,417 @@
|
||||
/* $Id: glu.c,v 1.1.2.1 2003/03/21 13:02:08 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.5
|
||||
* Copyright (C) 1995-2001 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gluP.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Miscellaneous utility functions
|
||||
*/
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926536
|
||||
#endif
|
||||
#define EPS 0.00001
|
||||
|
||||
#ifndef GLU_INCOMPATIBLE_GL_VERSION
|
||||
#define GLU_INCOMPATIBLE_GL_VERSION 100903
|
||||
#endif
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
|
||||
GLdouble centerx, GLdouble centery, GLdouble centerz,
|
||||
GLdouble upx, GLdouble upy, GLdouble upz)
|
||||
{
|
||||
GLfloat m[16];
|
||||
GLfloat x[3], y[3], z[3];
|
||||
GLfloat mag;
|
||||
|
||||
/* Make rotation matrix */
|
||||
|
||||
/* Z vector */
|
||||
z[0] = eyex - centerx;
|
||||
z[1] = eyey - centery;
|
||||
z[2] = eyez - centerz;
|
||||
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
|
||||
if (mag) { /* mpichler, 19950515 */
|
||||
z[0] /= mag;
|
||||
z[1] /= mag;
|
||||
z[2] /= mag;
|
||||
}
|
||||
|
||||
/* Y vector */
|
||||
y[0] = upx;
|
||||
y[1] = upy;
|
||||
y[2] = upz;
|
||||
|
||||
/* X vector = Y cross Z */
|
||||
x[0] = y[1] * z[2] - y[2] * z[1];
|
||||
x[1] = -y[0] * z[2] + y[2] * z[0];
|
||||
x[2] = y[0] * z[1] - y[1] * z[0];
|
||||
|
||||
/* Recompute Y = Z cross X */
|
||||
y[0] = z[1] * x[2] - z[2] * x[1];
|
||||
y[1] = -z[0] * x[2] + z[2] * x[0];
|
||||
y[2] = z[0] * x[1] - z[1] * x[0];
|
||||
|
||||
/* mpichler, 19950515 */
|
||||
/* cross product gives area of parallelogram, which is < 1.0 for
|
||||
* non-perpendicular unit-length vectors; so normalize x, y here
|
||||
*/
|
||||
|
||||
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
|
||||
if (mag) {
|
||||
x[0] /= mag;
|
||||
x[1] /= mag;
|
||||
x[2] /= mag;
|
||||
}
|
||||
|
||||
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
|
||||
if (mag) {
|
||||
y[0] /= mag;
|
||||
y[1] /= mag;
|
||||
y[2] /= mag;
|
||||
}
|
||||
|
||||
#define M(row,col) m[col*4+row]
|
||||
M(0, 0) = x[0];
|
||||
M(0, 1) = x[1];
|
||||
M(0, 2) = x[2];
|
||||
M(0, 3) = 0.0;
|
||||
M(1, 0) = y[0];
|
||||
M(1, 1) = y[1];
|
||||
M(1, 2) = y[2];
|
||||
M(1, 3) = 0.0;
|
||||
M(2, 0) = z[0];
|
||||
M(2, 1) = z[1];
|
||||
M(2, 2) = z[2];
|
||||
M(2, 3) = 0.0;
|
||||
M(3, 0) = 0.0;
|
||||
M(3, 1) = 0.0;
|
||||
M(3, 2) = 0.0;
|
||||
M(3, 3) = 1.0;
|
||||
#undef M
|
||||
glMultMatrixf(m);
|
||||
|
||||
/* Translate Eye to Origin */
|
||||
glTranslatef(-eyex, -eyey, -eyez);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
|
||||
{
|
||||
glOrtho(left, right, bottom, top, -1.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
frustum(GLfloat left, GLfloat right,
|
||||
GLfloat bottom, GLfloat top,
|
||||
GLfloat nearval, GLfloat farval)
|
||||
{
|
||||
GLfloat x, y, a, b, c, d;
|
||||
GLfloat m[16];
|
||||
|
||||
x = (2.0 * nearval) / (right - left);
|
||||
y = (2.0 * nearval) / (top - bottom);
|
||||
a = (right + left) / (right - left);
|
||||
b = (top + bottom) / (top - bottom);
|
||||
c = -(farval + nearval) / ( farval - nearval);
|
||||
d = -(2.0 * farval * nearval) / (farval - nearval);
|
||||
|
||||
#define M(row,col) m[col*4+row]
|
||||
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
|
||||
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
|
||||
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
|
||||
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
|
||||
#undef M
|
||||
|
||||
glMultMatrixf(m);
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
|
||||
{
|
||||
GLfloat xmin, xmax, ymin, ymax;
|
||||
|
||||
ymax = zNear * tan(fovy * M_PI / 360.0);
|
||||
ymin = -ymax;
|
||||
xmin = ymin * aspect;
|
||||
xmax = ymax * aspect;
|
||||
|
||||
/* don't call glFrustum() because of error semantics (covglu) */
|
||||
frustum(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluPickMatrix(GLdouble x, GLdouble y,
|
||||
GLdouble width, GLdouble height, GLint viewport[4])
|
||||
{
|
||||
GLfloat m[16];
|
||||
GLfloat sx, sy;
|
||||
GLfloat tx, ty;
|
||||
|
||||
sx = viewport[2] / width;
|
||||
sy = viewport[3] / height;
|
||||
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
|
||||
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
|
||||
|
||||
#define M(row,col) m[col*4+row]
|
||||
M(0, 0) = sx;
|
||||
M(0, 1) = 0.0;
|
||||
M(0, 2) = 0.0;
|
||||
M(0, 3) = tx;
|
||||
M(1, 0) = 0.0;
|
||||
M(1, 1) = sy;
|
||||
M(1, 2) = 0.0;
|
||||
M(1, 3) = ty;
|
||||
M(2, 0) = 0.0;
|
||||
M(2, 1) = 0.0;
|
||||
M(2, 2) = 1.0;
|
||||
M(2, 3) = 0.0;
|
||||
M(3, 0) = 0.0;
|
||||
M(3, 1) = 0.0;
|
||||
M(3, 2) = 0.0;
|
||||
M(3, 3) = 1.0;
|
||||
#undef M
|
||||
|
||||
glMultMatrixf(m);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const GLubyte *GLAPIENTRY
|
||||
gluErrorString(GLenum errorCode)
|
||||
{
|
||||
static char *tess_error[] = {
|
||||
"missing gluBeginPolygon",
|
||||
"missing gluBeginContour",
|
||||
"missing gluEndPolygon",
|
||||
"missing gluEndContour",
|
||||
"misoriented or self-intersecting loops",
|
||||
"coincident vertices",
|
||||
"colinear vertices",
|
||||
"FIST recovery process fatal error"
|
||||
};
|
||||
static char *nurbs_error[] = {
|
||||
"spline order un-supported",
|
||||
"too few knots",
|
||||
"valid knot range is empty",
|
||||
"decreasing knot sequence knot",
|
||||
"knot multiplicity greater than order of spline",
|
||||
"endcurve() must follow bgncurve()",
|
||||
"bgncurve() must precede endcurve()",
|
||||
"missing or extra geometric data",
|
||||
"can't draw pwlcurves",
|
||||
"missing bgncurve()",
|
||||
"missing bgnsurface()",
|
||||
"endtrim() must precede endsurface()",
|
||||
"bgnsurface() must precede endsurface()",
|
||||
"curve of improper type passed as trim curve",
|
||||
"bgnsurface() must precede bgntrim()",
|
||||
"endtrim() must follow bgntrim()",
|
||||
"bgntrim() must precede endtrim()",
|
||||
"invalid or missing trim curve",
|
||||
"bgntrim() must precede pwlcurve()",
|
||||
"pwlcurve referenced twice",
|
||||
"pwlcurve and nurbscurve mixed",
|
||||
"improper usage of trim data type",
|
||||
"nurbscurve referenced twice",
|
||||
"nurbscurve and pwlcurve mixed",
|
||||
"nurbssurface referenced twice",
|
||||
"invalid property",
|
||||
"endsurface() must follow bgnsurface()",
|
||||
"misoriented trim curves",
|
||||
"intersecting trim curves",
|
||||
"UNUSED",
|
||||
"unconnected trim curves",
|
||||
"unknown knot error",
|
||||
"negative vertex count encountered",
|
||||
"negative byte-stride encountered",
|
||||
"unknown type descriptor",
|
||||
"null control array or knot vector",
|
||||
"duplicate point on pwlcurve"
|
||||
};
|
||||
|
||||
/* GL Errors */
|
||||
if (errorCode == GL_NO_ERROR) {
|
||||
return (GLubyte *) "no error";
|
||||
}
|
||||
else if (errorCode == GL_INVALID_VALUE) {
|
||||
return (GLubyte *) "invalid value";
|
||||
}
|
||||
else if (errorCode == GL_INVALID_ENUM) {
|
||||
return (GLubyte *) "invalid enum";
|
||||
}
|
||||
else if (errorCode == GL_INVALID_OPERATION) {
|
||||
return (GLubyte *) "invalid operation";
|
||||
}
|
||||
else if (errorCode == GL_STACK_OVERFLOW) {
|
||||
return (GLubyte *) "stack overflow";
|
||||
}
|
||||
else if (errorCode == GL_STACK_UNDERFLOW) {
|
||||
return (GLubyte *) "stack underflow";
|
||||
}
|
||||
else if (errorCode == GL_OUT_OF_MEMORY) {
|
||||
return (GLubyte *) "out of memory";
|
||||
}
|
||||
/* GLU Errors */
|
||||
else if (errorCode == GLU_NO_ERROR) {
|
||||
return (GLubyte *) "no error";
|
||||
}
|
||||
else if (errorCode == GLU_INVALID_ENUM) {
|
||||
return (GLubyte *) "invalid enum";
|
||||
}
|
||||
else if (errorCode == GLU_INVALID_VALUE) {
|
||||
return (GLubyte *) "invalid value";
|
||||
}
|
||||
else if (errorCode == GLU_OUT_OF_MEMORY) {
|
||||
return (GLubyte *) "out of memory";
|
||||
}
|
||||
else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
|
||||
return (GLubyte *) "incompatible GL version";
|
||||
}
|
||||
else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
|
||||
return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
|
||||
}
|
||||
else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
|
||||
return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* New in GLU 1.1
|
||||
*/
|
||||
|
||||
const GLubyte *GLAPIENTRY
|
||||
gluGetString(GLenum name)
|
||||
{
|
||||
static char *extensions = "GL_EXT_abgr";
|
||||
static char *version = "1.1 Mesa 3.5";
|
||||
|
||||
switch (name) {
|
||||
case GLU_EXTENSIONS:
|
||||
return (GLubyte *) extensions;
|
||||
case GLU_VERSION:
|
||||
return (GLubyte *) version;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* gluGetProcAddressEXT not finalized yet! */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* for BeOS R4.5 */
|
||||
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
|
||||
#else
|
||||
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
|
||||
#endif
|
||||
{
|
||||
struct proc
|
||||
{
|
||||
const char *name;
|
||||
void *address;
|
||||
};
|
||||
static struct proc procTable[] = {
|
||||
{"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT}, /* me! */
|
||||
|
||||
/* new 1.1 functions */
|
||||
{"gluGetString", (void *) gluGetString},
|
||||
|
||||
/* new 1.2 functions */
|
||||
{"gluTessBeginPolygon", (void *) gluTessBeginPolygon},
|
||||
{"gluTessBeginContour", (void *) gluTessBeginContour},
|
||||
{"gluTessEndContour", (void *) gluTessEndContour},
|
||||
{"gluTessEndPolygon", (void *) gluTessEndPolygon},
|
||||
{"gluGetTessProperty", (void *) gluGetTessProperty},
|
||||
|
||||
/* new 1.3 functions */
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; procTable[i].address; i++) {
|
||||
if (strcmp((const char *) procName, procTable[i].name) == 0)
|
||||
return (void (GLAPIENTRY *) ()) procTable[i].address;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* New in GLU 1.3
|
||||
*/
|
||||
#ifdef GLU_VERSION_1_3
|
||||
GLboolean GLAPIENTRY
|
||||
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
|
||||
{
|
||||
assert(extName);
|
||||
assert(extString);
|
||||
{
|
||||
const int len = strlen((const char *) extName);
|
||||
const char *start = (const char *) extString;
|
||||
|
||||
while (1) {
|
||||
const char *c = strstr(start, (const char *) extName);
|
||||
if (!c)
|
||||
return GL_FALSE;
|
||||
|
||||
if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))
|
||||
return GL_TRUE;
|
||||
|
||||
start = c + len;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
142
src/glu/mini/gluP.h
Normal file
142
src/glu/mini/gluP.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* $Id: gluP.h,v 1.1.2.1 2003/03/21 13:02:10 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file allows the GLU code to be compiled either with the Mesa
|
||||
* headers or with the real OpenGL headers.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GLUP_H
|
||||
#define GLUP_H
|
||||
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if defined(_WIN32) && !defined(__WIN32__)
|
||||
# define __WIN32__
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN__))
|
||||
# pragma warning( disable : 4068 ) /* unknown pragma */
|
||||
# pragma warning( disable : 4710 ) /* function 'foo' not inlined */
|
||||
# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */
|
||||
# pragma warning( disable : 4127 ) /* conditional expression is constant */
|
||||
# if defined(MESA_MINWARN)
|
||||
# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
|
||||
# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
|
||||
# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
|
||||
# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
|
||||
# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
|
||||
# endif
|
||||
# if defined(_MSC_VER) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
|
||||
# define GLAPI __declspec(dllexport)
|
||||
# define WGLAPI __declspec(dllexport)
|
||||
# elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
|
||||
# define GLAPI __declspec(dllimport)
|
||||
# define WGLAPI __declspec(dllimport)
|
||||
# else /* for use with static link lib build of Win32 edition only */
|
||||
# define GLAPI extern
|
||||
# define WGLAPI __declspec(dllimport)
|
||||
# endif /* _STATIC_MESA support */
|
||||
# define GLAPIENTRY __stdcall
|
||||
# define GLAPIENTRYP __stdcall *
|
||||
# define GLCALLBACK __stdcall
|
||||
# define GLCALLBACKP __stdcall *
|
||||
# if defined(__CYGWIN__)
|
||||
# define GLCALLBACKPCAST *
|
||||
# else
|
||||
# define GLCALLBACKPCAST __stdcall *
|
||||
# endif
|
||||
# define GLWINAPI __stdcall
|
||||
# define GLWINAPIV __cdecl
|
||||
#else
|
||||
/* non-Windows compilation */
|
||||
# define GLAPI extern
|
||||
# define GLAPIENTRY
|
||||
# define GLAPIENTRYP *
|
||||
# define GLCALLBACK
|
||||
# define GLCALLBACKP *
|
||||
# define GLCALLBACKPCAST *
|
||||
# define GLWINAPI
|
||||
# define GLWINAPIV
|
||||
#endif /* WIN32 / CYGWIN bracket */
|
||||
|
||||
/* compatability guard so we don't need to change client code */
|
||||
|
||||
#if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP)
|
||||
# define CALLBACK GLCALLBACK
|
||||
typedef int (GLAPIENTRY *PROC)();
|
||||
typedef void *HGLRC;
|
||||
typedef void *HDC;
|
||||
typedef unsigned long COLORREF;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP)
|
||||
# define WGL_FONT_LINES 0
|
||||
# define WGL_FONT_POLYGONS 1
|
||||
#ifndef _GNU_H_WINDOWS32_FUNCTIONS
|
||||
# ifdef UNICODE
|
||||
# define wglUseFontBitmaps wglUseFontBitmapsW
|
||||
# define wglUseFontOutlines wglUseFontOutlinesW
|
||||
# else
|
||||
# define wglUseFontBitmaps wglUseFontBitmapsA
|
||||
# define wglUseFontOutlines wglUseFontOutlinesA
|
||||
# endif /* !UNICODE */
|
||||
#endif /* _GNU_H_WINDOWS32_FUNCTIONS */
|
||||
typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
|
||||
typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
|
||||
typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR;
|
||||
#include <gl/mesa_wgl.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef GLU_TESS_ERROR9
|
||||
/* If we're using the real OpenGL header files... */
|
||||
# define GLU_TESS_ERROR9 100159
|
||||
#endif
|
||||
|
||||
|
||||
#define GLU_NO_ERROR GL_NO_ERROR
|
||||
|
||||
|
||||
/* for Sun: */
|
||||
#ifdef SUNOS4
|
||||
#define MEMCPY( DST, SRC, BYTES) \
|
||||
memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
|
||||
#else
|
||||
#define MEMCPY( DST, SRC, BYTES) \
|
||||
memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
764
src/glu/mini/mipmap.c
Normal file
764
src/glu/mini/mipmap.c
Normal file
@@ -0,0 +1,764 @@
|
||||
/* $Id: mipmap.c,v 1.1.2.1 2003/03/21 13:02:12 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.4
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gluP.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Compute ceiling of integer quotient of A divided by B:
|
||||
*/
|
||||
#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
|
||||
|
||||
|
||||
|
||||
#ifdef EPSILON
|
||||
#undef EPSILON
|
||||
#endif
|
||||
#define EPSILON 0.001
|
||||
|
||||
|
||||
/* To work around optimizer bug in MSVC4.1 */
|
||||
#if defined(__WIN32__) && !defined(OPENSTEP)
|
||||
void
|
||||
dummy(GLuint j, GLuint k)
|
||||
{
|
||||
}
|
||||
#else
|
||||
#define dummy(J, K)
|
||||
#endif
|
||||
|
||||
|
||||
GLint GLAPIENTRY
|
||||
gluScaleImage(GLenum format,
|
||||
GLsizei widthin, GLsizei heightin,
|
||||
GLenum typein, const void *datain,
|
||||
GLsizei widthout, GLsizei heightout,
|
||||
GLenum typeout, void *dataout)
|
||||
{
|
||||
GLint components, i, j, k;
|
||||
GLfloat *tempin, *tempout, f;
|
||||
GLfloat sx, sy;
|
||||
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
|
||||
GLint packrowlength, packalignment, packskiprows, packskippixels;
|
||||
GLint sizein, sizeout;
|
||||
GLint rowstride, rowlen;
|
||||
|
||||
|
||||
/* Determine number of components per pixel */
|
||||
switch (format) {
|
||||
case GL_COLOR_INDEX:
|
||||
case GL_STENCIL_INDEX:
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_RED:
|
||||
case GL_GREEN:
|
||||
case GL_BLUE:
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE:
|
||||
components = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
components = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
case GL_BGR:
|
||||
components = 3;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
case GL_BGRA:
|
||||
#ifdef GL_EXT_abgr
|
||||
case GL_ABGR_EXT:
|
||||
#endif
|
||||
components = 4;
|
||||
break;
|
||||
default:
|
||||
return GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
/* Determine bytes per input datum */
|
||||
switch (typein) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
sizein = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_BYTE:
|
||||
sizein = sizeof(GLbyte);
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
sizein = sizeof(GLushort);
|
||||
break;
|
||||
case GL_SHORT:
|
||||
sizein = sizeof(GLshort);
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
sizein = sizeof(GLuint);
|
||||
break;
|
||||
case GL_INT:
|
||||
sizein = sizeof(GLint);
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
sizein = sizeof(GLfloat);
|
||||
break;
|
||||
case GL_BITMAP:
|
||||
/* not implemented yet */
|
||||
default:
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
/* Determine bytes per output datum */
|
||||
switch (typeout) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
sizeout = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_BYTE:
|
||||
sizeout = sizeof(GLbyte);
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
sizeout = sizeof(GLushort);
|
||||
break;
|
||||
case GL_SHORT:
|
||||
sizeout = sizeof(GLshort);
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
sizeout = sizeof(GLuint);
|
||||
break;
|
||||
case GL_INT:
|
||||
sizeout = sizeof(GLint);
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
sizeout = sizeof(GLfloat);
|
||||
break;
|
||||
case GL_BITMAP:
|
||||
/* not implemented yet */
|
||||
default:
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
/* Get glPixelStore state */
|
||||
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
|
||||
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
|
||||
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
|
||||
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
|
||||
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
|
||||
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
|
||||
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
|
||||
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
|
||||
|
||||
/* Allocate storage for intermediate images */
|
||||
tempin = (GLfloat *) malloc(widthin * heightin
|
||||
* components * sizeof(GLfloat));
|
||||
if (!tempin) {
|
||||
return GLU_OUT_OF_MEMORY;
|
||||
}
|
||||
tempout = (GLfloat *) malloc(widthout * heightout
|
||||
* components * sizeof(GLfloat));
|
||||
if (!tempout) {
|
||||
free(tempin);
|
||||
return GLU_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unpack the pixel data and convert to floating point
|
||||
*/
|
||||
|
||||
if (unpackrowlength > 0) {
|
||||
rowlen = unpackrowlength;
|
||||
}
|
||||
else {
|
||||
rowlen = widthin;
|
||||
}
|
||||
if (sizein >= unpackalignment) {
|
||||
rowstride = components * rowlen;
|
||||
}
|
||||
else {
|
||||
rowstride = unpackalignment / sizein
|
||||
* CEILING(components * rowlen * sizein, unpackalignment);
|
||||
}
|
||||
|
||||
switch (typein) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLubyte *ubptr = (GLubyte *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * ubptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_BYTE:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLbyte *bptr = (GLbyte *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * bptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLushort *usptr = (GLushort *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * usptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_SHORT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLshort *sptr = (GLshort *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * sptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLuint *uiptr = (GLuint *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * uiptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_INT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLint *iptr = (GLint *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = (GLfloat) * iptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightin; i++) {
|
||||
GLfloat *fptr = (GLfloat *) datain
|
||||
+ i * rowstride
|
||||
+ unpackskiprows * rowstride + unpackskippixels * components;
|
||||
for (j = 0; j < widthin * components; j++) {
|
||||
dummy(j, k);
|
||||
tempin[k++] = *fptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scale the image!
|
||||
*/
|
||||
|
||||
if (widthout > 1)
|
||||
sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
|
||||
else
|
||||
sx = (GLfloat) (widthin - 1);
|
||||
if (heightout > 1)
|
||||
sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
|
||||
else
|
||||
sy = (GLfloat) (heightin - 1);
|
||||
|
||||
/*#define POINT_SAMPLE*/
|
||||
#ifdef POINT_SAMPLE
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLint ii = i * sy;
|
||||
for (j = 0; j < widthout; j++) {
|
||||
GLint jj = j * sx;
|
||||
|
||||
GLfloat *src = tempin + (ii * widthin + jj) * components;
|
||||
GLfloat *dst = tempout + (i * widthout + j) * components;
|
||||
|
||||
for (k = 0; k < components; k++) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (sx < 1.0 && sy < 1.0) {
|
||||
/* magnify both width and height: use weighted sample of 4 pixels */
|
||||
GLint i0, i1, j0, j1;
|
||||
GLfloat alpha, beta;
|
||||
GLfloat *src00, *src01, *src10, *src11;
|
||||
GLfloat s1, s2;
|
||||
GLfloat *dst;
|
||||
|
||||
for (i = 0; i < heightout; i++) {
|
||||
i0 = i * sy;
|
||||
i1 = i0 + 1;
|
||||
if (i1 >= heightin)
|
||||
i1 = heightin - 1;
|
||||
/* i1 = (i+1) * sy - EPSILON;*/
|
||||
alpha = i * sy - i0;
|
||||
for (j = 0; j < widthout; j++) {
|
||||
j0 = j * sx;
|
||||
j1 = j0 + 1;
|
||||
if (j1 >= widthin)
|
||||
j1 = widthin - 1;
|
||||
/* j1 = (j+1) * sx - EPSILON; */
|
||||
beta = j * sx - j0;
|
||||
|
||||
/* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
|
||||
src00 = tempin + (i0 * widthin + j0) * components;
|
||||
src01 = tempin + (i0 * widthin + j1) * components;
|
||||
src10 = tempin + (i1 * widthin + j0) * components;
|
||||
src11 = tempin + (i1 * widthin + j1) * components;
|
||||
|
||||
dst = tempout + (i * widthout + j) * components;
|
||||
|
||||
for (k = 0; k < components; k++) {
|
||||
s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
|
||||
s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
|
||||
*dst++ = s1 * (1.0 - alpha) + s2 * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* shrink width and/or height: use an unweighted box filter */
|
||||
GLint i0, i1;
|
||||
GLint j0, j1;
|
||||
GLint ii, jj;
|
||||
GLfloat sum, *dst;
|
||||
|
||||
for (i = 0; i < heightout; i++) {
|
||||
i0 = i * sy;
|
||||
i1 = i0 + 1;
|
||||
if (i1 >= heightin)
|
||||
i1 = heightin - 1;
|
||||
/* i1 = (i+1) * sy - EPSILON; */
|
||||
for (j = 0; j < widthout; j++) {
|
||||
j0 = j * sx;
|
||||
j1 = j0 + 1;
|
||||
if (j1 >= widthin)
|
||||
j1 = widthin - 1;
|
||||
/* j1 = (j+1) * sx - EPSILON; */
|
||||
|
||||
dst = tempout + (i * widthout + j) * components;
|
||||
|
||||
/* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
|
||||
for (k = 0; k < components; k++) {
|
||||
sum = 0.0;
|
||||
for (ii = i0; ii <= i1; ii++) {
|
||||
for (jj = j0; jj <= j1; jj++) {
|
||||
sum += *(tempin + (ii * widthin + jj) * components + k);
|
||||
}
|
||||
}
|
||||
sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
|
||||
*dst++ = sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Return output image
|
||||
*/
|
||||
|
||||
if (packrowlength > 0) {
|
||||
rowlen = packrowlength;
|
||||
}
|
||||
else {
|
||||
rowlen = widthout;
|
||||
}
|
||||
if (sizeout >= packalignment) {
|
||||
rowstride = components * rowlen;
|
||||
}
|
||||
else {
|
||||
rowstride = packalignment / sizeout
|
||||
* CEILING(components * rowlen * sizeout, packalignment);
|
||||
}
|
||||
|
||||
switch (typeout) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLubyte *ubptr = (GLubyte *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*ubptr++ = (GLubyte) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_BYTE:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLbyte *bptr = (GLbyte *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*bptr++ = (GLbyte) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLushort *usptr = (GLushort *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*usptr++ = (GLushort) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_SHORT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLshort *sptr = (GLshort *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*sptr++ = (GLshort) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLuint *uiptr = (GLuint *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*uiptr++ = (GLuint) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_INT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLint *iptr = (GLint *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*iptr++ = (GLint) tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
k = 0;
|
||||
for (i = 0; i < heightout; i++) {
|
||||
GLfloat *fptr = (GLfloat *) dataout
|
||||
+ i * rowstride
|
||||
+ packskiprows * rowstride + packskippixels * components;
|
||||
for (j = 0; j < widthout * components; j++) {
|
||||
dummy(j, k + i);
|
||||
*fptr++ = tempout[k++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
|
||||
/* free temporary image storage */
|
||||
free(tempin);
|
||||
free(tempout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return the largest k such that 2^k <= n.
|
||||
*/
|
||||
static GLint
|
||||
ilog2(GLint n)
|
||||
{
|
||||
GLint k;
|
||||
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
for (k = 0; n >>= 1; k++);
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Find the value nearest to n which is also a power of two.
|
||||
*/
|
||||
static GLint
|
||||
round2(GLint n)
|
||||
{
|
||||
GLint m;
|
||||
|
||||
for (m = 1; m < n; m *= 2);
|
||||
|
||||
/* m>=n */
|
||||
if (m - n <= n - m / 2) {
|
||||
return m;
|
||||
}
|
||||
else {
|
||||
return m / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given an pixel format and datatype, return the number of bytes to
|
||||
* store one pixel.
|
||||
*/
|
||||
static GLint
|
||||
bytes_per_pixel(GLenum format, GLenum type)
|
||||
{
|
||||
GLint n, m;
|
||||
|
||||
switch (format) {
|
||||
case GL_COLOR_INDEX:
|
||||
case GL_STENCIL_INDEX:
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_RED:
|
||||
case GL_GREEN:
|
||||
case GL_BLUE:
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE:
|
||||
n = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
n = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
case GL_BGR:
|
||||
n = 3;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
case GL_BGRA:
|
||||
#ifdef GL_EXT_abgr
|
||||
case GL_ABGR_EXT:
|
||||
#endif
|
||||
n = 4;
|
||||
break;
|
||||
default:
|
||||
n = 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
m = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_BYTE:
|
||||
m = sizeof(GLbyte);
|
||||
break;
|
||||
case GL_BITMAP:
|
||||
m = 1;
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
m = sizeof(GLushort);
|
||||
break;
|
||||
case GL_SHORT:
|
||||
m = sizeof(GLshort);
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
m = sizeof(GLuint);
|
||||
break;
|
||||
case GL_INT:
|
||||
m = sizeof(GLint);
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
m = sizeof(GLfloat);
|
||||
break;
|
||||
default:
|
||||
m = 0;
|
||||
}
|
||||
|
||||
return n * m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* WARNING: This function isn't finished and has never been tested!!!!
|
||||
*/
|
||||
GLint GLAPIENTRY
|
||||
gluBuild1DMipmaps(GLenum target, GLint components,
|
||||
GLsizei width, GLenum format, GLenum type, const void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLint GLAPIENTRY
|
||||
gluBuild2DMipmaps(GLenum target, GLint components,
|
||||
GLsizei width, GLsizei height, GLenum format,
|
||||
GLenum type, const void *data)
|
||||
{
|
||||
GLint w, h;
|
||||
GLint maxsize;
|
||||
void *image, *newimage;
|
||||
GLint neww, newh, level, bpp;
|
||||
int error;
|
||||
GLboolean done;
|
||||
GLint retval = 0;
|
||||
GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
|
||||
GLint packrowlength, packalignment, packskiprows, packskippixels;
|
||||
GLfloat f;
|
||||
|
||||
if (width < 1 || height < 1)
|
||||
return GLU_INVALID_VALUE;
|
||||
|
||||
glGetFloatv(GL_MAX_TEXTURE_SIZE, &f); maxsize = (int)f;
|
||||
|
||||
w = round2(width);
|
||||
if (w > maxsize) {
|
||||
w = maxsize;
|
||||
}
|
||||
h = round2(height);
|
||||
if (h > maxsize) {
|
||||
h = maxsize;
|
||||
}
|
||||
|
||||
bpp = bytes_per_pixel(format, type);
|
||||
if (bpp == 0) {
|
||||
/* probably a bad format or type enum */
|
||||
return GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
/* Get current glPixelStore values */
|
||||
glGetFloatv(GL_UNPACK_ROW_LENGTH, &f); unpackrowlength = (int)f;
|
||||
glGetFloatv(GL_UNPACK_ALIGNMENT, &f); unpackalignment = (int)f;
|
||||
glGetFloatv(GL_UNPACK_SKIP_ROWS, &f); unpackskiprows = (int)f;
|
||||
glGetFloatv(GL_UNPACK_SKIP_PIXELS, &f); unpackskippixels = (int)f;
|
||||
glGetFloatv(GL_PACK_ROW_LENGTH, &f); packrowlength = (int)f;
|
||||
glGetFloatv(GL_PACK_ALIGNMENT, &f); packalignment = (int)f;
|
||||
glGetFloatv(GL_PACK_SKIP_ROWS, &f); packskiprows = (int)f;
|
||||
glGetFloatv(GL_PACK_SKIP_PIXELS, &f); packskippixels = (int)f;
|
||||
|
||||
/* set pixel packing */
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
|
||||
|
||||
done = GL_FALSE;
|
||||
|
||||
if (w != width || h != height) {
|
||||
/* must rescale image to get "top" mipmap texture image */
|
||||
image = malloc((w + 4) * h * bpp);
|
||||
if (!image) {
|
||||
return GLU_OUT_OF_MEMORY;
|
||||
}
|
||||
error = gluScaleImage(format, width, height, type, data,
|
||||
w, h, type, image);
|
||||
if (error) {
|
||||
retval = error;
|
||||
done = GL_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
image = (void *) data;
|
||||
}
|
||||
|
||||
level = 0;
|
||||
while (!done) {
|
||||
if (image != data) {
|
||||
/* set pixel unpacking */
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
}
|
||||
|
||||
glTexImage2D(target, level, components, w, h, 0, format, type, image);
|
||||
|
||||
if (w == 1 && h == 1)
|
||||
break;
|
||||
|
||||
neww = (w < 2) ? 1 : w / 2;
|
||||
newh = (h < 2) ? 1 : h / 2;
|
||||
newimage = malloc((neww + 4) * newh * bpp);
|
||||
if (!newimage) {
|
||||
return GLU_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
error = gluScaleImage(format, w, h, type, image,
|
||||
neww, newh, type, newimage);
|
||||
if (error) {
|
||||
retval = error;
|
||||
done = GL_TRUE;
|
||||
}
|
||||
|
||||
if (image != data) {
|
||||
free(image);
|
||||
}
|
||||
image = newimage;
|
||||
|
||||
w = neww;
|
||||
h = newh;
|
||||
level++;
|
||||
}
|
||||
|
||||
if (image != data) {
|
||||
free(image);
|
||||
}
|
||||
|
||||
/* Restore original glPixelStore state */
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
|
||||
|
||||
return retval;
|
||||
}
|
||||
158
src/glu/mini/nurbs.c
Normal file
158
src/glu/mini/nurbs.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* $Id: nurbs.c,v 1.1.2.1 2003/03/21 13:02:13 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
|
||||
* See README2 for more info.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gluP.h"
|
||||
#include "nurbs.h"
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
call_user_error(GLUnurbsObj * nobj, GLenum error)
|
||||
{
|
||||
nobj->error = error;
|
||||
if (nobj->error_callback != NULL) {
|
||||
(*(nobj->error_callback)) (error);
|
||||
}
|
||||
else {
|
||||
printf("NURBS error %d %s\n", error, (char *) gluErrorString(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLUnurbsObj *GLAPIENTRY
|
||||
gluNewNurbsRenderer(void)
|
||||
{
|
||||
GLUnurbsObj *n;
|
||||
GLfloat tmp_viewport[4];
|
||||
GLint i, j;
|
||||
|
||||
n = (GLUnurbsObj *) malloc(sizeof(GLUnurbsObj));
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluDeleteNurbsRenderer(GLUnurbsObj * nobj)
|
||||
{
|
||||
if (nobj) {
|
||||
free(nobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluLoadSamplingMatrices(GLUnurbsObj * nobj,
|
||||
const GLfloat modelMatrix[16],
|
||||
const GLfloat projMatrix[16], const GLint viewport[4])
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluGetNurbsProperty(GLUnurbsObj * nobj, GLenum property, GLfloat * value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluBeginCurve(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluEndCurve(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluNurbsCurve(GLUnurbsObj * nobj, GLint nknots, GLfloat * knot,
|
||||
GLint stride, GLfloat * ctlarray, GLint order, GLenum type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluBeginSurface(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluEndSurface(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluNurbsSurface(GLUnurbsObj * nobj,
|
||||
GLint sknot_count, GLfloat * sknot,
|
||||
GLint tknot_count, GLfloat * tknot,
|
||||
GLint s_stride, GLint t_stride,
|
||||
GLfloat * ctrlarray, GLint sorder, GLint torder, GLenum type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluNurbsCallback(GLUnurbsObj * nobj, GLenum which, void (GLCALLBACK * fn) ())
|
||||
{
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
gluBeginTrim(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
gluPwlCurve(GLUnurbsObj * nobj, GLint count, GLfloat * array, GLint stride,
|
||||
GLenum type)
|
||||
{
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
gluEndTrim(GLUnurbsObj * nobj)
|
||||
{
|
||||
}
|
||||
253
src/glu/mini/nurbs.h
Normal file
253
src/glu/mini/nurbs.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/* $Id: nurbs.h,v 1.1.2.1 2003/03/21 13:02:14 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
|
||||
* See README2 for more info.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NURBS_H
|
||||
#define NURBS_H
|
||||
|
||||
|
||||
#define EPSILON 1e-06 /* epsilon for double precision compares */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
|
||||
GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
|
||||
}
|
||||
GLU_nurbs_enum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GLU_TRIM_NURBS, GLU_TRIM_PWL
|
||||
}
|
||||
GLU_trim_enum;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLint sknot_count;
|
||||
GLfloat *sknot;
|
||||
GLint tknot_count;
|
||||
GLfloat *tknot;
|
||||
GLint s_stride;
|
||||
GLint t_stride;
|
||||
GLfloat *ctrlarray;
|
||||
GLint sorder;
|
||||
GLint torder;
|
||||
GLint dim;
|
||||
GLenum type;
|
||||
}
|
||||
surface_attribs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
surface_attribs geom;
|
||||
surface_attribs color;
|
||||
surface_attribs texture;
|
||||
surface_attribs normal;
|
||||
}
|
||||
nurbs_surface;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLint knot_count;
|
||||
GLfloat *knot;
|
||||
GLint stride;
|
||||
GLfloat *ctrlarray;
|
||||
GLint order;
|
||||
GLint dim;
|
||||
GLenum type;
|
||||
}
|
||||
curve_attribs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLint pt_count;
|
||||
GLfloat *ctrlarray;
|
||||
GLint stride;
|
||||
GLint dim;
|
||||
GLenum type;
|
||||
}
|
||||
pwl_curve_attribs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
curve_attribs geom;
|
||||
curve_attribs color;
|
||||
curve_attribs texture;
|
||||
curve_attribs normal;
|
||||
}
|
||||
nurbs_curve;
|
||||
|
||||
typedef struct trim_list_str
|
||||
{
|
||||
GLU_trim_enum trim_type;
|
||||
union
|
||||
{
|
||||
pwl_curve_attribs pwl_curve;
|
||||
curve_attribs nurbs_curve;
|
||||
}
|
||||
curve;
|
||||
struct trim_list_str *next;
|
||||
}
|
||||
trim_list;
|
||||
|
||||
typedef struct seg_trim_str
|
||||
{
|
||||
GLfloat *points;
|
||||
GLint pt_cnt, seg_array_len;
|
||||
struct seg_trim_str *next;
|
||||
}
|
||||
trim_segments;
|
||||
|
||||
typedef struct nurbs_trim_str
|
||||
{
|
||||
trim_list *trim_loop;
|
||||
trim_segments *segments;
|
||||
struct nurbs_trim_str *next;
|
||||
}
|
||||
nurbs_trim;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat model[16], proj[16], viewport[4];
|
||||
}
|
||||
culling_and_sampling_str;
|
||||
|
||||
struct GLUnurbs
|
||||
{
|
||||
GLboolean culling;
|
||||
GLenum error;
|
||||
void (GLCALLBACK * error_callback) (GLenum err);
|
||||
GLenum display_mode;
|
||||
GLU_nurbs_enum nurbs_type;
|
||||
GLboolean auto_load_matrix;
|
||||
culling_and_sampling_str sampling_matrices;
|
||||
GLenum sampling_method;
|
||||
GLfloat sampling_tolerance;
|
||||
GLfloat parametric_tolerance;
|
||||
GLint u_step, v_step;
|
||||
nurbs_surface surface;
|
||||
nurbs_curve curve;
|
||||
nurbs_trim *trim;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat *knot;
|
||||
GLint nknots;
|
||||
GLfloat *unified_knot;
|
||||
GLint unified_nknots;
|
||||
GLint order;
|
||||
GLint t_min, t_max;
|
||||
GLint delta_nknots;
|
||||
GLboolean open_at_begin, open_at_end;
|
||||
GLfloat *new_knot;
|
||||
GLfloat *alpha;
|
||||
}
|
||||
knot_str_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat *geom_ctrl;
|
||||
GLint geom_s_stride, geom_t_stride;
|
||||
GLfloat **geom_offsets;
|
||||
GLint geom_s_pt_cnt, geom_t_pt_cnt;
|
||||
GLfloat *color_ctrl;
|
||||
GLint color_s_stride, color_t_stride;
|
||||
GLfloat **color_offsets;
|
||||
GLint color_s_pt_cnt, color_t_pt_cnt;
|
||||
GLfloat *normal_ctrl;
|
||||
GLint normal_s_stride, normal_t_stride;
|
||||
GLfloat **normal_offsets;
|
||||
GLint normal_s_pt_cnt, normal_t_pt_cnt;
|
||||
GLfloat *texture_ctrl;
|
||||
GLint texture_s_stride, texture_t_stride;
|
||||
GLfloat **texture_offsets;
|
||||
GLint texture_s_pt_cnt, texture_t_pt_cnt;
|
||||
GLint s_bezier_cnt, t_bezier_cnt;
|
||||
}
|
||||
new_ctrl_type;
|
||||
|
||||
extern void call_user_error(GLUnurbsObj * nobj, GLenum error);
|
||||
|
||||
extern GLenum test_knot(GLint nknots, GLfloat * knot, GLint order);
|
||||
|
||||
extern GLenum explode_knot(knot_str_type * the_knot);
|
||||
|
||||
extern GLenum calc_alphas(knot_str_type * the_knot);
|
||||
|
||||
extern GLenum calc_new_ctrl_pts(GLfloat * ctrl, GLint stride,
|
||||
knot_str_type * the_knot, GLint dim,
|
||||
GLfloat ** new_ctrl, GLint * ncontrol);
|
||||
|
||||
extern GLenum glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * new_ctrl,
|
||||
GLint n_ctrl, GLint order, GLint dim,
|
||||
GLint ** factors);
|
||||
|
||||
extern GLenum glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
|
||||
int **sfactors, GLint ** tfactors);
|
||||
|
||||
extern GLenum glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
|
||||
int **sfactors, GLint ** tfactors);
|
||||
|
||||
extern GLenum glu_do_sampling_param_3D(GLUnurbsObj * nobj,
|
||||
new_ctrl_type * new_ctrl,
|
||||
int **sfactors, GLint ** tfactors);
|
||||
|
||||
extern GLboolean fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * ctrl,
|
||||
GLint n_ctrl, GLint stride, GLint dim);
|
||||
|
||||
extern GLboolean fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * ctrl,
|
||||
GLint s_n_ctrl, GLint t_n_ctrl,
|
||||
GLint s_stride, GLint t_stride,
|
||||
GLint dim);
|
||||
|
||||
extern void do_nurbs_curve(GLUnurbsObj * nobj);
|
||||
|
||||
extern void do_nurbs_surface(GLUnurbsObj * nobj);
|
||||
|
||||
extern GLenum patch_trimming(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl,
|
||||
GLint * sfactors, GLint * tfactors);
|
||||
|
||||
extern void collect_unified_knot(knot_str_type * dest, knot_str_type * src,
|
||||
GLfloat maximal_min_knot,
|
||||
GLfloat minimal_max_knot);
|
||||
|
||||
extern GLenum select_knot_working_range(GLUnurbsObj * nobj,
|
||||
knot_str_type * geom_knot,
|
||||
knot_str_type * color_knot,
|
||||
knot_str_type * normal_knot,
|
||||
knot_str_type * texture_knot);
|
||||
|
||||
extern void free_unified_knots(knot_str_type * geom_knot,
|
||||
knot_str_type * color_knot,
|
||||
knot_str_type * normal_knot,
|
||||
knot_str_type * texture_knot);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
133
src/glu/mini/nurbscrv.c
Normal file
133
src/glu/mini/nurbscrv.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $Id: nurbscrv.c,v 1.1.2.1 2003/03/21 13:02:16 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
|
||||
* See README2 for more info.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "gluP.h"
|
||||
#include "nurbs.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* main NURBS curve procedure */
|
||||
void
|
||||
do_nurbs_curve(GLUnurbsObj * nobj)
|
||||
{
|
||||
GLint geom_order, color_order = 0, normal_order = 0, texture_order = 0;
|
||||
GLenum geom_type;
|
||||
GLint n_ctrl;
|
||||
GLfloat *new_geom_ctrl, *new_color_ctrl, *new_normal_ctrl,
|
||||
*new_texture_ctrl;
|
||||
GLfloat *geom_ctrl = 0, *color_ctrl = 0, *normal_ctrl = 0, *texture_ctrl = 0;
|
||||
GLint *factors;
|
||||
GLint i, j;
|
||||
GLint geom_dim, color_dim = 0, normal_dim = 0, texture_dim = 0;
|
||||
|
||||
/* test the user supplied data */
|
||||
if (test_nurbs_curves(nobj) != GLU_NO_ERROR)
|
||||
return;
|
||||
|
||||
if (convert_curves(nobj, &new_geom_ctrl, &n_ctrl, &new_color_ctrl,
|
||||
&new_normal_ctrl, &new_texture_ctrl) != GLU_NO_ERROR)
|
||||
return;
|
||||
|
||||
geom_order = nobj->curve.geom.order;
|
||||
geom_type = nobj->curve.geom.type;
|
||||
geom_dim = nobj->curve.geom.dim;
|
||||
|
||||
if (glu_do_sampling_crv(nobj, new_geom_ctrl, n_ctrl, geom_order, geom_dim,
|
||||
&factors) != GLU_NO_ERROR) {
|
||||
free(new_geom_ctrl);
|
||||
if (new_color_ctrl)
|
||||
free(new_color_ctrl);
|
||||
if (new_normal_ctrl)
|
||||
free(new_normal_ctrl);
|
||||
if (new_texture_ctrl)
|
||||
free(new_texture_ctrl);
|
||||
return;
|
||||
}
|
||||
glEnable(geom_type);
|
||||
if (new_color_ctrl) {
|
||||
glEnable(nobj->curve.color.type);
|
||||
color_dim = nobj->curve.color.dim;
|
||||
color_ctrl = new_color_ctrl;
|
||||
color_order = nobj->curve.color.order;
|
||||
}
|
||||
if (new_normal_ctrl) {
|
||||
glEnable(nobj->curve.normal.type);
|
||||
normal_dim = nobj->curve.normal.dim;
|
||||
normal_ctrl = new_normal_ctrl;
|
||||
normal_order = nobj->curve.normal.order;
|
||||
}
|
||||
if (new_texture_ctrl) {
|
||||
glEnable(nobj->curve.texture.type);
|
||||
texture_dim = nobj->curve.texture.dim;
|
||||
texture_ctrl = new_texture_ctrl;
|
||||
texture_order = nobj->curve.texture.order;
|
||||
}
|
||||
for (i = 0, j = 0, geom_ctrl = new_geom_ctrl;
|
||||
i < n_ctrl; i += geom_order, j++, geom_ctrl += geom_order * geom_dim) {
|
||||
if (fine_culling_test_2D
|
||||
(nobj, geom_ctrl, geom_order, geom_dim, geom_dim)) {
|
||||
color_ctrl += color_order * color_dim;
|
||||
normal_ctrl += normal_order * normal_dim;
|
||||
texture_ctrl += texture_order * texture_dim;
|
||||
continue;
|
||||
}
|
||||
glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl);
|
||||
if (new_color_ctrl) {
|
||||
glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim,
|
||||
color_order, color_ctrl);
|
||||
color_ctrl += color_order * color_dim;
|
||||
}
|
||||
if (new_normal_ctrl) {
|
||||
glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim,
|
||||
normal_order, normal_ctrl);
|
||||
normal_ctrl += normal_order * normal_dim;
|
||||
}
|
||||
if (new_texture_ctrl) {
|
||||
glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim,
|
||||
texture_order, texture_ctrl);
|
||||
texture_ctrl += texture_order * texture_dim;
|
||||
}
|
||||
glMapGrid1f(factors[j], 0.0, 1.0);
|
||||
glEvalMesh1(GL_LINE, 0, factors[j]);
|
||||
}
|
||||
free(new_geom_ctrl);
|
||||
free(factors);
|
||||
if (new_color_ctrl)
|
||||
free(new_color_ctrl);
|
||||
if (new_normal_ctrl)
|
||||
free(new_normal_ctrl);
|
||||
if (new_texture_ctrl)
|
||||
free(new_texture_ctrl);
|
||||
}
|
||||
938
src/glu/mini/polytest.c
Normal file
938
src/glu/mini/polytest.c
Normal file
@@ -0,0 +1,938 @@
|
||||
/* $Id: polytest.c,v 1.1.2.1 2003/03/21 13:02:17 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file is part of the polygon tesselation code contributed by
|
||||
* Bogdan Sikorski
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "gluP.h"
|
||||
#include "tess.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static GLenum store_polygon_as_contour(GLUtriangulatorObj *);
|
||||
static void free_current_polygon(tess_polygon *);
|
||||
static void prepare_projection_info(GLUtriangulatorObj *);
|
||||
static GLdouble twice_the_polygon_area(tess_vertex *, tess_vertex *);
|
||||
static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *);
|
||||
void tess_find_contour_hierarchies(GLUtriangulatorObj *);
|
||||
static GLenum test_for_overlapping_contours(GLUtriangulatorObj *);
|
||||
static GLenum contours_overlap(tess_contour *, tess_polygon *);
|
||||
static GLenum is_contour_contained_in(tess_contour *, tess_contour *);
|
||||
static void add_new_exterior(GLUtriangulatorObj *, tess_contour *);
|
||||
static void add_new_interior(GLUtriangulatorObj *, tess_contour *,
|
||||
tess_contour *);
|
||||
static void add_interior_with_hierarchy_check(GLUtriangulatorObj *,
|
||||
tess_contour *, tess_contour *);
|
||||
static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *,
|
||||
tess_contour *,
|
||||
tess_contour *);
|
||||
static GLboolean point_in_polygon(tess_contour *, GLdouble, GLdouble);
|
||||
static void shift_interior_to_exterior(GLUtriangulatorObj *, tess_contour *);
|
||||
static void add_exterior_with_check(GLUtriangulatorObj *, tess_contour *,
|
||||
tess_contour *);
|
||||
static GLenum cut_out_hole(GLUtriangulatorObj *, tess_contour *,
|
||||
tess_contour *);
|
||||
static GLenum merge_hole_with_contour(GLUtriangulatorObj *,
|
||||
tess_contour *, tess_contour *,
|
||||
tess_vertex *, tess_vertex *);
|
||||
|
||||
static GLenum
|
||||
find_normal(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_vertex *va, *vb, *vc;
|
||||
GLdouble A, B, C;
|
||||
GLdouble A0, A1, A2, B0, B1, B2;
|
||||
|
||||
va = polygon->vertices;
|
||||
vb = va->next;
|
||||
A0 = vb->location[0] - va->location[0];
|
||||
A1 = vb->location[1] - va->location[1];
|
||||
A2 = vb->location[2] - va->location[2];
|
||||
for (vc = vb->next; vc != va; vc = vc->next) {
|
||||
B0 = vc->location[0] - va->location[0];
|
||||
B1 = vc->location[1] - va->location[1];
|
||||
B2 = vc->location[2] - va->location[2];
|
||||
A = A1 * B2 - A2 * B1;
|
||||
B = A2 * B0 - A0 * B2;
|
||||
C = A0 * B1 - A1 * B0;
|
||||
if (fabs(A) > EPSILON || fabs(B) > EPSILON || fabs(C) > EPSILON) {
|
||||
polygon->A = A;
|
||||
polygon->B = B;
|
||||
polygon->C = C;
|
||||
polygon->D =
|
||||
-A * va->location[0] - B * va->location[1] - C * va->location[2];
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
}
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR7);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
tess_test_polygon(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
|
||||
/* any vertices defined? */
|
||||
if (polygon->vertex_cnt < 3) {
|
||||
free_current_polygon(polygon);
|
||||
return;
|
||||
}
|
||||
/* wrap pointers */
|
||||
polygon->last_vertex->next = polygon->vertices;
|
||||
polygon->vertices->previous = polygon->last_vertex;
|
||||
/* determine the normal */
|
||||
if (find_normal(tobj) == GLU_ERROR)
|
||||
return;
|
||||
/* compare the normals of previously defined contours and this one */
|
||||
/* first contour define ? */
|
||||
if (tobj->contours == NULL) {
|
||||
tobj->A = polygon->A;
|
||||
tobj->B = polygon->B;
|
||||
tobj->C = polygon->C;
|
||||
tobj->D = polygon->D;
|
||||
/* determine the best projection to use */
|
||||
if (fabs(polygon->A) > fabs(polygon->B))
|
||||
if (fabs(polygon->A) > fabs(polygon->C))
|
||||
tobj->projection = OYZ;
|
||||
else
|
||||
tobj->projection = OXY;
|
||||
else if (fabs(polygon->B) > fabs(polygon->C))
|
||||
tobj->projection = OXZ;
|
||||
else
|
||||
tobj->projection = OXY;
|
||||
}
|
||||
else {
|
||||
GLdouble a[3], b[3];
|
||||
tess_vertex *vertex = polygon->vertices;
|
||||
|
||||
a[0] = tobj->A;
|
||||
a[1] = tobj->B;
|
||||
a[2] = tobj->C;
|
||||
b[0] = polygon->A;
|
||||
b[1] = polygon->B;
|
||||
b[2] = polygon->C;
|
||||
|
||||
/* compare the normals */
|
||||
if (fabs(a[1] * b[2] - a[2] * b[1]) > EPSILON ||
|
||||
fabs(a[2] * b[0] - a[0] * b[2]) > EPSILON ||
|
||||
fabs(a[0] * b[1] - a[1] * b[0]) > EPSILON) {
|
||||
/* not coplanar */
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR9);
|
||||
return;
|
||||
}
|
||||
/* the normals are parallel - test for plane equation */
|
||||
if (fabs(a[0] * vertex->location[0] + a[1] * vertex->location[1] +
|
||||
a[2] * vertex->location[2] + tobj->D) > EPSILON) {
|
||||
/* not the same plane */
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR9);
|
||||
return;
|
||||
}
|
||||
}
|
||||
prepare_projection_info(tobj);
|
||||
if (verify_edge_vertex_intersections(tobj) == GLU_ERROR)
|
||||
return;
|
||||
if (test_for_overlapping_contours(tobj) == GLU_ERROR)
|
||||
return;
|
||||
if (store_polygon_as_contour(tobj) == GLU_ERROR)
|
||||
return;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
test_for_overlapping_contours(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_contour *contour;
|
||||
tess_polygon *polygon;
|
||||
|
||||
polygon = tobj->current_polygon;
|
||||
for (contour = tobj->contours; contour != NULL; contour = contour->next)
|
||||
if (contours_overlap(contour, polygon) != GLU_NO_ERROR) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR5);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
store_polygon_as_contour(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_contour *contour = tobj->contours;
|
||||
|
||||
/* the first contour defined */
|
||||
if (contour == NULL) {
|
||||
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
free_current_polygon(polygon);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
tobj->contours = tobj->last_contour = contour;
|
||||
contour->next = contour->previous = NULL;
|
||||
}
|
||||
else {
|
||||
if ((contour = (tess_contour *) malloc(sizeof(tess_contour))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
free_current_polygon(polygon);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
contour->previous = tobj->last_contour;
|
||||
tobj->last_contour->next = contour;
|
||||
tobj->last_contour = contour;
|
||||
contour->next = NULL;
|
||||
}
|
||||
/* mark all vertices in new contour as not special */
|
||||
/* and all are boundary edges */
|
||||
{
|
||||
tess_vertex *vertex;
|
||||
GLuint vertex_cnt, i;
|
||||
|
||||
for (vertex = polygon->vertices, i = 0, vertex_cnt =
|
||||
polygon->vertex_cnt; i < vertex_cnt; vertex = vertex->next, i++) {
|
||||
vertex->shadow_vertex = NULL;
|
||||
vertex->edge_flag = GL_TRUE;
|
||||
}
|
||||
}
|
||||
contour->vertex_cnt = polygon->vertex_cnt;
|
||||
contour->area = polygon->area;
|
||||
contour->orientation = polygon->orientation;
|
||||
contour->type = GLU_UNKNOWN;
|
||||
contour->vertices = polygon->vertices;
|
||||
contour->last_vertex = polygon->last_vertex;
|
||||
polygon->vertices = polygon->last_vertex = NULL;
|
||||
polygon->vertex_cnt = 0;
|
||||
++(tobj->contour_cnt);
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static void
|
||||
free_current_polygon(tess_polygon * polygon)
|
||||
{
|
||||
tess_vertex *vertex, *vertex_tmp;
|
||||
GLuint i;
|
||||
|
||||
/* free current_polygon structures */
|
||||
for (vertex = polygon->vertices, i = 0; i < polygon->vertex_cnt; i++) {
|
||||
vertex_tmp = vertex->next;
|
||||
free(vertex);
|
||||
vertex = vertex_tmp;
|
||||
}
|
||||
polygon->vertices = polygon->last_vertex = NULL;
|
||||
polygon->vertex_cnt = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_projection_info(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_vertex *vertex, *last_vertex_ptr;
|
||||
GLdouble area;
|
||||
|
||||
last_vertex_ptr = polygon->last_vertex;
|
||||
switch (tobj->projection) {
|
||||
case OXY:
|
||||
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
|
||||
vertex = vertex->next) {
|
||||
vertex->x = vertex->location[0];
|
||||
vertex->y = vertex->location[1];
|
||||
}
|
||||
last_vertex_ptr->x = last_vertex_ptr->location[0];
|
||||
last_vertex_ptr->y = last_vertex_ptr->location[1];
|
||||
break;
|
||||
case OXZ:
|
||||
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
|
||||
vertex = vertex->next) {
|
||||
vertex->x = vertex->location[0];
|
||||
vertex->y = vertex->location[2];
|
||||
}
|
||||
last_vertex_ptr->x = last_vertex_ptr->location[0];
|
||||
last_vertex_ptr->y = last_vertex_ptr->location[2];
|
||||
break;
|
||||
case OYZ:
|
||||
for (vertex = polygon->vertices; vertex != last_vertex_ptr;
|
||||
vertex = vertex->next) {
|
||||
vertex->x = vertex->location[1];
|
||||
vertex->y = vertex->location[2];
|
||||
}
|
||||
last_vertex_ptr->x = last_vertex_ptr->location[1];
|
||||
last_vertex_ptr->y = last_vertex_ptr->location[2];
|
||||
break;
|
||||
}
|
||||
area = twice_the_polygon_area(polygon->vertices, polygon->last_vertex);
|
||||
if (area >= 0.0) {
|
||||
polygon->orientation = GLU_CCW;
|
||||
polygon->area = area;
|
||||
}
|
||||
else {
|
||||
polygon->orientation = GLU_CW;
|
||||
polygon->area = -area;
|
||||
}
|
||||
}
|
||||
|
||||
static GLdouble
|
||||
twice_the_polygon_area(tess_vertex * vertex, tess_vertex * last_vertex)
|
||||
{
|
||||
tess_vertex *next;
|
||||
GLdouble area, x, y;
|
||||
|
||||
area = 0.0;
|
||||
x = vertex->x;
|
||||
y = vertex->y;
|
||||
vertex = vertex->next;
|
||||
for (; vertex != last_vertex; vertex = vertex->next) {
|
||||
next = vertex->next;
|
||||
area +=
|
||||
(vertex->x - x) * (next->y - y) - (vertex->y - y) * (next->x - x);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
/* test if edges ab and cd intersect */
|
||||
/* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */
|
||||
/* else if adjacent return GLU_TESS_ERROR4 */
|
||||
static GLenum
|
||||
edge_edge_intersect(tess_vertex * a,
|
||||
tess_vertex * b, tess_vertex * c, tess_vertex * d)
|
||||
{
|
||||
GLdouble denom, r, s;
|
||||
GLdouble xba, ydc, yba, xdc, yac, xac;
|
||||
|
||||
xba = b->x - a->x;
|
||||
yba = b->y - a->y;
|
||||
xdc = d->x - c->x;
|
||||
ydc = d->y - c->y;
|
||||
xac = a->x - c->x;
|
||||
yac = a->y - c->y;
|
||||
denom = xba * ydc - yba * xdc;
|
||||
r = yac * xdc - xac * ydc;
|
||||
/* parallel? */
|
||||
if (fabs(denom) < EPSILON) {
|
||||
if (fabs(r) < EPSILON) {
|
||||
/* colinear */
|
||||
if (fabs(xba) < EPSILON) {
|
||||
/* compare the Y coordinate */
|
||||
if (yba > 0.0) {
|
||||
if (
|
||||
(fabs(a->y - c->y) < EPSILON
|
||||
&& fabs(c->y - b->y) < EPSILON)
|
||||
|| (fabs(a->y - d->y) < EPSILON
|
||||
&& fabs(d->y - b->y) <
|
||||
EPSILON)) return GLU_TESS_ERROR4;
|
||||
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(fabs(b->y - c->y) < EPSILON
|
||||
&& fabs(c->y - a->y) < EPSILON)
|
||||
|| (fabs(b->y - d->y) < EPSILON
|
||||
&& fabs(d->y - a->y) <
|
||||
EPSILON)) return GLU_TESS_ERROR4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* compare the X coordinate */
|
||||
if (xba > 0.0) {
|
||||
if (
|
||||
(fabs(a->x - c->x) < EPSILON
|
||||
&& fabs(c->x - b->x) < EPSILON)
|
||||
|| (fabs(a->x - d->x) < EPSILON
|
||||
&& fabs(d->x - b->x) <
|
||||
EPSILON)) return GLU_TESS_ERROR4;
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(fabs(b->x - c->x) < EPSILON
|
||||
&& fabs(c->x - a->x) < EPSILON)
|
||||
|| (fabs(b->x - d->x) < EPSILON
|
||||
&& fabs(d->x - a->x) <
|
||||
EPSILON)) return GLU_TESS_ERROR4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
r /= denom;
|
||||
s = (yac * xba - xac * yba) / denom;
|
||||
/* test if one vertex lies on other edge */
|
||||
if (((fabs(r) < EPSILON || (r < 1.0 + EPSILON && r > 1.0 - EPSILON)) &&
|
||||
s > -EPSILON && s < 1.0 + EPSILON) ||
|
||||
((fabs(s) < EPSILON || (s < 1.0 + EPSILON && s > 1.0 - EPSILON)) &&
|
||||
r > -EPSILON && r < 1.0 + EPSILON)) {
|
||||
return GLU_TESS_ERROR4;
|
||||
}
|
||||
/* test for crossing */
|
||||
if (r > -EPSILON && r < 1.0 + EPSILON && s > -EPSILON && s < 1.0 + EPSILON) {
|
||||
return GLU_TESS_ERROR8;
|
||||
}
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
verify_edge_vertex_intersections(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_vertex *vertex1, *last_vertex, *vertex2;
|
||||
GLenum test;
|
||||
|
||||
last_vertex = polygon->last_vertex;
|
||||
vertex1 = last_vertex;
|
||||
for (vertex2 = vertex1->next->next;
|
||||
vertex2->next != last_vertex; vertex2 = vertex2->next) {
|
||||
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
|
||||
vertex2->next);
|
||||
if (test != GLU_NO_ERROR) {
|
||||
tess_call_user_error(tobj, test);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
}
|
||||
for (vertex1 = polygon->vertices;
|
||||
vertex1->next->next != last_vertex; vertex1 = vertex1->next) {
|
||||
for (vertex2 = vertex1->next->next;
|
||||
vertex2 != last_vertex; vertex2 = vertex2->next) {
|
||||
test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
|
||||
vertex2->next);
|
||||
if (test != GLU_NO_ERROR) {
|
||||
tess_call_user_error(tobj, test);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef WIN32
|
||||
__cdecl
|
||||
#endif
|
||||
area_compare(const void *a, const void *b)
|
||||
{
|
||||
GLdouble area1, area2;
|
||||
|
||||
area1 = (*((tess_contour **) a))->area;
|
||||
area2 = (*((tess_contour **) b))->area;
|
||||
if (area1 < area2)
|
||||
return 1;
|
||||
if (area1 > area2)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tess_find_contour_hierarchies(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_contour **contours; /* dinamic array of pointers */
|
||||
tess_contour *tmp_contour_ptr = tobj->contours;
|
||||
GLuint cnt, i;
|
||||
GLenum result;
|
||||
GLboolean hierarchy_changed;
|
||||
|
||||
/* any contours? */
|
||||
if (tobj->contour_cnt < 2) {
|
||||
tobj->contours->type = GLU_EXTERIOR;
|
||||
return;
|
||||
}
|
||||
if ((contours = (tess_contour **)
|
||||
malloc(sizeof(tess_contour *) * (tobj->contour_cnt))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
for (tmp_contour_ptr = tobj->contours, cnt = 0;
|
||||
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next)
|
||||
contours[cnt++] = tmp_contour_ptr;
|
||||
/* now sort the contours in decreasing area size order */
|
||||
qsort((void *) contours, (size_t) cnt, (size_t) sizeof(tess_contour *),
|
||||
area_compare);
|
||||
/* we leave just the first contour - remove others from list */
|
||||
tobj->contours = contours[0];
|
||||
tobj->contours->next = tobj->contours->previous = NULL;
|
||||
tobj->last_contour = tobj->contours;
|
||||
tobj->contour_cnt = 1;
|
||||
/* first contour is the one with greatest area */
|
||||
/* must be EXTERIOR */
|
||||
tobj->contours->type = GLU_EXTERIOR;
|
||||
tmp_contour_ptr = tobj->contours;
|
||||
/* now we play! */
|
||||
for (i = 1; i < cnt; i++) {
|
||||
hierarchy_changed = GL_FALSE;
|
||||
for (tmp_contour_ptr = tobj->contours;
|
||||
tmp_contour_ptr != NULL; tmp_contour_ptr = tmp_contour_ptr->next) {
|
||||
if (tmp_contour_ptr->type == GLU_EXTERIOR) {
|
||||
/* check if contour completely contained in EXTERIOR */
|
||||
result = is_contour_contained_in(tmp_contour_ptr, contours[i]);
|
||||
switch (result) {
|
||||
case GLU_INTERIOR:
|
||||
/* now we have to check if contour is inside interiors */
|
||||
/* or not */
|
||||
/* any interiors? */
|
||||
if (tmp_contour_ptr->next != NULL &&
|
||||
tmp_contour_ptr->next->type == GLU_INTERIOR) {
|
||||
/* for all interior, check if inside any of them */
|
||||
/* if not inside any of interiors, its another */
|
||||
/* interior */
|
||||
/* or it may contain some interiors, then change */
|
||||
/* the contained interiors to exterior ones */
|
||||
add_interior_with_hierarchy_check(tobj,
|
||||
tmp_contour_ptr,
|
||||
contours[i]);
|
||||
}
|
||||
else {
|
||||
/* not in interior, add as new interior contour */
|
||||
add_new_interior(tobj, tmp_contour_ptr, contours[i]);
|
||||
}
|
||||
hierarchy_changed = GL_TRUE;
|
||||
break;
|
||||
case GLU_EXTERIOR:
|
||||
/* ooops, the marked as EXTERIOR (contours[i]) is */
|
||||
/* actually an interior of tmp_contour_ptr */
|
||||
/* reverse the local hierarchy */
|
||||
reverse_hierarchy_and_add_exterior(tobj, tmp_contour_ptr,
|
||||
contours[i]);
|
||||
hierarchy_changed = GL_TRUE;
|
||||
break;
|
||||
case GLU_NO_ERROR:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (hierarchy_changed)
|
||||
break; /* break from for loop */
|
||||
}
|
||||
if (hierarchy_changed == GL_FALSE) {
|
||||
/* disjoint with all contours, add to contour list */
|
||||
add_new_exterior(tobj, contours[i]);
|
||||
}
|
||||
}
|
||||
free(contours);
|
||||
}
|
||||
|
||||
/* returns GLU_INTERIOR if inner is completey enclosed within outer */
|
||||
/* returns GLU_EXTERIOR if outer is completely enclosed within inner */
|
||||
/* returns GLU_NO_ERROR if contours are disjoint */
|
||||
static GLenum
|
||||
is_contour_contained_in(tess_contour * outer, tess_contour * inner)
|
||||
{
|
||||
GLenum relation_flag;
|
||||
|
||||
/* set relation_flag to relation of containment of first inner vertex */
|
||||
/* regarding outer contour */
|
||||
if (point_in_polygon(outer, inner->vertices->x, inner->vertices->y))
|
||||
relation_flag = GLU_INTERIOR;
|
||||
else
|
||||
relation_flag = GLU_EXTERIOR;
|
||||
if (relation_flag == GLU_INTERIOR)
|
||||
return GLU_INTERIOR;
|
||||
if (point_in_polygon(inner, outer->vertices->x, outer->vertices->y))
|
||||
return GLU_EXTERIOR;
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
point_in_polygon(tess_contour * contour, GLdouble x, GLdouble y)
|
||||
{
|
||||
tess_vertex *v1, *v2;
|
||||
GLuint i, vertex_cnt;
|
||||
GLdouble xp1, yp1, xp2, yp2;
|
||||
GLboolean tst;
|
||||
|
||||
tst = GL_FALSE;
|
||||
v1 = contour->vertices;
|
||||
v2 = contour->vertices->previous;
|
||||
for (i = 0, vertex_cnt = contour->vertex_cnt; i < vertex_cnt; i++) {
|
||||
xp1 = v1->x;
|
||||
yp1 = v1->y;
|
||||
xp2 = v2->x;
|
||||
yp2 = v2->y;
|
||||
if ((((yp1 <= y) && (y < yp2)) || ((yp2 <= y) && (y < yp1))) &&
|
||||
(x < (xp2 - xp1) * (y - yp1) / (yp2 - yp1) + xp1))
|
||||
tst = (tst == GL_FALSE ? GL_TRUE : GL_FALSE);
|
||||
v2 = v1;
|
||||
v1 = v1->next;
|
||||
}
|
||||
return tst;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
contours_overlap(tess_contour * contour, tess_polygon * polygon)
|
||||
{
|
||||
tess_vertex *vertex1, *vertex2;
|
||||
GLuint vertex1_cnt, vertex2_cnt, i, j;
|
||||
GLenum test;
|
||||
|
||||
vertex1 = contour->vertices;
|
||||
vertex2 = polygon->vertices;
|
||||
vertex1_cnt = contour->vertex_cnt;
|
||||
vertex2_cnt = polygon->vertex_cnt;
|
||||
for (i = 0; i < vertex1_cnt; vertex1 = vertex1->next, i++) {
|
||||
for (j = 0; j < vertex2_cnt; vertex2 = vertex2->next, j++)
|
||||
if ((test = edge_edge_intersect(vertex1, vertex1->next, vertex2,
|
||||
vertex2->next)) != GLU_NO_ERROR)
|
||||
return test;
|
||||
}
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
|
||||
static void
|
||||
add_new_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
contour->type = GLU_EXTERIOR;
|
||||
contour->next = NULL;
|
||||
contour->previous = tobj->last_contour;
|
||||
tobj->last_contour->next = contour;
|
||||
tobj->last_contour = contour;
|
||||
}
|
||||
|
||||
static void
|
||||
add_new_interior(GLUtriangulatorObj * tobj,
|
||||
tess_contour * outer, tess_contour * contour)
|
||||
{
|
||||
contour->type = GLU_INTERIOR;
|
||||
contour->next = outer->next;
|
||||
contour->previous = outer;
|
||||
if (outer->next != NULL)
|
||||
outer->next->previous = contour;
|
||||
outer->next = contour;
|
||||
if (tobj->last_contour == outer)
|
||||
tobj->last_contour = contour;
|
||||
}
|
||||
|
||||
static void
|
||||
add_interior_with_hierarchy_check(GLUtriangulatorObj * tobj,
|
||||
tess_contour * outer,
|
||||
tess_contour * contour)
|
||||
{
|
||||
tess_contour *ptr;
|
||||
|
||||
/* for all interiors of outer check if they are interior of contour */
|
||||
/* if so, change that interior to exterior and move it of of the */
|
||||
/* interior sequence */
|
||||
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
|
||||
GLenum test;
|
||||
|
||||
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
|
||||
ptr = ptr->next) {
|
||||
test = is_contour_contained_in(ptr, contour);
|
||||
switch (test) {
|
||||
case GLU_INTERIOR:
|
||||
/* contour is contained in one of the interiors */
|
||||
/* check if possibly contained in other exteriors */
|
||||
/* move ptr to first EXTERIOR */
|
||||
for (; ptr != NULL && ptr->type == GLU_INTERIOR; ptr = ptr->next);
|
||||
if (ptr == NULL)
|
||||
/* another exterior */
|
||||
add_new_exterior(tobj, contour);
|
||||
else
|
||||
add_exterior_with_check(tobj, ptr, contour);
|
||||
return;
|
||||
case GLU_EXTERIOR:
|
||||
/* one of the interiors is contained in the contour */
|
||||
/* change it to EXTERIOR, and shift it away from the */
|
||||
/* interior sequence */
|
||||
shift_interior_to_exterior(tobj, ptr);
|
||||
break;
|
||||
case GLU_NO_ERROR:
|
||||
/* disjoint */
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* add contour to the interior sequence */
|
||||
add_new_interior(tobj, outer, contour);
|
||||
}
|
||||
|
||||
static void
|
||||
reverse_hierarchy_and_add_exterior(GLUtriangulatorObj * tobj,
|
||||
tess_contour * outer,
|
||||
tess_contour * contour)
|
||||
{
|
||||
tess_contour *ptr;
|
||||
|
||||
/* reverse INTERIORS to EXTERIORS */
|
||||
/* any INTERIORS? */
|
||||
if (outer->next != NULL && outer->next->type == GLU_INTERIOR)
|
||||
for (ptr = outer->next; ptr != NULL && ptr->type == GLU_INTERIOR;
|
||||
ptr = ptr->next) ptr->type = GLU_EXTERIOR;
|
||||
/* the outer now becomes inner */
|
||||
outer->type = GLU_INTERIOR;
|
||||
/* contour is the EXTERIOR */
|
||||
contour->next = outer;
|
||||
if (tobj->contours == outer) {
|
||||
/* first contour beeing reversed */
|
||||
contour->previous = NULL;
|
||||
tobj->contours = contour;
|
||||
}
|
||||
else {
|
||||
outer->previous->next = contour;
|
||||
contour->previous = outer->previous;
|
||||
}
|
||||
outer->previous = contour;
|
||||
}
|
||||
|
||||
static void
|
||||
shift_interior_to_exterior(GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
contour->previous->next = contour->next;
|
||||
if (contour->next != NULL)
|
||||
contour->next->previous = contour->previous;
|
||||
else
|
||||
tobj->last_contour = contour->previous;
|
||||
}
|
||||
|
||||
static void
|
||||
add_exterior_with_check(GLUtriangulatorObj * tobj,
|
||||
tess_contour * outer, tess_contour * contour)
|
||||
{
|
||||
GLenum test;
|
||||
|
||||
/* this contour might be interior to further exteriors - check */
|
||||
/* if not, just add as a new exterior */
|
||||
for (; outer != NULL && outer->type == GLU_EXTERIOR; outer = outer->next) {
|
||||
test = is_contour_contained_in(outer, contour);
|
||||
switch (test) {
|
||||
case GLU_INTERIOR:
|
||||
/* now we have to check if contour is inside interiors */
|
||||
/* or not */
|
||||
/* any interiors? */
|
||||
if (outer->next != NULL && outer->next->type == GLU_INTERIOR) {
|
||||
/* for all interior, check if inside any of them */
|
||||
/* if not inside any of interiors, its another */
|
||||
/* interior */
|
||||
/* or it may contain some interiors, then change */
|
||||
/* the contained interiors to exterior ones */
|
||||
add_interior_with_hierarchy_check(tobj, outer, contour);
|
||||
}
|
||||
else {
|
||||
/* not in interior, add as new interior contour */
|
||||
add_new_interior(tobj, outer, contour);
|
||||
}
|
||||
return;
|
||||
case GLU_NO_ERROR:
|
||||
/* disjoint */
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
/* add contour to the exterior sequence */
|
||||
add_new_exterior(tobj, contour);
|
||||
}
|
||||
|
||||
void
|
||||
tess_handle_holes(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_contour *contour, *hole;
|
||||
GLenum exterior_orientation;
|
||||
|
||||
/* verify hole orientation */
|
||||
for (contour = tobj->contours; contour != NULL;) {
|
||||
exterior_orientation = contour->orientation;
|
||||
for (contour = contour->next;
|
||||
contour != NULL && contour->type == GLU_INTERIOR;
|
||||
contour = contour->next) {
|
||||
if (contour->orientation == exterior_orientation) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* now cut-out holes */
|
||||
for (contour = tobj->contours; contour != NULL;) {
|
||||
hole = contour->next;
|
||||
while (hole != NULL && hole->type == GLU_INTERIOR) {
|
||||
if (cut_out_hole(tobj, contour, hole) == GLU_ERROR)
|
||||
return;
|
||||
hole = contour->next;
|
||||
}
|
||||
contour = contour->next;
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum
|
||||
cut_out_hole(GLUtriangulatorObj * tobj,
|
||||
tess_contour * contour, tess_contour * hole)
|
||||
{
|
||||
tess_contour *tmp_hole;
|
||||
tess_vertex *v1, *v2, *tmp_vertex;
|
||||
GLuint vertex1_cnt, vertex2_cnt, tmp_vertex_cnt;
|
||||
GLuint i, j, k;
|
||||
GLenum test = 0;
|
||||
|
||||
/* find an edge connecting contour and hole not intersecting any other */
|
||||
/* edge belonging to either the contour or any of the other holes */
|
||||
for (v1 = contour->vertices, vertex1_cnt = contour->vertex_cnt, i = 0;
|
||||
i < vertex1_cnt; i++, v1 = v1->next) {
|
||||
for (v2 = hole->vertices, vertex2_cnt = hole->vertex_cnt, j = 0;
|
||||
j < vertex2_cnt; j++, v2 = v2->next) {
|
||||
/* does edge (v1,v2) intersect any edge of contour */
|
||||
for (tmp_vertex = contour->vertices, tmp_vertex_cnt =
|
||||
contour->vertex_cnt, k = 0; k < tmp_vertex_cnt;
|
||||
tmp_vertex = tmp_vertex->next, k++) {
|
||||
/* skip edge tests for edges directly connected */
|
||||
if (v1 == tmp_vertex || v1 == tmp_vertex->next)
|
||||
continue;
|
||||
test = edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
|
||||
if (test != GLU_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
if (test == GLU_NO_ERROR) {
|
||||
/* does edge (v1,v2) intersect any edge of hole */
|
||||
for (tmp_vertex = hole->vertices,
|
||||
tmp_vertex_cnt = hole->vertex_cnt, k = 0;
|
||||
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
|
||||
/* skip edge tests for edges directly connected */
|
||||
if (v2 == tmp_vertex || v2 == tmp_vertex->next)
|
||||
continue;
|
||||
test =
|
||||
edge_edge_intersect(v1, v2, tmp_vertex, tmp_vertex->next);
|
||||
if (test != GLU_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
if (test == GLU_NO_ERROR) {
|
||||
/* does edge (v1,v2) intersect any other hole? */
|
||||
for (tmp_hole = hole->next;
|
||||
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
|
||||
tmp_hole = tmp_hole->next) {
|
||||
/* does edge (v1,v2) intersect any edge of hole */
|
||||
for (tmp_vertex = tmp_hole->vertices,
|
||||
tmp_vertex_cnt = tmp_hole->vertex_cnt, k = 0;
|
||||
k < tmp_vertex_cnt; tmp_vertex = tmp_vertex->next, k++) {
|
||||
test = edge_edge_intersect(v1, v2, tmp_vertex,
|
||||
tmp_vertex->next);
|
||||
if (test != GLU_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
if (test != GLU_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (test == GLU_NO_ERROR) {
|
||||
/* edge (v1,v2) is good for eliminating the hole */
|
||||
if (merge_hole_with_contour(tobj, contour, hole, v1, v2)
|
||||
== GLU_NO_ERROR)
|
||||
return GLU_NO_ERROR;
|
||||
else
|
||||
return GLU_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* other holes are blocking all possible connections of hole */
|
||||
/* with contour, we shift this hole as the last hole and retry */
|
||||
for (tmp_hole = hole;
|
||||
tmp_hole != NULL && tmp_hole->type == GLU_INTERIOR;
|
||||
tmp_hole = tmp_hole->next);
|
||||
contour->next = hole->next;
|
||||
hole->next->previous = contour;
|
||||
if (tmp_hole == NULL) {
|
||||
/* last EXTERIOR contour, shift hole as last contour */
|
||||
hole->next = NULL;
|
||||
hole->previous = tobj->last_contour;
|
||||
tobj->last_contour->next = hole;
|
||||
tobj->last_contour = hole;
|
||||
}
|
||||
else {
|
||||
tmp_hole->previous->next = hole;
|
||||
hole->previous = tmp_hole->previous;
|
||||
tmp_hole->previous = hole;
|
||||
hole->next = tmp_hole;
|
||||
}
|
||||
hole = contour->next;
|
||||
/* try once again - recurse */
|
||||
return cut_out_hole(tobj, contour, hole);
|
||||
}
|
||||
|
||||
static GLenum
|
||||
merge_hole_with_contour(GLUtriangulatorObj * tobj,
|
||||
tess_contour * contour,
|
||||
tess_contour * hole,
|
||||
tess_vertex * v1, tess_vertex * v2)
|
||||
{
|
||||
tess_vertex *v1_new, *v2_new;
|
||||
|
||||
/* make copies of v1 and v2, place them respectively after their originals */
|
||||
if ((v1_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
if ((v2_new = (tess_vertex *) malloc(sizeof(tess_vertex))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return GLU_ERROR;
|
||||
}
|
||||
v1_new->edge_flag = GL_TRUE;
|
||||
v1_new->data = v1->data;
|
||||
v1_new->location[0] = v1->location[0];
|
||||
v1_new->location[1] = v1->location[1];
|
||||
v1_new->location[2] = v1->location[2];
|
||||
v1_new->x = v1->x;
|
||||
v1_new->y = v1->y;
|
||||
v1_new->shadow_vertex = v1;
|
||||
v1->shadow_vertex = v1_new;
|
||||
v1_new->next = v1->next;
|
||||
v1_new->previous = v1;
|
||||
v1->next->previous = v1_new;
|
||||
v1->next = v1_new;
|
||||
v2_new->edge_flag = GL_TRUE;
|
||||
v2_new->data = v2->data;
|
||||
v2_new->location[0] = v2->location[0];
|
||||
v2_new->location[1] = v2->location[1];
|
||||
v2_new->location[2] = v2->location[2];
|
||||
v2_new->x = v2->x;
|
||||
v2_new->y = v2->y;
|
||||
v2_new->shadow_vertex = v2;
|
||||
v2->shadow_vertex = v2_new;
|
||||
v2_new->next = v2->next;
|
||||
v2_new->previous = v2;
|
||||
v2->next->previous = v2_new;
|
||||
v2->next = v2_new;
|
||||
/* link together the two lists */
|
||||
v1->next = v2_new;
|
||||
v2_new->previous = v1;
|
||||
v2->next = v1_new;
|
||||
v1_new->previous = v2;
|
||||
/* update the vertex count of the contour */
|
||||
contour->vertex_cnt += hole->vertex_cnt + 2;
|
||||
/* remove the INTERIOR contour */
|
||||
contour->next = hole->next;
|
||||
if (hole->next != NULL)
|
||||
hole->next->previous = contour;
|
||||
free(hole);
|
||||
/* update tobj structure */
|
||||
--(tobj->contour_cnt);
|
||||
if (contour->last_vertex == v1)
|
||||
contour->last_vertex = v1_new;
|
||||
/* mark two vertices with edge_flag */
|
||||
v2->edge_flag = GL_FALSE;
|
||||
v1->edge_flag = GL_FALSE;
|
||||
return GLU_NO_ERROR;
|
||||
}
|
||||
402
src/glu/mini/project.c
Normal file
402
src/glu/mini/project.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/* $Id: project.c,v 1.1.2.1 2003/03/21 13:02:18 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "gluP.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr).
|
||||
* Thanks Marc!!!
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* implementation de gluProject et gluUnproject */
|
||||
/* M. Buffat 17/2/95 */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in
|
||||
* Input: m - the 4x4 matrix
|
||||
* in - the 4x1 vector
|
||||
* Output: out - the resulting 4x1 vector.
|
||||
*/
|
||||
static void
|
||||
transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
|
||||
{
|
||||
#define M(row,col) m[col*4+row]
|
||||
out[0] =
|
||||
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
|
||||
out[1] =
|
||||
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
|
||||
out[2] =
|
||||
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
|
||||
out[3] =
|
||||
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
|
||||
#undef M
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Perform a 4x4 matrix multiplication (product = a x b).
|
||||
* Input: a, b - matrices to multiply
|
||||
* Output: product - product of a and b
|
||||
*/
|
||||
static void
|
||||
matmul(GLdouble * product, const GLdouble * a, const GLdouble * b)
|
||||
{
|
||||
/* This matmul was contributed by Thomas Malik */
|
||||
GLdouble temp[16];
|
||||
GLint i;
|
||||
|
||||
#define A(row,col) a[(col<<2)+row]
|
||||
#define B(row,col) b[(col<<2)+row]
|
||||
#define T(row,col) temp[(col<<2)+row]
|
||||
|
||||
/* i-te Zeile */
|
||||
for (i = 0; i < 4; i++) {
|
||||
T(i, 0) =
|
||||
A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i,
|
||||
3) *
|
||||
B(3, 0);
|
||||
T(i, 1) =
|
||||
A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i,
|
||||
3) *
|
||||
B(3, 1);
|
||||
T(i, 2) =
|
||||
A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i,
|
||||
3) *
|
||||
B(3, 2);
|
||||
T(i, 3) =
|
||||
A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i,
|
||||
3) *
|
||||
B(3, 3);
|
||||
}
|
||||
|
||||
#undef A
|
||||
#undef B
|
||||
#undef T
|
||||
MEMCPY(product, temp, 16 * sizeof(GLdouble));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Compute inverse of 4x4 transformation matrix.
|
||||
* Code contributed by Jacques Leroy jle@star.be
|
||||
* Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
|
||||
*/
|
||||
static GLboolean
|
||||
invert_matrix(const GLdouble * m, GLdouble * out)
|
||||
{
|
||||
/* NB. OpenGL Matrices are COLUMN major. */
|
||||
#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
|
||||
#define MAT(m,r,c) (m)[(c)*4+(r)]
|
||||
|
||||
GLdouble wtmp[4][8];
|
||||
GLdouble m0, m1, m2, m3, s;
|
||||
GLdouble *r0, *r1, *r2, *r3;
|
||||
|
||||
r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
|
||||
|
||||
r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1),
|
||||
r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3),
|
||||
r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
|
||||
r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1),
|
||||
r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3),
|
||||
r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
|
||||
r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1),
|
||||
r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3),
|
||||
r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
|
||||
r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1),
|
||||
r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3),
|
||||
r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
|
||||
|
||||
/* choose pivot - or die */
|
||||
if (fabs(r3[0]) > fabs(r2[0]))
|
||||
SWAP_ROWS(r3, r2);
|
||||
if (fabs(r2[0]) > fabs(r1[0]))
|
||||
SWAP_ROWS(r2, r1);
|
||||
if (fabs(r1[0]) > fabs(r0[0]))
|
||||
SWAP_ROWS(r1, r0);
|
||||
if (0.0 == r0[0])
|
||||
return GL_FALSE;
|
||||
|
||||
/* eliminate first variable */
|
||||
m1 = r1[0] / r0[0];
|
||||
m2 = r2[0] / r0[0];
|
||||
m3 = r3[0] / r0[0];
|
||||
s = r0[1];
|
||||
r1[1] -= m1 * s;
|
||||
r2[1] -= m2 * s;
|
||||
r3[1] -= m3 * s;
|
||||
s = r0[2];
|
||||
r1[2] -= m1 * s;
|
||||
r2[2] -= m2 * s;
|
||||
r3[2] -= m3 * s;
|
||||
s = r0[3];
|
||||
r1[3] -= m1 * s;
|
||||
r2[3] -= m2 * s;
|
||||
r3[3] -= m3 * s;
|
||||
s = r0[4];
|
||||
if (s != 0.0) {
|
||||
r1[4] -= m1 * s;
|
||||
r2[4] -= m2 * s;
|
||||
r3[4] -= m3 * s;
|
||||
}
|
||||
s = r0[5];
|
||||
if (s != 0.0) {
|
||||
r1[5] -= m1 * s;
|
||||
r2[5] -= m2 * s;
|
||||
r3[5] -= m3 * s;
|
||||
}
|
||||
s = r0[6];
|
||||
if (s != 0.0) {
|
||||
r1[6] -= m1 * s;
|
||||
r2[6] -= m2 * s;
|
||||
r3[6] -= m3 * s;
|
||||
}
|
||||
s = r0[7];
|
||||
if (s != 0.0) {
|
||||
r1[7] -= m1 * s;
|
||||
r2[7] -= m2 * s;
|
||||
r3[7] -= m3 * s;
|
||||
}
|
||||
|
||||
/* choose pivot - or die */
|
||||
if (fabs(r3[1]) > fabs(r2[1]))
|
||||
SWAP_ROWS(r3, r2);
|
||||
if (fabs(r2[1]) > fabs(r1[1]))
|
||||
SWAP_ROWS(r2, r1);
|
||||
if (0.0 == r1[1])
|
||||
return GL_FALSE;
|
||||
|
||||
/* eliminate second variable */
|
||||
m2 = r2[1] / r1[1];
|
||||
m3 = r3[1] / r1[1];
|
||||
r2[2] -= m2 * r1[2];
|
||||
r3[2] -= m3 * r1[2];
|
||||
r2[3] -= m2 * r1[3];
|
||||
r3[3] -= m3 * r1[3];
|
||||
s = r1[4];
|
||||
if (0.0 != s) {
|
||||
r2[4] -= m2 * s;
|
||||
r3[4] -= m3 * s;
|
||||
}
|
||||
s = r1[5];
|
||||
if (0.0 != s) {
|
||||
r2[5] -= m2 * s;
|
||||
r3[5] -= m3 * s;
|
||||
}
|
||||
s = r1[6];
|
||||
if (0.0 != s) {
|
||||
r2[6] -= m2 * s;
|
||||
r3[6] -= m3 * s;
|
||||
}
|
||||
s = r1[7];
|
||||
if (0.0 != s) {
|
||||
r2[7] -= m2 * s;
|
||||
r3[7] -= m3 * s;
|
||||
}
|
||||
|
||||
/* choose pivot - or die */
|
||||
if (fabs(r3[2]) > fabs(r2[2]))
|
||||
SWAP_ROWS(r3, r2);
|
||||
if (0.0 == r2[2])
|
||||
return GL_FALSE;
|
||||
|
||||
/* eliminate third variable */
|
||||
m3 = r3[2] / r2[2];
|
||||
r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
|
||||
r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
|
||||
|
||||
/* last check */
|
||||
if (0.0 == r3[3])
|
||||
return GL_FALSE;
|
||||
|
||||
s = 1.0 / r3[3]; /* now back substitute row 3 */
|
||||
r3[4] *= s;
|
||||
r3[5] *= s;
|
||||
r3[6] *= s;
|
||||
r3[7] *= s;
|
||||
|
||||
m2 = r2[3]; /* now back substitute row 2 */
|
||||
s = 1.0 / r2[2];
|
||||
r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
|
||||
r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
|
||||
m1 = r1[3];
|
||||
r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
|
||||
r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
|
||||
m0 = r0[3];
|
||||
r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
|
||||
r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
|
||||
|
||||
m1 = r1[2]; /* now back substitute row 1 */
|
||||
s = 1.0 / r1[1];
|
||||
r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
|
||||
r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
|
||||
m0 = r0[2];
|
||||
r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
|
||||
r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
|
||||
|
||||
m0 = r0[1]; /* now back substitute row 0 */
|
||||
s = 1.0 / r0[0];
|
||||
r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
|
||||
r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
|
||||
|
||||
MAT(out, 0, 0) = r0[4];
|
||||
MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6];
|
||||
MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4];
|
||||
MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6];
|
||||
MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4];
|
||||
MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6];
|
||||
MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4];
|
||||
MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6];
|
||||
MAT(out, 3, 3) = r3[7];
|
||||
|
||||
return GL_TRUE;
|
||||
|
||||
#undef MAT
|
||||
#undef SWAP_ROWS
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */
|
||||
GLint GLAPIENTRY
|
||||
gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
|
||||
const GLdouble model[16], const GLdouble proj[16],
|
||||
const GLint viewport[4],
|
||||
GLdouble * winx, GLdouble * winy, GLdouble * winz)
|
||||
{
|
||||
/* matrice de transformation */
|
||||
GLdouble in[4], out[4];
|
||||
|
||||
/* initilise la matrice et le vecteur a transformer */
|
||||
in[0] = objx;
|
||||
in[1] = objy;
|
||||
in[2] = objz;
|
||||
in[3] = 1.0;
|
||||
transform_point(out, model, in);
|
||||
transform_point(in, proj, out);
|
||||
|
||||
/* d'ou le resultat normalise entre -1 et 1 */
|
||||
if (in[3] == 0.0)
|
||||
return GL_FALSE;
|
||||
|
||||
in[0] /= in[3];
|
||||
in[1] /= in[3];
|
||||
in[2] /= in[3];
|
||||
|
||||
/* en coordonnees ecran */
|
||||
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
|
||||
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
|
||||
/* entre 0 et 1 suivant z */
|
||||
*winz = (1 + in[2]) / 2;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* transformation du point ecran (winx,winy,winz) en point objet */
|
||||
GLint GLAPIENTRY
|
||||
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
|
||||
const GLdouble model[16], const GLdouble proj[16],
|
||||
const GLint viewport[4],
|
||||
GLdouble * objx, GLdouble * objy, GLdouble * objz)
|
||||
{
|
||||
/* matrice de transformation */
|
||||
GLdouble m[16], A[16];
|
||||
GLdouble in[4], out[4];
|
||||
|
||||
/* transformation coordonnees normalisees entre -1 et 1 */
|
||||
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
|
||||
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
|
||||
in[2] = 2 * winz - 1.0;
|
||||
in[3] = 1.0;
|
||||
|
||||
/* calcul transformation inverse */
|
||||
matmul(A, proj, model);
|
||||
invert_matrix(A, m);
|
||||
|
||||
/* d'ou les coordonnees objets */
|
||||
transform_point(out, m, in);
|
||||
if (out[3] == 0.0)
|
||||
return GL_FALSE;
|
||||
*objx = out[0] / out[3];
|
||||
*objy = out[1] / out[3];
|
||||
*objz = out[2] / out[3];
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* New in GLU 1.3
|
||||
* This is like gluUnProject but also takes near and far DepthRange values.
|
||||
*/
|
||||
#ifdef GLU_VERSION_1_3
|
||||
GLint GLAPIENTRY
|
||||
gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
|
||||
const GLdouble modelMatrix[16],
|
||||
const GLdouble projMatrix[16],
|
||||
const GLint viewport[4],
|
||||
GLclampd nearZ, GLclampd farZ,
|
||||
GLdouble * objx, GLdouble * objy, GLdouble * objz,
|
||||
GLdouble * objw)
|
||||
{
|
||||
/* matrice de transformation */
|
||||
GLdouble m[16], A[16];
|
||||
GLdouble in[4], out[4];
|
||||
GLdouble z = nearZ + winz * (farZ - nearZ);
|
||||
|
||||
/* transformation coordonnees normalisees entre -1 et 1 */
|
||||
in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
|
||||
in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
|
||||
in[2] = 2.0 * z - 1.0;
|
||||
in[3] = clipw;
|
||||
|
||||
/* calcul transformation inverse */
|
||||
matmul(A, projMatrix, modelMatrix);
|
||||
invert_matrix(A, m);
|
||||
|
||||
/* d'ou les coordonnees objets */
|
||||
transform_point(out, m, in);
|
||||
if (out[3] == 0.0)
|
||||
return GL_FALSE;
|
||||
*objx = out[0] / out[3];
|
||||
*objy = out[1] / out[3];
|
||||
*objz = out[2] / out[3];
|
||||
*objw = out[3];
|
||||
return GL_TRUE;
|
||||
}
|
||||
#endif
|
||||
774
src/glu/mini/quadric.c
Normal file
774
src/glu/mini/quadric.c
Normal file
@@ -0,0 +1,774 @@
|
||||
/* $Id: quadric.c,v 1.1.2.1 2003/03/21 13:02:22 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1999-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/* TODO:
|
||||
* texture coordinate support
|
||||
* flip normals according to orientation
|
||||
* there's still some inside/outside orientation bugs in possibly all
|
||||
* but the sphere function
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gluP.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI (3.1415926)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Convert degrees to radians:
|
||||
*/
|
||||
#define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
|
||||
|
||||
|
||||
/*
|
||||
* Sin and Cos for degree angles:
|
||||
*/
|
||||
#define SIND( A ) sin( (A)*(M_PI/180.0) )
|
||||
#define COSD( A) cos( (A)*(M_PI/180.0) )
|
||||
|
||||
|
||||
/*
|
||||
* Texture coordinates if texture flag is set
|
||||
*/
|
||||
#define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
|
||||
|
||||
|
||||
|
||||
struct GLUquadric
|
||||
{
|
||||
GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
|
||||
GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
|
||||
GLboolean TextureFlag; /* Generate texture coords? */
|
||||
GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
|
||||
void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Process a GLU error.
|
||||
*/
|
||||
static void
|
||||
quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
|
||||
{
|
||||
/* Call the error call back function if any */
|
||||
if (qobj->ErrorFunc) {
|
||||
(*qobj->ErrorFunc) (error);
|
||||
}
|
||||
/* Print a message to stdout if MESA_DEBUG variable is defined */
|
||||
if (getenv("MESA_DEBUG")) {
|
||||
fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
|
||||
msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GLUquadricObj *GLAPIENTRY
|
||||
gluNewQuadric(void)
|
||||
{
|
||||
GLUquadricObj *q;
|
||||
|
||||
q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
|
||||
if (q) {
|
||||
q->DrawStyle = GLU_FILL;
|
||||
q->Orientation = GLU_OUTSIDE;
|
||||
q->TextureFlag = GL_FALSE;
|
||||
q->Normals = GLU_SMOOTH;
|
||||
q->ErrorFunc = NULL;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluDeleteQuadric(GLUquadricObj * state)
|
||||
{
|
||||
if (state) {
|
||||
free((void *) state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
|
||||
* or GLU_POINT.
|
||||
*/
|
||||
void GLAPIENTRY
|
||||
gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
|
||||
{
|
||||
if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
|
||||
|| drawStyle == GLU_SILHOUETTE
|
||||
|| drawStyle == GLU_POINT)) {
|
||||
quadObject->DrawStyle = drawStyle;
|
||||
}
|
||||
else {
|
||||
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
|
||||
*/
|
||||
void GLAPIENTRY
|
||||
gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
|
||||
{
|
||||
if (quadObject
|
||||
&& (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
|
||||
quadObject->Orientation = orientation;
|
||||
}
|
||||
else {
|
||||
quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set the error handler callback function.
|
||||
*/
|
||||
void GLAPIENTRY
|
||||
gluQuadricCallback(GLUquadricObj * qobj,
|
||||
GLenum which, void (GLCALLBACK * fn) ())
|
||||
{
|
||||
/*
|
||||
* UGH, this is a mess! I thought ANSI was a standard.
|
||||
*/
|
||||
if (qobj && which == GLU_ERROR) {
|
||||
#ifdef __CYGWIN32__
|
||||
qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
|
||||
#elif defined(OPENSTEP)
|
||||
qobj->ErrorFunc = (void (*)(GLenum)) fn;
|
||||
#elif defined(_WIN32)
|
||||
qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
|
||||
#elif defined(__STORM__)
|
||||
qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
|
||||
#elif defined(__BEOS__)
|
||||
qobj->ErrorFunc = (void (*)(GLenum)) fn;
|
||||
#else
|
||||
qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
|
||||
{
|
||||
if (quadObject
|
||||
&& (normals == GLU_NONE || normals == GLU_FLAT
|
||||
|| normals == GLU_SMOOTH)) {
|
||||
quadObject->Normals = normals;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
|
||||
{
|
||||
if (quadObject) {
|
||||
quadObject->TextureFlag = textureCoords;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Call glNormal3f after scaling normal to unit length.
|
||||
*/
|
||||
static void
|
||||
normal3f(GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluCylinder(GLUquadricObj * qobj,
|
||||
GLdouble baseRadius, GLdouble topRadius,
|
||||
GLdouble height, GLint slices, GLint stacks)
|
||||
{
|
||||
GLdouble da, r, dr, dz;
|
||||
GLfloat x, y, z, nz, nsign;
|
||||
GLint i, j;
|
||||
|
||||
if (qobj->Orientation == GLU_INSIDE) {
|
||||
nsign = -1.0;
|
||||
}
|
||||
else {
|
||||
nsign = 1.0;
|
||||
}
|
||||
|
||||
da = 2.0 * M_PI / slices;
|
||||
dr = (topRadius - baseRadius) / stacks;
|
||||
dz = height / stacks;
|
||||
nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
|
||||
|
||||
if (qobj->DrawStyle == GLU_POINT) {
|
||||
glBegin(GL_POINTS);
|
||||
for (i = 0; i < slices; i++) {
|
||||
x = cos(i * da);
|
||||
y = sin(i * da);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
|
||||
z = 0.0;
|
||||
r = baseRadius;
|
||||
for (j = 0; j <= stacks; j++) {
|
||||
glVertex3f(x * r, y * r, z);
|
||||
z += dz;
|
||||
r += dr;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
|
||||
/* Draw rings */
|
||||
if (qobj->DrawStyle == GLU_LINE) {
|
||||
z = 0.0;
|
||||
r = baseRadius;
|
||||
for (j = 0; j <= stacks; j++) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (i = 0; i < slices; i++) {
|
||||
x = cos(i * da);
|
||||
y = sin(i * da);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
glVertex3f(x * r, y * r, z);
|
||||
}
|
||||
glEnd();
|
||||
z += dz;
|
||||
r += dr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* draw one ring at each end */
|
||||
if (baseRadius != 0.0) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (i = 0; i < slices; i++) {
|
||||
x = cos(i * da);
|
||||
y = sin(i * da);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
|
||||
}
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (i = 0; i < slices; i++) {
|
||||
x = cos(i * da);
|
||||
y = sin(i * da);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
glVertex3f(x * topRadius, y * topRadius, height);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
/* draw length lines */
|
||||
glBegin(GL_LINES);
|
||||
for (i = 0; i < slices; i++) {
|
||||
x = cos(i * da);
|
||||
y = sin(i * da);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
glVertex3f(x * baseRadius, y * baseRadius, 0.0);
|
||||
glVertex3f(x * topRadius, y * topRadius, height);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_FILL) {
|
||||
GLfloat ds = 1.0 / slices;
|
||||
GLfloat dt = 1.0 / stacks;
|
||||
GLfloat t = 0.0;
|
||||
z = 0.0;
|
||||
r = baseRadius;
|
||||
for (j = 0; j < stacks; j++) {
|
||||
GLfloat s = 0.0;
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= slices; i++) {
|
||||
GLfloat x, y;
|
||||
if (i == slices) {
|
||||
x = sin(0.0);
|
||||
y = cos(0.0);
|
||||
}
|
||||
else {
|
||||
x = sin(i * da);
|
||||
y = cos(i * da);
|
||||
}
|
||||
if (nsign == 1.0) {
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
TXTR_COORD(s, t);
|
||||
glVertex3f(x * r, y * r, z);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
TXTR_COORD(s, t + dt);
|
||||
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
|
||||
}
|
||||
else {
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
TXTR_COORD(s, t);
|
||||
glVertex3f(x * r, y * r, z);
|
||||
normal3f(x * nsign, y * nsign, nz * nsign);
|
||||
TXTR_COORD(s, t + dt);
|
||||
glVertex3f(x * (r + dr), y * (r + dr), z + dz);
|
||||
}
|
||||
s += ds;
|
||||
} /* for slices */
|
||||
glEnd();
|
||||
r += dr;
|
||||
t += dt;
|
||||
z += dz;
|
||||
} /* for stacks */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
|
||||
{
|
||||
GLfloat rho, drho, theta, dtheta;
|
||||
GLfloat x, y, z;
|
||||
GLfloat s, t, ds, dt;
|
||||
GLint i, j, imin, imax;
|
||||
GLboolean normals;
|
||||
GLfloat nsign;
|
||||
|
||||
if (qobj->Normals == GLU_NONE) {
|
||||
normals = GL_FALSE;
|
||||
}
|
||||
else {
|
||||
normals = GL_TRUE;
|
||||
}
|
||||
if (qobj->Orientation == GLU_INSIDE) {
|
||||
nsign = -1.0;
|
||||
}
|
||||
else {
|
||||
nsign = 1.0;
|
||||
}
|
||||
|
||||
drho = M_PI / (GLfloat) stacks;
|
||||
dtheta = 2.0 * M_PI / (GLfloat) slices;
|
||||
|
||||
/* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
|
||||
/* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
|
||||
/* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
|
||||
|
||||
if (qobj->DrawStyle == GLU_FILL) {
|
||||
if (!qobj->TextureFlag) {
|
||||
/* draw +Z end as a triangle fan */
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
/* glNormal3f(0.0, 0.0, 1.0); */
|
||||
glVertex3f(0.0, 0.0, nsign * radius);
|
||||
for (j = 0; j <= slices; j++) {
|
||||
theta = (j == slices) ? 0.0 : j * dtheta;
|
||||
x = -sin(theta) * sin(drho);
|
||||
y = cos(theta) * sin(drho);
|
||||
z = nsign * cos(drho);
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
ds = 1.0 / slices;
|
||||
dt = 1.0 / stacks;
|
||||
t = 1.0; /* because loop now runs from 0 */
|
||||
if (qobj->TextureFlag) {
|
||||
imin = 0;
|
||||
imax = stacks;
|
||||
}
|
||||
else {
|
||||
imin = 1;
|
||||
imax = stacks - 1;
|
||||
}
|
||||
|
||||
/* draw intermediate stacks as quad strips */
|
||||
for (i = imin; i < imax; i++) {
|
||||
rho = i * drho;
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
s = 0.0;
|
||||
for (j = 0; j <= slices; j++) {
|
||||
theta = (j == slices) ? 0.0 : j * dtheta;
|
||||
x = -sin(theta) * sin(rho);
|
||||
y = cos(theta) * sin(rho);
|
||||
z = nsign * cos(rho);
|
||||
TXTR_COORD(s, t);
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
x = -sin(theta) * sin(rho + drho);
|
||||
y = cos(theta) * sin(rho + drho);
|
||||
z = nsign * cos(rho + drho);
|
||||
TXTR_COORD(s, t - dt);
|
||||
s += ds;
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
glEnd();
|
||||
t -= dt;
|
||||
}
|
||||
|
||||
if (!qobj->TextureFlag) {
|
||||
/* draw -Z end as a triangle fan */
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f(0.0, 0.0, -radius * nsign);
|
||||
rho = M_PI - drho;
|
||||
s = 1.0;
|
||||
t = dt;
|
||||
for (j = slices; j >= 0; j--) {
|
||||
theta = (j == slices) ? 0.0 : j * dtheta;
|
||||
x = -sin(theta) * sin(rho);
|
||||
y = cos(theta) * sin(rho);
|
||||
z = nsign * cos(rho);
|
||||
s -= ds;
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
|
||||
/* draw stack lines */
|
||||
for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
|
||||
rho = i * drho;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (j = 0; j < slices; j++) {
|
||||
theta = j * dtheta;
|
||||
x = cos(theta) * sin(rho);
|
||||
y = sin(theta) * sin(rho);
|
||||
z = cos(rho);
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
/* draw slice lines */
|
||||
for (j = 0; j < slices; j++) {
|
||||
theta = j * dtheta;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (i = 0; i <= stacks; i++) {
|
||||
rho = i * drho;
|
||||
x = cos(theta) * sin(rho);
|
||||
y = sin(theta) * sin(rho);
|
||||
z = cos(rho);
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_POINT) {
|
||||
/* top and bottom-most points */
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0.0, 0.0, radius);
|
||||
glVertex3f(0.0, 0.0, -radius);
|
||||
|
||||
/* loop over stacks */
|
||||
for (i = 1; i < stacks - 1; i++) {
|
||||
rho = i * drho;
|
||||
for (j = 0; j < slices; j++) {
|
||||
theta = j * dtheta;
|
||||
x = cos(theta) * sin(rho);
|
||||
y = sin(theta) * sin(rho);
|
||||
z = cos(rho);
|
||||
glVertex3f(x * radius, y * radius, z * radius);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluDisk(GLUquadricObj * qobj,
|
||||
GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
|
||||
{
|
||||
GLfloat da, dr;
|
||||
#if 0
|
||||
GLdouble a, da;
|
||||
GLfloat r, dr;
|
||||
GLfloat x, y;
|
||||
GLfloat r1, r2, dtc;
|
||||
GLint s, l;
|
||||
#endif
|
||||
|
||||
|
||||
da = 2.0 * M_PI / slices;
|
||||
dr = (outerRadius - innerRadius) / (GLfloat) loops;
|
||||
|
||||
switch (qobj->DrawStyle) {
|
||||
case GLU_FILL:
|
||||
{
|
||||
/* texture of a gluDisk is a cut out of the texture unit square
|
||||
* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
|
||||
* (linear mapping)
|
||||
*/
|
||||
GLfloat dtc = 2.0f * outerRadius;
|
||||
GLfloat sa, ca;
|
||||
GLfloat r1 = innerRadius;
|
||||
GLint l;
|
||||
for (l = 0; l < loops; l++) {
|
||||
GLfloat r2 = r1 + dr;
|
||||
if (qobj->Orientation == GLU_OUTSIDE) {
|
||||
GLint s;
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (s = 0; s <= slices; s++) {
|
||||
GLfloat a;
|
||||
if (s == slices)
|
||||
a = 0.0;
|
||||
else
|
||||
a = s * da;
|
||||
sa = sin(a);
|
||||
ca = cos(a);
|
||||
TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
|
||||
glVertex2f(r2 * sa, r2 * ca);
|
||||
TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
|
||||
glVertex2f(r1 * sa, r1 * ca);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
GLint s;
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (s = slices; s >= 0; s--) {
|
||||
GLfloat a;
|
||||
if (s == slices)
|
||||
a = 0.0;
|
||||
else
|
||||
a = s * da;
|
||||
sa = sin(a);
|
||||
ca = cos(a);
|
||||
TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
|
||||
glVertex2f(r2 * sa, r2 * ca);
|
||||
TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
|
||||
glVertex2f(r1 * sa, r1 * ca);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
r1 = r2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLU_LINE:
|
||||
{
|
||||
GLint l, s;
|
||||
/* draw loops */
|
||||
for (l = 0; l <= loops; l++) {
|
||||
GLfloat r = innerRadius + l * dr;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (s = 0; s < slices; s++) {
|
||||
GLfloat a = s * da;
|
||||
glVertex2f(r * sin(a), r * cos(a));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
/* draw spokes */
|
||||
for (s = 0; s < slices; s++) {
|
||||
GLfloat a = s * da;
|
||||
GLfloat x = sin(a);
|
||||
GLfloat y = cos(a);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (l = 0; l <= loops; l++) {
|
||||
GLfloat r = innerRadius + l * dr;
|
||||
glVertex2f(r * x, r * y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLU_POINT:
|
||||
{
|
||||
GLint s;
|
||||
glBegin(GL_POINTS);
|
||||
for (s = 0; s < slices; s++) {
|
||||
GLfloat a = s * da;
|
||||
GLfloat x = sin(a);
|
||||
GLfloat y = cos(a);
|
||||
GLint l;
|
||||
for (l = 0; l <= loops; l++) {
|
||||
GLfloat r = innerRadius * l * dr;
|
||||
glVertex2f(r * x, r * y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
break;
|
||||
}
|
||||
case GLU_SILHOUETTE:
|
||||
{
|
||||
if (innerRadius != 0.0) {
|
||||
GLfloat a;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (a = 0.0; a < 2.0 * M_PI; a += da) {
|
||||
GLfloat x = innerRadius * sin(a);
|
||||
GLfloat y = innerRadius * cos(a);
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
{
|
||||
GLfloat a;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for (a = 0; a < 2.0 * M_PI; a += da) {
|
||||
GLfloat x = outerRadius * sin(a);
|
||||
GLfloat y = outerRadius * cos(a);
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
|
||||
GLdouble outerRadius, GLint slices, GLint loops,
|
||||
GLdouble startAngle, GLdouble sweepAngle)
|
||||
{
|
||||
if (qobj->DrawStyle == GLU_POINT) {
|
||||
GLint loop, slice;
|
||||
GLdouble radius, delta_radius;
|
||||
GLdouble angle, delta_angle;
|
||||
delta_radius = (outerRadius - innerRadius) / (loops - 1);
|
||||
delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
|
||||
glBegin(GL_POINTS);
|
||||
radius = innerRadius;
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
for (slice = 0; slice < slices; slice++) {
|
||||
glVertex2f(radius * sin(angle), radius * cos(angle));
|
||||
angle += delta_angle;
|
||||
}
|
||||
radius += delta_radius;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_LINE) {
|
||||
GLint loop, slice;
|
||||
GLdouble radius, delta_radius;
|
||||
GLdouble angle, delta_angle;
|
||||
delta_radius = (outerRadius - innerRadius) / loops;
|
||||
delta_angle = DEG_TO_RAD(sweepAngle / slices);
|
||||
/* draw rings */
|
||||
radius = innerRadius;
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (slice = 0; slice <= slices; slice++) {
|
||||
glVertex2f(radius * sin(angle), radius * cos(angle));
|
||||
angle += delta_angle;
|
||||
}
|
||||
glEnd();
|
||||
radius += delta_radius;
|
||||
}
|
||||
/* draw spokes */
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
for (slice = 0; slice <= slices; slice++) {
|
||||
radius = innerRadius;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
glVertex2f(radius * sin(angle), radius * cos(angle));
|
||||
radius += delta_radius;
|
||||
}
|
||||
glEnd();
|
||||
angle += delta_angle;
|
||||
}
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_SILHOUETTE) {
|
||||
GLint slice;
|
||||
GLdouble angle, delta_angle;
|
||||
delta_angle = DEG_TO_RAD(sweepAngle / slices);
|
||||
/* draw outer ring */
|
||||
glBegin(GL_LINE_STRIP);
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
for (slice = 0; slice <= slices; slice++) {
|
||||
glVertex2f(outerRadius * sin(angle), outerRadius * cos(angle));
|
||||
angle += delta_angle;
|
||||
}
|
||||
glEnd();
|
||||
/* draw inner ring */
|
||||
if (innerRadius > 0.0) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
for (slice = 0; slice < slices; slice++) {
|
||||
glVertex2f(innerRadius * sin(angle), innerRadius * cos(angle));
|
||||
angle += delta_angle;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
/* draw spokes */
|
||||
if (sweepAngle < 360.0) {
|
||||
GLdouble stopAngle = startAngle + sweepAngle;
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(innerRadius * SIND(startAngle),
|
||||
innerRadius * COSD(startAngle));
|
||||
glVertex2f(outerRadius * SIND(startAngle),
|
||||
outerRadius * COSD(startAngle));
|
||||
glVertex2f(innerRadius * SIND(stopAngle),
|
||||
innerRadius * COSD(stopAngle));
|
||||
glVertex2f(outerRadius * SIND(stopAngle),
|
||||
outerRadius * COSD(stopAngle));
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
else if (qobj->DrawStyle == GLU_FILL) {
|
||||
GLint loop, slice;
|
||||
GLdouble radius, delta_radius;
|
||||
GLdouble angle, delta_angle;
|
||||
delta_radius = (outerRadius - innerRadius) / loops;
|
||||
delta_angle = DEG_TO_RAD(sweepAngle / slices);
|
||||
radius = innerRadius;
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
angle = DEG_TO_RAD(startAngle);
|
||||
for (slice = 0; slice <= slices; slice++) {
|
||||
if (qobj->Orientation == GLU_OUTSIDE) {
|
||||
glVertex2f((radius + delta_radius) * sin(angle),
|
||||
(radius + delta_radius) * cos(angle));
|
||||
glVertex2f(radius * sin(angle), radius * cos(angle));
|
||||
}
|
||||
else {
|
||||
glVertex2f(radius * sin(angle), radius * cos(angle));
|
||||
glVertex2f((radius + delta_radius) * sin(angle),
|
||||
(radius + delta_radius) * cos(angle));
|
||||
}
|
||||
angle += delta_angle;
|
||||
}
|
||||
glEnd();
|
||||
radius += delta_radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
328
src/glu/mini/tess.c
Normal file
328
src/glu/mini/tess.c
Normal file
@@ -0,0 +1,328 @@
|
||||
/* $Id: tess.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file is part of the polygon tesselation code contributed by
|
||||
* Bogdan Sikorski
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "tess.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This is ugly, but seems the easiest way to do things to make the
|
||||
* code work under YellowBox for Windows
|
||||
*/
|
||||
#if defined(OPENSTEP) && defined(CALLBACK)
|
||||
#undef CALLBACK
|
||||
#define CALLBACK
|
||||
#endif
|
||||
|
||||
|
||||
static void delete_contours(GLUtriangulatorObj *);
|
||||
|
||||
#ifdef __CYGWIN32__
|
||||
#define _CALLBACK
|
||||
#else
|
||||
#define _CALLBACK GLCALLBACK
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init_callbacks(tess_callbacks * callbacks)
|
||||
{
|
||||
callbacks->begin = (void (_CALLBACK *) (GLenum)) 0;
|
||||
callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0;
|
||||
callbacks->vertex = (void (_CALLBACK *) (void *)) 0;
|
||||
callbacks->end = (void (_CALLBACK *) (void)) 0;
|
||||
callbacks->error = (void (_CALLBACK *) (GLenum)) 0;
|
||||
}
|
||||
|
||||
void
|
||||
tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr)
|
||||
{
|
||||
if (tobj->error == GLU_NO_ERROR)
|
||||
tobj->error = gluerr;
|
||||
if (tobj->callbacks.error != NULL)
|
||||
(tobj->callbacks.error) (gluerr);
|
||||
}
|
||||
|
||||
GLUtriangulatorObj *GLAPIENTRY
|
||||
gluNewTess(void)
|
||||
{
|
||||
GLUtriangulatorObj *tobj;
|
||||
|
||||
if ((tobj = (GLUtriangulatorObj *)
|
||||
malloc(sizeof(struct GLUtesselator))) == NULL)
|
||||
return NULL;
|
||||
tobj->contours = tobj->last_contour = NULL;
|
||||
init_callbacks(&tobj->callbacks);
|
||||
tobj->error = GLU_NO_ERROR;
|
||||
tobj->current_polygon = NULL;
|
||||
tobj->contour_cnt = 0;
|
||||
return tobj;
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluTessCallback(GLUtriangulatorObj * tobj, GLenum which,
|
||||
void (GLCALLBACK * fn) ())
|
||||
{
|
||||
switch (which) {
|
||||
case GLU_BEGIN:
|
||||
tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn;
|
||||
break;
|
||||
case GLU_EDGE_FLAG:
|
||||
tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn;
|
||||
break;
|
||||
case GLU_VERTEX:
|
||||
tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn;
|
||||
break;
|
||||
case GLU_END:
|
||||
tobj->callbacks.end = (void (_CALLBACK *) (void)) fn;
|
||||
break;
|
||||
case GLU_ERROR:
|
||||
tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn;
|
||||
break;
|
||||
default:
|
||||
tobj->error = GLU_INVALID_ENUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluDeleteTess(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt)
|
||||
/* was gluEndPolygon called? */
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR1);
|
||||
/* delete all internal structures */
|
||||
delete_contours(tobj);
|
||||
free(tobj);
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluBeginPolygon(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
/*
|
||||
if(tobj->error!=GLU_NO_ERROR)
|
||||
return;
|
||||
*/
|
||||
tobj->error = GLU_NO_ERROR;
|
||||
if (tobj->current_polygon != NULL) {
|
||||
/* gluEndPolygon was not called */
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR1);
|
||||
/* delete all internal structures */
|
||||
delete_contours(tobj);
|
||||
}
|
||||
else {
|
||||
if ((tobj->current_polygon =
|
||||
(tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
tobj->current_polygon->vertex_cnt = 0;
|
||||
tobj->current_polygon->vertices =
|
||||
tobj->current_polygon->last_vertex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluEndPolygon(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
/*tess_contour *contour_ptr; */
|
||||
|
||||
/* there was an error */
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
goto end;
|
||||
|
||||
/* check if gluBeginPolygon was called */
|
||||
if (tobj->current_polygon == NULL) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR2);
|
||||
return;
|
||||
}
|
||||
tess_test_polygon(tobj);
|
||||
/* there was an error */
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
goto end;
|
||||
|
||||
/* any real contours? */
|
||||
if (tobj->contour_cnt == 0) {
|
||||
/* delete all internal structures */
|
||||
delete_contours(tobj);
|
||||
return;
|
||||
}
|
||||
tess_find_contour_hierarchies(tobj);
|
||||
/* there was an error */
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
goto end;
|
||||
|
||||
tess_handle_holes(tobj);
|
||||
/* there was an error */
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
goto end;
|
||||
|
||||
/* if no callbacks, nothing to do */
|
||||
if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL &&
|
||||
tobj->callbacks.end != NULL) {
|
||||
if (tobj->callbacks.edgeFlag == NULL)
|
||||
tess_tesselate(tobj);
|
||||
else
|
||||
tess_tesselate_with_edge_flag(tobj);
|
||||
}
|
||||
|
||||
end:
|
||||
/* delete all internal structures */
|
||||
delete_contours(tobj);
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluNextContour(GLUtriangulatorObj * tobj, GLenum type)
|
||||
{
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
if (tobj->current_polygon == NULL) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR2);
|
||||
return;
|
||||
}
|
||||
/* first contour? */
|
||||
if (tobj->current_polygon->vertex_cnt)
|
||||
tess_test_polygon(tobj);
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_vertex *last_vertex_ptr;
|
||||
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
if (polygon == NULL) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR2);
|
||||
return;
|
||||
}
|
||||
last_vertex_ptr = polygon->last_vertex;
|
||||
if (last_vertex_ptr == NULL) {
|
||||
if ((last_vertex_ptr = (tess_vertex *)
|
||||
malloc(sizeof(tess_vertex))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
polygon->vertices = last_vertex_ptr;
|
||||
polygon->last_vertex = last_vertex_ptr;
|
||||
last_vertex_ptr->data = data;
|
||||
last_vertex_ptr->location[0] = v[0];
|
||||
last_vertex_ptr->location[1] = v[1];
|
||||
last_vertex_ptr->location[2] = v[2];
|
||||
last_vertex_ptr->next = NULL;
|
||||
last_vertex_ptr->previous = NULL;
|
||||
++(polygon->vertex_cnt);
|
||||
}
|
||||
else {
|
||||
tess_vertex *vertex_ptr;
|
||||
|
||||
/* same point twice? */
|
||||
if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON &&
|
||||
fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON &&
|
||||
fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) {
|
||||
tess_call_user_error(tobj, GLU_TESS_ERROR6);
|
||||
return;
|
||||
}
|
||||
if ((vertex_ptr = (tess_vertex *)
|
||||
malloc(sizeof(tess_vertex))) == NULL) {
|
||||
tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
vertex_ptr->data = data;
|
||||
vertex_ptr->location[0] = v[0];
|
||||
vertex_ptr->location[1] = v[1];
|
||||
vertex_ptr->location[2] = v[2];
|
||||
vertex_ptr->next = NULL;
|
||||
vertex_ptr->previous = last_vertex_ptr;
|
||||
++(polygon->vertex_cnt);
|
||||
last_vertex_ptr->next = vertex_ptr;
|
||||
polygon->last_vertex = vertex_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
delete_contours(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_polygon *polygon = tobj->current_polygon;
|
||||
tess_contour *contour, *contour_tmp;
|
||||
tess_vertex *vertex, *vertex_tmp;
|
||||
|
||||
/* remove current_polygon list - if exists due to detected error */
|
||||
if (polygon != NULL) {
|
||||
if (polygon->vertices) {
|
||||
for (vertex = polygon->vertices; vertex != polygon->last_vertex;) {
|
||||
vertex_tmp = vertex->next;
|
||||
free(vertex);
|
||||
vertex = vertex_tmp;
|
||||
}
|
||||
free(vertex);
|
||||
}
|
||||
free(polygon);
|
||||
tobj->current_polygon = NULL;
|
||||
}
|
||||
/* remove all contour data */
|
||||
for (contour = tobj->contours; contour != NULL;) {
|
||||
for (vertex = contour->vertices; vertex != contour->last_vertex;) {
|
||||
vertex_tmp = vertex->next;
|
||||
free(vertex);
|
||||
vertex = vertex_tmp;
|
||||
}
|
||||
free(vertex);
|
||||
contour_tmp = contour->next;
|
||||
free(contour);
|
||||
contour = contour_tmp;
|
||||
}
|
||||
tobj->contours = tobj->last_contour = NULL;
|
||||
tobj->contour_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ)
|
||||
{
|
||||
/* dummy function */
|
||||
(void) tess;
|
||||
(void) valueX;
|
||||
(void) valueY;
|
||||
(void) valueZ;
|
||||
}
|
||||
108
src/glu/mini/tess.h
Normal file
108
src/glu/mini/tess.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* $Id: tess.h,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file is part of the polygon tesselation code contributed by
|
||||
* Bogdan Sikorski
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TESS_H
|
||||
#define TESS_H
|
||||
|
||||
|
||||
#include "gluP.h"
|
||||
|
||||
#define EPSILON 1e-06 /* epsilon for double precision compares */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OXY,
|
||||
OYZ,
|
||||
OXZ
|
||||
}
|
||||
projection_type;
|
||||
|
||||
typedef struct callbacks_str
|
||||
{
|
||||
void (GLCALLBACK * begin) (GLenum mode);
|
||||
void (GLCALLBACK * edgeFlag) (GLboolean flag);
|
||||
void (GLCALLBACK * vertex) (GLvoid * v);
|
||||
void (GLCALLBACK * end) (void);
|
||||
void (GLCALLBACK * error) (GLenum err);
|
||||
}
|
||||
tess_callbacks;
|
||||
|
||||
typedef struct vertex_str
|
||||
{
|
||||
void *data;
|
||||
GLdouble location[3];
|
||||
GLdouble x, y;
|
||||
GLboolean edge_flag;
|
||||
struct vertex_str *shadow_vertex;
|
||||
struct vertex_str *next, *previous;
|
||||
}
|
||||
tess_vertex;
|
||||
|
||||
typedef struct contour_str
|
||||
{
|
||||
GLenum type;
|
||||
GLuint vertex_cnt;
|
||||
GLdouble area;
|
||||
GLenum orientation;
|
||||
struct vertex_str *vertices, *last_vertex;
|
||||
struct contour_str *next, *previous;
|
||||
}
|
||||
tess_contour;
|
||||
|
||||
typedef struct polygon_str
|
||||
{
|
||||
GLuint vertex_cnt;
|
||||
GLdouble A, B, C, D;
|
||||
GLdouble area;
|
||||
GLenum orientation;
|
||||
struct vertex_str *vertices, *last_vertex;
|
||||
}
|
||||
tess_polygon;
|
||||
|
||||
struct GLUtesselator
|
||||
{
|
||||
tess_contour *contours, *last_contour;
|
||||
GLuint contour_cnt;
|
||||
tess_callbacks callbacks;
|
||||
tess_polygon *current_polygon;
|
||||
GLenum error;
|
||||
GLdouble A, B, C, D;
|
||||
projection_type projection;
|
||||
};
|
||||
|
||||
|
||||
extern void tess_call_user_error(GLUtriangulatorObj *, GLenum);
|
||||
extern void tess_test_polygon(GLUtriangulatorObj *);
|
||||
extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
|
||||
extern void tess_handle_holes(GLUtriangulatorObj *);
|
||||
extern void tess_tesselate(GLUtriangulatorObj *);
|
||||
extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
|
||||
|
||||
|
||||
#endif
|
||||
407
src/glu/mini/tesselat.c
Normal file
407
src/glu/mini/tesselat.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/* $Id: tesselat.c,v 1.1.2.1 2003/03/21 13:02:23 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.3
|
||||
* Copyright (C) 1995-2000 Brian Paul
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file is part of the polygon tesselation code contributed by
|
||||
* Bogdan Sikorski
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PC_HEADER
|
||||
#include "all.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "tess.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static GLboolean edge_flag;
|
||||
|
||||
static void emit_triangle(GLUtriangulatorObj *, tess_vertex *,
|
||||
tess_vertex *, tess_vertex *);
|
||||
|
||||
static void emit_triangle_with_edge_flag(GLUtriangulatorObj *,
|
||||
tess_vertex *, GLboolean,
|
||||
tess_vertex *, GLboolean,
|
||||
tess_vertex *, GLboolean);
|
||||
|
||||
static GLdouble
|
||||
twice_the_triangle_area(tess_vertex * va, tess_vertex * vb, tess_vertex * vc)
|
||||
{
|
||||
return (vb->x - va->x) * (vc->y - va->y) - (vb->y - va->y) * (vc->x -
|
||||
va->x);
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
left(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
|
||||
{
|
||||
if (A * x + B * y + C > -EPSILON)
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
right(GLdouble A, GLdouble B, GLdouble C, GLdouble x, GLdouble y)
|
||||
{
|
||||
if (A * x + B * y + C < EPSILON)
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLint
|
||||
convex_ccw(tess_vertex * va,
|
||||
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
|
||||
{
|
||||
GLdouble d;
|
||||
|
||||
d = twice_the_triangle_area(va, vb, vc);
|
||||
|
||||
if (d > EPSILON) {
|
||||
return 1;
|
||||
}
|
||||
else if (d < -EPSILON) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static GLint
|
||||
convex_cw(tess_vertex * va,
|
||||
tess_vertex * vb, tess_vertex * vc, GLUtriangulatorObj * tobj)
|
||||
{
|
||||
GLdouble d;
|
||||
|
||||
d = twice_the_triangle_area(va, vb, vc);
|
||||
|
||||
if (d < -EPSILON) {
|
||||
return 1;
|
||||
}
|
||||
else if (d > EPSILON) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
diagonal_ccw(tess_vertex * va,
|
||||
tess_vertex * vb,
|
||||
GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
|
||||
struct
|
||||
{
|
||||
GLdouble A, B, C;
|
||||
}
|
||||
ac, cb, ba;
|
||||
GLdouble x, y;
|
||||
|
||||
GLint res = convex_ccw(va, vc, vb, tobj);
|
||||
if (res == 0)
|
||||
return GL_FALSE;
|
||||
if (res == -1)
|
||||
return GL_TRUE;
|
||||
|
||||
ba.A = vb->y - va->y;
|
||||
ba.B = va->x - vb->x;
|
||||
ba.C = -ba.A * va->x - ba.B * va->y;
|
||||
ac.A = va->y - vc->y;
|
||||
ac.B = vc->x - va->x;
|
||||
ac.C = -ac.A * vc->x - ac.B * vc->y;
|
||||
cb.A = vc->y - vb->y;
|
||||
cb.B = vb->x - vc->x;
|
||||
cb.C = -cb.A * vb->x - cb.B * vb->y;
|
||||
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
|
||||
shadow_vertex = vertex->shadow_vertex;
|
||||
if (shadow_vertex != NULL &&
|
||||
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
|
||||
continue;
|
||||
x = vertex->x;
|
||||
y = vertex->y;
|
||||
if (left(ba.A, ba.B, ba.C, x, y) &&
|
||||
left(ac.A, ac.B, ac.C, x, y) && left(cb.A, cb.B, cb.C, x, y))
|
||||
return GL_FALSE;
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
diagonal_cw(tess_vertex * va,
|
||||
tess_vertex * vb,
|
||||
GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vc = va->next, *vertex, *shadow_vertex;
|
||||
struct
|
||||
{
|
||||
GLdouble A, B, C;
|
||||
}
|
||||
ac, cb, ba;
|
||||
GLdouble x, y;
|
||||
|
||||
GLint res = convex_cw(va, vc, vb, tobj);
|
||||
if (res == 0)
|
||||
return GL_FALSE;
|
||||
if (res == -1)
|
||||
return GL_TRUE;
|
||||
|
||||
ba.A = vb->y - va->y;
|
||||
ba.B = va->x - vb->x;
|
||||
ba.C = -ba.A * va->x - ba.B * va->y;
|
||||
ac.A = va->y - vc->y;
|
||||
ac.B = vc->x - va->x;
|
||||
ac.C = -ac.A * vc->x - ac.B * vc->y;
|
||||
cb.A = vc->y - vb->y;
|
||||
cb.B = vb->x - vc->x;
|
||||
cb.C = -cb.A * vb->x - cb.B * vb->y;
|
||||
for (vertex = vb->next; vertex != va; vertex = vertex->next) {
|
||||
shadow_vertex = vertex->shadow_vertex;
|
||||
if (shadow_vertex != NULL &&
|
||||
(shadow_vertex == va || shadow_vertex == vb || shadow_vertex == vc))
|
||||
continue;
|
||||
x = vertex->x;
|
||||
y = vertex->y;
|
||||
if (right(ba.A, ba.B, ba.C, x, y) &&
|
||||
right(ac.A, ac.B, ac.C, x, y) && right(cb.A, cb.B, cb.C, x, y))
|
||||
return GL_FALSE;
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clip_ear(GLUtriangulatorObj * tobj, tess_vertex * v, tess_contour * contour)
|
||||
{
|
||||
emit_triangle(tobj, v->previous, v, v->next);
|
||||
/* the first in the list */
|
||||
if (contour->vertices == v) {
|
||||
contour->vertices = v->next;
|
||||
contour->last_vertex->next = v->next;
|
||||
v->next->previous = contour->last_vertex;
|
||||
}
|
||||
else
|
||||
/* the last ? */
|
||||
if (contour->last_vertex == v) {
|
||||
contour->vertices->previous = v->previous;
|
||||
v->previous->next = v->next;
|
||||
contour->last_vertex = v->previous;
|
||||
}
|
||||
else {
|
||||
v->next->previous = v->previous;
|
||||
v->previous->next = v->next;
|
||||
}
|
||||
free(v);
|
||||
--(contour->vertex_cnt);
|
||||
}
|
||||
|
||||
static void
|
||||
clip_ear_with_edge_flag(GLUtriangulatorObj * tobj,
|
||||
tess_vertex * v, tess_contour * contour)
|
||||
{
|
||||
emit_triangle_with_edge_flag(tobj, v->previous, v->previous->edge_flag,
|
||||
v, v->edge_flag, v->next, GL_FALSE);
|
||||
v->previous->edge_flag = GL_FALSE;
|
||||
/* the first in the list */
|
||||
if (contour->vertices == v) {
|
||||
contour->vertices = v->next;
|
||||
contour->last_vertex->next = v->next;
|
||||
v->next->previous = contour->last_vertex;
|
||||
}
|
||||
else
|
||||
/* the last ? */
|
||||
if (contour->last_vertex == v) {
|
||||
contour->vertices->previous = v->previous;
|
||||
v->previous->next = v->next;
|
||||
contour->last_vertex = v->previous;
|
||||
}
|
||||
else {
|
||||
v->next->previous = v->previous;
|
||||
v->previous->next = v->next;
|
||||
}
|
||||
free(v);
|
||||
--(contour->vertex_cnt);
|
||||
}
|
||||
|
||||
static void
|
||||
triangulate_ccw(GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vertex;
|
||||
GLuint vertex_cnt = contour->vertex_cnt;
|
||||
|
||||
while (vertex_cnt > 3) {
|
||||
vertex = contour->vertices;
|
||||
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
|
||||
GL_FALSE && tobj->error == GLU_NO_ERROR)
|
||||
vertex = vertex->next;
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
clip_ear(tobj, vertex->next, contour);
|
||||
--vertex_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
triangulate_cw(GLUtriangulatorObj * tobj, tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vertex;
|
||||
GLuint vertex_cnt = contour->vertex_cnt;
|
||||
|
||||
while (vertex_cnt > 3) {
|
||||
vertex = contour->vertices;
|
||||
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
|
||||
GL_FALSE && tobj->error == GLU_NO_ERROR)
|
||||
vertex = vertex->next;
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
clip_ear(tobj, vertex->next, contour);
|
||||
--vertex_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
triangulate_ccw_with_edge_flag(GLUtriangulatorObj * tobj,
|
||||
tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vertex;
|
||||
GLuint vertex_cnt = contour->vertex_cnt;
|
||||
|
||||
while (vertex_cnt > 3) {
|
||||
vertex = contour->vertices;
|
||||
while (diagonal_ccw(vertex, vertex->next->next, tobj, contour) ==
|
||||
GL_FALSE && tobj->error == GLU_NO_ERROR)
|
||||
vertex = vertex->next;
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
clip_ear_with_edge_flag(tobj, vertex->next, contour);
|
||||
--vertex_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
triangulate_cw_with_edge_flag(GLUtriangulatorObj * tobj,
|
||||
tess_contour * contour)
|
||||
{
|
||||
tess_vertex *vertex;
|
||||
GLuint vertex_cnt = contour->vertex_cnt;
|
||||
|
||||
while (vertex_cnt > 3) {
|
||||
vertex = contour->vertices;
|
||||
while (diagonal_cw(vertex, vertex->next->next, tobj, contour) ==
|
||||
GL_FALSE && tobj->error == GLU_NO_ERROR)
|
||||
vertex = vertex->next;
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
clip_ear_with_edge_flag(tobj, vertex->next, contour);
|
||||
--vertex_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tess_tesselate(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_contour *contour;
|
||||
|
||||
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
|
||||
if (contour->orientation == GLU_CCW) {
|
||||
triangulate_ccw(tobj, contour);
|
||||
}
|
||||
else {
|
||||
triangulate_cw(tobj, contour);
|
||||
}
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
|
||||
/* emit the last triangle */
|
||||
emit_triangle(tobj, contour->vertices, contour->vertices->next,
|
||||
contour->vertices->next->next);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tess_tesselate_with_edge_flag(GLUtriangulatorObj * tobj)
|
||||
{
|
||||
tess_contour *contour;
|
||||
|
||||
edge_flag = GL_TRUE;
|
||||
/* first callback with edgeFlag set to GL_TRUE */
|
||||
(tobj->callbacks.edgeFlag) (GL_TRUE);
|
||||
|
||||
for (contour = tobj->contours; contour != NULL; contour = contour->next) {
|
||||
if (contour->orientation == GLU_CCW)
|
||||
triangulate_ccw_with_edge_flag(tobj, contour);
|
||||
else
|
||||
triangulate_cw_with_edge_flag(tobj, contour);
|
||||
if (tobj->error != GLU_NO_ERROR)
|
||||
return;
|
||||
/* emit the last triangle */
|
||||
emit_triangle_with_edge_flag(tobj, contour->vertices,
|
||||
contour->vertices->edge_flag,
|
||||
contour->vertices->next,
|
||||
contour->vertices->next->edge_flag,
|
||||
contour->vertices->next->next,
|
||||
contour->vertices->next->next->edge_flag);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_triangle(GLUtriangulatorObj * tobj,
|
||||
tess_vertex * v1, tess_vertex * v2, tess_vertex * v3)
|
||||
{
|
||||
(tobj->callbacks.begin) (GL_TRIANGLES);
|
||||
(tobj->callbacks.vertex) (v1->data);
|
||||
(tobj->callbacks.vertex) (v2->data);
|
||||
(tobj->callbacks.vertex) (v3->data);
|
||||
(tobj->callbacks.end) ();
|
||||
}
|
||||
|
||||
static void
|
||||
emit_triangle_with_edge_flag(GLUtriangulatorObj * tobj,
|
||||
tess_vertex * v1,
|
||||
GLboolean edge_flag1,
|
||||
tess_vertex * v2,
|
||||
GLboolean edge_flag2,
|
||||
tess_vertex * v3, GLboolean edge_flag3)
|
||||
{
|
||||
(tobj->callbacks.begin) (GL_TRIANGLES);
|
||||
if (edge_flag1 != edge_flag) {
|
||||
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
|
||||
(tobj->callbacks.edgeFlag) (edge_flag);
|
||||
}
|
||||
(tobj->callbacks.vertex) (v1->data);
|
||||
if (edge_flag2 != edge_flag) {
|
||||
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
|
||||
(tobj->callbacks.edgeFlag) (edge_flag);
|
||||
}
|
||||
(tobj->callbacks.vertex) (v2->data);
|
||||
if (edge_flag3 != edge_flag) {
|
||||
edge_flag = (edge_flag == GL_TRUE ? GL_FALSE : GL_TRUE);
|
||||
(tobj->callbacks.edgeFlag) (edge_flag);
|
||||
}
|
||||
(tobj->callbacks.vertex) (v3->data);
|
||||
(tobj->callbacks.end) ();
|
||||
}
|
||||
@@ -1,43 +1,11 @@
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 4.0
|
||||
#
|
||||
# Copyright (C) 1999 Brian Paul All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# DOS/DJGPP glut makefile v1.1 for Mesa 4.0
|
||||
#
|
||||
# Copyright (C) 2002 - Borca Daniel
|
||||
# Email : dborca@yahoo.com
|
||||
# Web : http://www.geocities.com/dborca
|
||||
MESA = ../..
|
||||
|
||||
MARK = $(MESA)/src-glut
|
||||
default: libglut.so.3.7 install
|
||||
include $(MESA)/Makefile.include
|
||||
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
TOP = ../..
|
||||
MARK = $(TOP)/src-glut
|
||||
LIBDIR = $(TOP)/lib
|
||||
GLUT_LIB = libglut.so
|
||||
|
||||
CC = gcc
|
||||
INCLUDES = -I$(TOP)/include -I$(MARK)
|
||||
CFLAGS = -c -g $(INCLUDES) -MD
|
||||
INCLUDES = -I$(MESA)/include -I$(MARK)
|
||||
|
||||
CORE_SOURCES = \
|
||||
bitmap.c \
|
||||
@@ -64,35 +32,19 @@ MARK_SOURCES = \
|
||||
|
||||
SOURCES = $(CORE_SOURCES) $(MARK_SOURCES)
|
||||
|
||||
OBJS = $(addsuffix .o,$(basename $(SOURCES)))
|
||||
|
||||
LIBS=-L$(TOP)/lib -lGL -lGLU -lm
|
||||
|
||||
.c.o:
|
||||
$(CC) -o $@ -c $(CFLAGS) $<
|
||||
.S.o:
|
||||
$(CC) -o $@ -c $(CFLAGS) $<
|
||||
|
||||
default: libglut.so.3.7 install
|
||||
OBJS = $(SOURCES:.c=.o)
|
||||
|
||||
LIBS = -L$(MESA)/lib -lGL -lGLU -lm
|
||||
|
||||
libglut.so.3.7: $(OBJS) Makefile
|
||||
gcc -shared -Wl,-soname,libglut.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@
|
||||
|
||||
install:
|
||||
rm -f $(TOP)/lib/libglut.so*
|
||||
install -D libglut.so.3.7 $(TOP)/lib/libglut.so.3.7
|
||||
ln -s libglut.so.3.7 $(TOP)/lib/libglut.so.3
|
||||
ln -s libglut.so.3 $(TOP)/lib/libglut.so
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *~ .*~ *.o libglut.so* *.d
|
||||
rm -f $(MESA)/lib/libglut.so*
|
||||
install -D libglut.so.3.7 $(MESA)/lib/libglut.so.3.7
|
||||
ln -s libglut.so.3.7 $(MESA)/lib/libglut.so.3
|
||||
ln -s libglut.so.3 $(MESA)/lib/libglut.so
|
||||
|
||||
|
||||
-include $(SOURCES:.c=.d)
|
||||
|
||||
.SUFFIXES: .c .d
|
||||
|
||||
.c.d:
|
||||
$(CC) -M $(INCLUDES) $< > $@
|
||||
|
||||
@@ -12,8 +12,8 @@ glutBitmapCharacter(GLUTbitmapFont font, int c)
|
||||
{
|
||||
const BitmapCharRec *ch;
|
||||
BitmapFontPtr fontinfo;
|
||||
GLint swapbytes, lsbfirst, rowlength;
|
||||
GLint skiprows, skippixels, alignment;
|
||||
GLfloat swapbytes, lsbfirst, rowlength;
|
||||
GLfloat skiprows, skippixels, alignment;
|
||||
|
||||
#if defined(_WIN32)
|
||||
fontinfo = (BitmapFontPtr) __glutFont(font);
|
||||
@@ -27,30 +27,30 @@ glutBitmapCharacter(GLUTbitmapFont font, int c)
|
||||
ch = fontinfo->ch[c - fontinfo->first];
|
||||
if (ch) {
|
||||
/* Save current modes. */
|
||||
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
|
||||
glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
|
||||
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
|
||||
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
/* glGetFloatv(GL_UNPACK_SWAP_BYTES, &swapbytes); */
|
||||
/* glGetFloatv(GL_UNPACK_LSB_FIRST, &lsbfirst); */
|
||||
/* glGetFloatv(GL_UNPACK_ROW_LENGTH, &rowlength); */
|
||||
/* glGetFloatv(GL_UNPACK_SKIP_ROWS, &skiprows); */
|
||||
/* glGetFloatv(GL_UNPACK_SKIP_PIXELS, &skippixels); */
|
||||
glGetFloatv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
/* Little endian machines (DEC Alpha for example) could
|
||||
benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE
|
||||
instead of GL_FALSE, but this would require changing the
|
||||
generated bitmaps too. */
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
/* glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); */
|
||||
/* glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); */
|
||||
/* glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); */
|
||||
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); */
|
||||
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); */
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
|
||||
ch->advance, 0, ch->bitmap);
|
||||
/* Restore saved modes. */
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
/* glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); */
|
||||
/* glPixelStorei(GL_UNPACK_LSB_FIRST, (int)lsbfirst); */
|
||||
/* glPixelStorei(GL_UNPACK_ROW_LENGTH, (int)rowlength); */
|
||||
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); */
|
||||
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); */
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, (int)alignment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,6 @@ void APIENTRY glutInit (int *argcp, char **argv)
|
||||
void APIENTRY glutInitDisplayMode (unsigned int mode)
|
||||
{
|
||||
g_display_mode = mode;
|
||||
|
||||
/* pc_install_keyb(); */
|
||||
/* g_mouse = pc_install_mouse(); */
|
||||
}
|
||||
|
||||
|
||||
@@ -60,103 +57,3 @@ void APIENTRY glutInitWindowSize (int width, int height)
|
||||
}
|
||||
|
||||
|
||||
void APIENTRY glutMainLoop (void)
|
||||
{
|
||||
GLboolean idle;
|
||||
static int old_mouse_x = 0;
|
||||
static int old_mouse_y = 0;
|
||||
static int old_mouse_b = 0;
|
||||
|
||||
glutPostRedisplay();
|
||||
if (reshape_func) reshape_func(g_width, g_height);
|
||||
if (visibility_func) visibility_func(GLUT_VISIBLE);
|
||||
/* if (g_mouse) pc_show_mouse(); */
|
||||
|
||||
while (GL_TRUE) {
|
||||
idle = GL_TRUE;
|
||||
|
||||
if (g_redisplay && display_func) {
|
||||
idle = GL_FALSE;
|
||||
g_redisplay = GL_FALSE;
|
||||
|
||||
/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_scare_mouse(); */
|
||||
display_func();
|
||||
/* if (g_mouse && !(g_display_mode & GLUT_DOUBLE)) pc_unscare_mouse(); */
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (pc_keypressed()) {
|
||||
int key;
|
||||
|
||||
idle = GL_FALSE;
|
||||
key = pc_readkey();
|
||||
|
||||
switch (key>>16) {
|
||||
case KEY_F1: if (special_func) special_func(GLUT_KEY_F1, 0, 0); break;
|
||||
case KEY_F2: if (special_func) special_func(GLUT_KEY_F2, 0, 0); break;
|
||||
case KEY_F3: if (special_func) special_func(GLUT_KEY_F3, 0, 0); break;
|
||||
case KEY_F4: if (special_func) special_func(GLUT_KEY_F4, 0, 0); break;
|
||||
case KEY_F5: if (special_func) special_func(GLUT_KEY_F5, 0, 0); break;
|
||||
case KEY_F6: if (special_func) special_func(GLUT_KEY_F6, 0, 0); break;
|
||||
case KEY_F7: if (special_func) special_func(GLUT_KEY_F7, 0, 0); break;
|
||||
case KEY_F8: if (special_func) special_func(GLUT_KEY_F8, 0, 0); break;
|
||||
case KEY_F9: if (special_func) special_func(GLUT_KEY_F9, 0, 0); break;
|
||||
case KEY_F10: if (special_func) special_func(GLUT_KEY_F10, 0, 0); break;
|
||||
case KEY_F11: if (special_func) special_func(GLUT_KEY_F11, 0, 0); break;
|
||||
case KEY_F12: if (special_func) special_func(GLUT_KEY_F12, 0, 0); break;
|
||||
case KEY_LEFT: if (special_func) special_func(GLUT_KEY_LEFT, 0, 0); break;
|
||||
case KEY_UP: if (special_func) special_func(GLUT_KEY_UP, 0, 0); break;
|
||||
case KEY_RIGHT: if (special_func) special_func(GLUT_KEY_RIGHT, 0, 0); break;
|
||||
case KEY_DOWN: if (special_func) special_func(GLUT_KEY_DOWN, 0, 0); break;
|
||||
case KEY_PGUP: if (special_func) special_func(GLUT_KEY_PAGE_UP, 0, 0); break;
|
||||
case KEY_PGDN: if (special_func) special_func(GLUT_KEY_PAGE_DOWN, 0, 0); break;
|
||||
case KEY_HOME: if (special_func) special_func(GLUT_KEY_HOME, 0, 0); break;
|
||||
case KEY_END: if (special_func) special_func(GLUT_KEY_END, 0, 0); break;
|
||||
case KEY_INSERT: if (special_func) special_func(GLUT_KEY_INSERT, 0, 0); break;
|
||||
default: if (keyboard_func) keyboard_func(key & 0xFF, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_mouse) {
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
int mouse_b;
|
||||
|
||||
mouse_b = pc_query_mouse(&mouse_x, &mouse_y);
|
||||
|
||||
if (motion_func && ((mouse_x != old_mouse_x) || (mouse_y != old_mouse_y))) {
|
||||
idle = GL_FALSE;
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
|
||||
motion_func(old_mouse_x, old_mouse_y);
|
||||
}
|
||||
|
||||
if (mouse_func && (mouse_b != old_mouse_b)) {
|
||||
int new_mouse_b = mouse_b;
|
||||
|
||||
if ((old_mouse_b & 1) && !(new_mouse_b & 1))
|
||||
mouse_func(GLUT_LEFT_BUTTON, GLUT_UP, mouse_x, mouse_y);
|
||||
else if (!(old_mouse_b & 1) && (new_mouse_b & 1))
|
||||
mouse_func(GLUT_LEFT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
|
||||
|
||||
if ((old_mouse_b & 2) && !(new_mouse_b & 2))
|
||||
mouse_func(GLUT_RIGHT_BUTTON, GLUT_UP, mouse_x, mouse_y);
|
||||
else if (!(old_mouse_b & 2) && (new_mouse_b & 2))
|
||||
mouse_func(GLUT_RIGHT_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
|
||||
|
||||
if ((old_mouse_b & 4) && !(new_mouse_b & 4))
|
||||
mouse_func(GLUT_MIDDLE_BUTTON, GLUT_UP, mouse_x, mouse_y);
|
||||
else if (!(old_mouse_b & 3) && (new_mouse_b & 4))
|
||||
mouse_func(GLUT_MIDDLE_BUTTON, GLUT_DOWN, mouse_x, mouse_y);
|
||||
|
||||
idle = GL_FALSE;
|
||||
old_mouse_b = new_mouse_b;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (idle && idle_func)
|
||||
idle_func();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ drawBox(GLfloat size, GLenum type)
|
||||
|
||||
for (i = 5; i >= 0; i--) {
|
||||
glBegin(type);
|
||||
glNormal3fv(&n[i][0]);
|
||||
/* glNormal3fv(&n[i][0]); */
|
||||
glVertex3fv(&v[faces[i][0]][0]);
|
||||
glVertex3fv(&v[faces[i][1]][0]);
|
||||
glVertex3fv(&v[faces[i][2]][0]);
|
||||
@@ -205,9 +205,9 @@ doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
|
||||
sinPhi = sin(phi);
|
||||
dist = R + r * cosPhi;
|
||||
|
||||
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
|
||||
/* glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); */
|
||||
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
|
||||
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
|
||||
/* glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); */
|
||||
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
|
||||
}
|
||||
glEnd();
|
||||
@@ -222,10 +222,10 @@ void APIENTRY
|
||||
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
|
||||
GLint nsides, GLint rings)
|
||||
{
|
||||
glPushAttrib(GL_POLYGON_BIT);
|
||||
/* glPushAttrib(GL_POLYGON_BIT); */
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
doughnut(innerRadius, outerRadius, nsides, rings);
|
||||
glPopAttrib();
|
||||
/* glPopAttrib(); */
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
@@ -318,7 +318,7 @@ pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
|
||||
normalize(n0);
|
||||
|
||||
glBegin(shadeType);
|
||||
glNormal3fv(n0);
|
||||
/* glNormal3fv(n0); */
|
||||
glVertex3fv(&dodec[a][0]);
|
||||
glVertex3fv(&dodec[b][0]);
|
||||
glVertex3fv(&dodec[c][0]);
|
||||
@@ -377,7 +377,7 @@ recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
|
||||
normalize(q1);
|
||||
|
||||
glBegin(shadeType);
|
||||
glNormal3fv(q1);
|
||||
/* glNormal3fv(q1); */
|
||||
glVertex3fv(n1);
|
||||
glVertex3fv(n2);
|
||||
glVertex3fv(n3);
|
||||
|
||||
@@ -143,6 +143,7 @@ teapot(GLint grid, GLdouble scale, GLenum type)
|
||||
float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
|
||||
long i, j, k, l;
|
||||
|
||||
#if 0
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
|
||||
glEnable(GL_AUTO_NORMAL);
|
||||
glEnable(GL_NORMALIZE);
|
||||
@@ -194,6 +195,7 @@ teapot(GLint grid, GLdouble scale, GLenum type)
|
||||
}
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
|
||||
@@ -218,3 +218,50 @@ void APIENTRY glutShowWindow (void)
|
||||
void APIENTRY glutHideWindow (void)
|
||||
{
|
||||
}
|
||||
|
||||
void APIENTRY glutMainLoop (void)
|
||||
{
|
||||
GLboolean idle;
|
||||
GLboolean have_event;
|
||||
XEvent evt;
|
||||
|
||||
glutPostRedisplay();
|
||||
if (reshape_func) reshape_func(g_width, g_height);
|
||||
|
||||
while (GL_TRUE) {
|
||||
idle = GL_TRUE;
|
||||
|
||||
|
||||
if (idle_func)
|
||||
have_event = XCheckWindowEvent( dpy, win, ~0, &evt );
|
||||
else
|
||||
have_event = XNextEvent( dpy, &evt );
|
||||
|
||||
if (have_event) {
|
||||
fprintf(stderr, "got event type %d\n", evt.type);
|
||||
idle = GL_FALSE;
|
||||
switch(evt.type) {
|
||||
case MapNotify:
|
||||
if (visibility_func) visibility_func(GLUT_VISIBLE);
|
||||
break;
|
||||
case UnmapNotify:
|
||||
if (visibility_func) visibility_func(GLUT_NOT_VISIBLE);
|
||||
break;
|
||||
case Expose:
|
||||
g_redisplay = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_redisplay && display_func) {
|
||||
idle = GL_FALSE;
|
||||
g_redisplay = GL_FALSE;
|
||||
|
||||
display_func();
|
||||
}
|
||||
|
||||
if (idle && idle_func) {
|
||||
idle_func();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
src/kernel/agpgart/NOTES
Normal file
1
src/kernel/agpgart/NOTES
Normal file
@@ -0,0 +1 @@
|
||||
This directory not really of interest to anybody... Feel free to ignore.
|
||||
1690
src/kernel/agpgart/agp.c
Normal file
1690
src/kernel/agpgart/agp.c
Normal file
File diff suppressed because it is too large
Load Diff
377
src/kernel/agpgart/agp.h
Normal file
377
src/kernel/agpgart/agp.h
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* AGPGART module version 0.99
|
||||
* 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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* chipset specific init 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 ": "
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
enum aper_size_type {
|
||||
U8_APER_SIZE,
|
||||
U16_APER_SIZE,
|
||||
U32_APER_SIZE,
|
||||
LVL2_APER_SIZE,
|
||||
FIXED_APER_SIZE
|
||||
};
|
||||
|
||||
struct gatt_mask {
|
||||
unsigned long mask;
|
||||
u32 type;
|
||||
/* totally device specific, for integrated chipsets that
|
||||
* might have different types of memory masks. For other
|
||||
* devices this will probably be ignored */
|
||||
};
|
||||
|
||||
struct aper_size_info_8 {
|
||||
int size;
|
||||
int num_entries;
|
||||
int page_order;
|
||||
u8 size_value;
|
||||
};
|
||||
|
||||
struct aper_size_info_16 {
|
||||
int size;
|
||||
int num_entries;
|
||||
int page_order;
|
||||
u16 size_value;
|
||||
};
|
||||
|
||||
struct aper_size_info_32 {
|
||||
int size;
|
||||
int num_entries;
|
||||
int page_order;
|
||||
u32 size_value;
|
||||
};
|
||||
|
||||
struct aper_size_info_lvl2 {
|
||||
int size;
|
||||
int num_entries;
|
||||
u32 size_value;
|
||||
};
|
||||
|
||||
struct aper_size_info_fixed {
|
||||
int size;
|
||||
int num_entries;
|
||||
int page_order;
|
||||
};
|
||||
|
||||
struct agp_bridge_data {
|
||||
struct agp_version *version;
|
||||
void *aperture_sizes;
|
||||
void *previous_size;
|
||||
void *current_size;
|
||||
void *dev_private_data;
|
||||
struct pci_dev *dev;
|
||||
struct gatt_mask *masks;
|
||||
unsigned long *gatt_table;
|
||||
unsigned long *gatt_table_real;
|
||||
unsigned long scratch_page;
|
||||
unsigned long gart_bus_addr;
|
||||
unsigned long gatt_bus_addr;
|
||||
u32 mode;
|
||||
enum chipset_type type;
|
||||
enum aper_size_type size_type;
|
||||
unsigned long *key_list;
|
||||
atomic_t current_memory_agp;
|
||||
atomic_t agp_in_use;
|
||||
int max_memory_agp; /* in number of pages */
|
||||
int needs_scratch_page;
|
||||
int aperture_size_idx;
|
||||
int num_aperture_sizes;
|
||||
int num_of_masks;
|
||||
int capndx;
|
||||
int cant_use_aperture;
|
||||
|
||||
/* Links to driver specific functions */
|
||||
|
||||
int (*fetch_size) (void);
|
||||
int (*configure) (void);
|
||||
void (*agp_enable) (u32);
|
||||
void (*cleanup) (void);
|
||||
void (*tlb_flush) (agp_memory *);
|
||||
unsigned long (*mask_memory) (unsigned long, int);
|
||||
void (*cache_flush) (void);
|
||||
int (*create_gatt_table) (void);
|
||||
int (*free_gatt_table) (void);
|
||||
int (*insert_memory) (agp_memory *, off_t, int);
|
||||
int (*remove_memory) (agp_memory *, off_t, int);
|
||||
agp_memory *(*alloc_by_type) (size_t, int);
|
||||
void (*free_by_type) (agp_memory *);
|
||||
void *(*agp_alloc_page) (void);
|
||||
void (*agp_destroy_page) (void *);
|
||||
int (*suspend)(void);
|
||||
void (*resume)(void);
|
||||
|
||||
};
|
||||
|
||||
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
|
||||
#define OUTREG32(mmap, addr, val) __raw_writel((val), (mmap)+(addr))
|
||||
#define OUTREG16(mmap, addr, val) __raw_writew((val), (mmap)+(addr))
|
||||
#define OUTREG8(mmap, addr, val) __raw_writeb((val), (mmap)+(addr))
|
||||
|
||||
#define INREG64(mmap, addr) __raw_readq((mmap)+(addr))
|
||||
#define INREG32(mmap, addr) __raw_readl((mmap)+(addr))
|
||||
#define INREG16(mmap, addr) __raw_readw((mmap)+(addr))
|
||||
#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
|
||||
#define A_SIZE_8(x) ((struct aper_size_info_8 *) x)
|
||||
#define A_SIZE_16(x) ((struct aper_size_info_16 *) x)
|
||||
#define A_SIZE_32(x) ((struct aper_size_info_32 *) x)
|
||||
#define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x)
|
||||
#define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x)
|
||||
#define A_IDX8() (A_SIZE_8(agp_bridge.aperture_sizes) + i)
|
||||
#define A_IDX16() (A_SIZE_16(agp_bridge.aperture_sizes) + i)
|
||||
#define A_IDX32() (A_SIZE_32(agp_bridge.aperture_sizes) + i)
|
||||
#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge.aperture_sizes) + i)
|
||||
#define A_IDXFIX() (A_SIZE_FIX(agp_bridge.aperture_sizes) + i)
|
||||
#define MAXKEY (4096 * 32)
|
||||
|
||||
#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
|
||||
|
||||
/* intel register */
|
||||
#define INTEL_APBASE 0x10
|
||||
#define INTEL_APSIZE 0xb4
|
||||
#define INTEL_ATTBASE 0xb8
|
||||
#define INTEL_AGPCTRL 0xb0
|
||||
#define INTEL_NBXCFG 0x50
|
||||
#define INTEL_ERRSTS 0x91
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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 w. an external graphic card */
|
||||
#define INTEL_I830_ERRSTS 0x92
|
||||
|
||||
/* intel 815 register */
|
||||
#define INTEL_815_APCONT 0x51
|
||||
#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
|
||||
|
||||
/* intel i820 registers */
|
||||
#define INTEL_I820_RDCR 0x51
|
||||
#define INTEL_I820_ERRSTS 0xc8
|
||||
|
||||
/* intel i840 registers */
|
||||
#define INTEL_I840_MCHCFG 0x50
|
||||
#define INTEL_I840_ERRSTS 0xc8
|
||||
|
||||
/* intel i845 registers */
|
||||
#define INTEL_I845_AGPM 0x51
|
||||
#define INTEL_I845_ERRSTS 0xc8
|
||||
|
||||
/* intel i850 registers */
|
||||
#define INTEL_I850_MCHCFG 0x50
|
||||
#define INTEL_I850_ERRSTS 0xc8
|
||||
|
||||
/* intel i860 registers */
|
||||
#define INTEL_I860_MCHCFG 0x50
|
||||
#define INTEL_I860_ERRSTS 0xc8
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
||||
/* VIA register */
|
||||
#define VIA_APBASE 0x10
|
||||
#define VIA_GARTCTRL 0x80
|
||||
#define VIA_APSIZE 0x84
|
||||
#define VIA_ATTBASE 0x88
|
||||
|
||||
/* SiS registers */
|
||||
#define SIS_APBASE 0x10
|
||||
#define SIS_ATTBASE 0x90
|
||||
#define SIS_APSIZE 0x94
|
||||
#define SIS_TLBCNTRL 0x97
|
||||
#define SIS_TLBFLUSH 0x98
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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 */
|
||||
1086
src/kernel/agpgart/frontend.c
Normal file
1086
src/kernel/agpgart/frontend.c
Normal file
File diff suppressed because it is too large
Load Diff
594
src/kernel/agpgart/i810_agp.c
Normal file
594
src/kernel/agpgart/i810_agp.c
Normal file
@@ -0,0 +1,594 @@
|
||||
/*
|
||||
* AGPGART module version 0.99
|
||||
* 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.
|
||||
*
|
||||
* TODO:
|
||||
* - Allocate more than order 0 pages to avoid too much linear map splitting.
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
731
src/kernel/agpgart/i8x0_agp.c
Normal file
731
src/kernel/agpgart/i8x0_agp.c
Normal file
@@ -0,0 +1,731 @@
|
||||
/*
|
||||
* AGPGART module version 0.99
|
||||
* 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.
|
||||
*
|
||||
* TODO:
|
||||
* - Allocate more than order 0 pages to avoid too much linear map splitting.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/agp_backend.h>
|
||||
#include "agp.h"
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void intel_820_tlbflush(agp_memory * mem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void intel_845_resume(void)
|
||||
{
|
||||
intel_845_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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned long intel_mask_memory(unsigned long addr, int type)
|
||||
{
|
||||
/* Memory type is ignored */
|
||||
|
||||
return addr | agp_bridge.masks[0].mask;
|
||||
}
|
||||
|
||||
static void intel_resume(void)
|
||||
{
|
||||
intel_configure();
|
||||
}
|
||||
|
||||
/* Setup function */
|
||||
static struct gatt_mask intel_generic_masks[] =
|
||||
{
|
||||
{mask: 0x00000017, type: 0}
|
||||
};
|
||||
|
||||
static struct aper_size_info_8 intel_815_sizes[2] =
|
||||
{
|
||||
{64, 16384, 4, 0},
|
||||
{32, 8192, 3, 8},
|
||||
};
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
1
src/kernel/fbdev/radeonfb-2.5/NOTES
Normal file
1
src/kernel/fbdev/radeonfb-2.5/NOTES
Normal file
@@ -0,0 +1 @@
|
||||
This directory not really of interest to anybody... Feel free to ignore.
|
||||
3168
src/kernel/fbdev/radeonfb-2.5/radeonfb.c
Normal file
3168
src/kernel/fbdev/radeonfb-2.5/radeonfb.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
|
||||
|
||||
|
||||
118
src/mesa/drivers/dri/r200/Makefile
Normal file
118
src/mesa/drivers/dri/r200/Makefile
Normal file
@@ -0,0 +1,118 @@
|
||||
# $Id: Makefile,v 1.1.2.2 2003/04/15 09:47:37 keithw Exp $
|
||||
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 5.0
|
||||
# Copyright (C) 1995-2002 Brian Paul
|
||||
|
||||
|
||||
|
||||
MESA = ../../..
|
||||
default: r200_dri.so
|
||||
include $(MESA)/Makefile.include
|
||||
|
||||
|
||||
SHARED_INCLUDES= -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -Iserver
|
||||
MINIGLX_INCLUDES = -I$(MESABUILDDIR)/miniglx
|
||||
DRI_INCLUDES = -I$(MESABUILDDIR)/dri
|
||||
|
||||
DEFINES = \
|
||||
-DGLX_DIRECT_RENDERING \
|
||||
-Dlinux -D__i386__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -DFUNCPROTO=15 -DNARROWPROTO -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -DMALLOC_0_RETURNS_NULL -DGLXEXT -DXF86DRI -DGLX_DIRECT_RENDERING -DGLX_USE_DLOPEN -DGLX_USE_MESA -DX_BYTE_ORDER=X_LITTLE_ENDIAN \
|
||||
-D_HAVE_SWRAST=1 \
|
||||
-D_HAVE_SWTNL=1 \
|
||||
-D_HAVE_SANITY=1 \
|
||||
-D_HAVE_CODEGEN=1 \
|
||||
-D_HAVE_LIGHTING=1 \
|
||||
-D_HAVE_TEXGEN=1 \
|
||||
-D_HAVE_USERCLIP=1 \
|
||||
-D_HAVE_FULL_GL=1
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
MINIGLX_SOURCES = server/radeon_dri.c
|
||||
|
||||
DRIVER_SOURCES = r200_context.c \
|
||||
r200_ioctl.c \
|
||||
r200_lock.c \
|
||||
r200_screen.c \
|
||||
r200_state.c \
|
||||
r200_state_init.c \
|
||||
../common/mm.c \
|
||||
r200_cmdbuf.c \
|
||||
r200_pixel.c \
|
||||
r200_tex.c \
|
||||
r200_texmem.c \
|
||||
r200_texstate.c \
|
||||
r200_tcl.c \
|
||||
r200_swtcl.c \
|
||||
r200_span.c \
|
||||
r200_maos.c \
|
||||
r200_sanity.c \
|
||||
r200_vtxfmt.c \
|
||||
r200_vtxfmt_c.c \
|
||||
r200_vtxfmt_sse.c \
|
||||
r200_vtxfmt_x86.c
|
||||
|
||||
|
||||
INCLUDES = $(MINIGLX_INCLUDES) \
|
||||
$(SHARED_INCLUDES)
|
||||
|
||||
|
||||
C_SOURCES = $(DRIVER_SOURCES) \
|
||||
$(MINIGLX_SOURCES)
|
||||
MESA_MODULES = $(FULL_MESA)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
SYMLINKS = server/Makefile \
|
||||
server/radeon_common.h \
|
||||
server/radeon_dri.c \
|
||||
server/radeon_dri.h \
|
||||
server/radeon.h \
|
||||
server/radeon_macros.h \
|
||||
server/radeon_reg.h \
|
||||
server/radeon_sarea.h \
|
||||
|
||||
|
||||
$(SYMLINKS):
|
||||
rm -f $@ && ln -s ../../radeon/$@ $@
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
clean: clean_here
|
||||
|
||||
clean_here:
|
||||
rm -f $(SYMLINKS)
|
||||
|
||||
# Build the subset or full driver?
|
||||
#
|
||||
r200_dri.so: $(SYMLINKS) $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile
|
||||
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lGL -lc -lm -Wl,-rpath,../../../lib
|
||||
rm -f $(MESA)/lib/r200_dri.so && \
|
||||
install r200_dri.so $(MESA)/lib/r200_dri.so
|
||||
|
||||
##### DEPENDENCIES #####
|
||||
|
||||
-include $(C_SOURCES:.c=.d)
|
||||
344
src/mesa/drivers/dri/r200/r200_cmdbuf.c
Normal file
344
src/mesa/drivers/dri/r200/r200_cmdbuf.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "simple_list.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_sanity.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
static void print_state_atom( struct r200_state_atom *state )
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
|
||||
|
||||
if (0 & R200_DEBUG & DEBUG_VERBOSE)
|
||||
for (i = 0 ; i < state->cmd_size ; i++)
|
||||
fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
|
||||
|
||||
}
|
||||
|
||||
static void r200_emit_state_list( r200ContextPtr rmesa,
|
||||
struct r200_state_atom *list )
|
||||
{
|
||||
struct r200_state_atom *state, *tmp;
|
||||
char *dest;
|
||||
|
||||
foreach_s( state, tmp, list ) {
|
||||
if (state->check( rmesa->glCtx, state->idx )) {
|
||||
dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
|
||||
memcpy( dest, state->cmd, state->cmd_size * 4);
|
||||
move_to_head( &(rmesa->hw.clean), state );
|
||||
if (R200_DEBUG & DEBUG_STATE)
|
||||
print_state_atom( state );
|
||||
}
|
||||
else if (R200_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "skip state %s\n", state->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void r200EmitState( r200ContextPtr rmesa )
|
||||
{
|
||||
struct r200_state_atom *state, *tmp;
|
||||
|
||||
if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* Somewhat overkill:
|
||||
*/
|
||||
if ( rmesa->lost_context) {
|
||||
if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL))
|
||||
fprintf(stderr, "%s - lost context\n", __FUNCTION__);
|
||||
|
||||
foreach_s( state, tmp, &(rmesa->hw.clean) )
|
||||
move_to_tail(&(rmesa->hw.dirty), state );
|
||||
|
||||
rmesa->lost_context = 0;
|
||||
}
|
||||
else {
|
||||
move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] );
|
||||
/* odd bug? -- isosurf, cycle between reflect & lit */
|
||||
}
|
||||
|
||||
r200_emit_state_list( rmesa, &rmesa->hw.dirty );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fire a section of the retained (indexed_verts) buffer as a regular
|
||||
* primtive.
|
||||
*/
|
||||
extern void r200EmitVbufPrim( r200ContextPtr rmesa,
|
||||
GLuint primitive,
|
||||
GLuint vertex_nr )
|
||||
{
|
||||
drmRadeonCmdHeader *cmd;
|
||||
|
||||
assert(!(primitive & R200_VF_PRIM_WALK_IND));
|
||||
|
||||
r200EmitState( rmesa );
|
||||
|
||||
if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
|
||||
fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__,
|
||||
rmesa->store.cmd_used/4, primitive, vertex_nr);
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 3 * sizeof(*cmd),
|
||||
__FUNCTION__ );
|
||||
cmd[0].i = 0;
|
||||
cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
|
||||
cmd[1].i = R200_CP_CMD_3D_DRAW_VBUF_2;
|
||||
cmd[2].i = (primitive |
|
||||
R200_VF_PRIM_WALK_LIST |
|
||||
R200_VF_COLOR_ORDER_RGBA |
|
||||
(vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT));
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "\nSyncing\n\n");
|
||||
R200_FIREVERTICES( rmesa );
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void r200FlushElts( r200ContextPtr rmesa )
|
||||
{
|
||||
int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
|
||||
int dwords;
|
||||
int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 12)) / 2;
|
||||
|
||||
if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
assert( rmesa->dma.flush == r200FlushElts );
|
||||
rmesa->dma.flush = 0;
|
||||
|
||||
/* Cope with odd number of elts:
|
||||
*/
|
||||
rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
|
||||
dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
|
||||
|
||||
cmd[1] |= (dwords - 3) << 16;
|
||||
cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT;
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__);
|
||||
R200_FIREVERTICES( rmesa );
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
|
||||
GLuint primitive,
|
||||
GLuint min_nr )
|
||||
{
|
||||
drmRadeonCmdHeader *cmd;
|
||||
GLushort *retval;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
|
||||
|
||||
assert((primitive & R200_VF_PRIM_WALK_IND));
|
||||
|
||||
r200EmitState( rmesa );
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa,
|
||||
12 + min_nr*2,
|
||||
__FUNCTION__ );
|
||||
cmd[0].i = 0;
|
||||
cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
|
||||
cmd[1].i = R200_CP_CMD_3D_DRAW_INDX_2;
|
||||
cmd[2].i = (primitive |
|
||||
R200_VF_PRIM_WALK_IND |
|
||||
R200_VF_COLOR_ORDER_RGBA);
|
||||
|
||||
|
||||
retval = (GLushort *)(cmd+3);
|
||||
|
||||
if (R200_DEBUG & DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s: header 0x%x prim %x \n",
|
||||
__FUNCTION__,
|
||||
cmd[1].i, primitive);
|
||||
|
||||
assert(!rmesa->dma.flush);
|
||||
rmesa->dma.flush = r200FlushElts;
|
||||
|
||||
rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void r200EmitVertexAOS( r200ContextPtr rmesa,
|
||||
GLuint vertex_size,
|
||||
GLuint offset )
|
||||
{
|
||||
drmRadeonCmdHeader *cmd;
|
||||
|
||||
if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
|
||||
fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
|
||||
__FUNCTION__, vertex_size, offset);
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 5 * sizeof(int),
|
||||
__FUNCTION__ );
|
||||
|
||||
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
|
||||
cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (2 << 16);
|
||||
cmd[2].i = 1;
|
||||
cmd[3].i = vertex_size | (vertex_size << 8);
|
||||
cmd[4].i = offset;
|
||||
}
|
||||
|
||||
|
||||
void r200EmitAOS( r200ContextPtr rmesa,
|
||||
struct r200_dma_region **component,
|
||||
GLuint nr,
|
||||
GLuint offset )
|
||||
{
|
||||
drmRadeonCmdHeader *cmd;
|
||||
int sz = 3 + ((nr/2)*3) + ((nr&1)*2);
|
||||
int i;
|
||||
int *tmp;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr);
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sz * sizeof(int),
|
||||
__FUNCTION__ );
|
||||
cmd[0].i = 0;
|
||||
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
|
||||
cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | ((sz-3) << 16);
|
||||
cmd[2].i = nr;
|
||||
tmp = &cmd[0].i;
|
||||
cmd += 3;
|
||||
|
||||
for (i = 0 ; i < nr ; i++) {
|
||||
if (i & 1) {
|
||||
cmd[0].i |= ((component[i]->aos_stride << 24) |
|
||||
(component[i]->aos_size << 16));
|
||||
cmd[2].i = (component[i]->aos_start +
|
||||
offset * component[i]->aos_stride * 4);
|
||||
cmd += 3;
|
||||
}
|
||||
else {
|
||||
cmd[0].i = ((component[i]->aos_stride << 8) |
|
||||
(component[i]->aos_size << 0));
|
||||
cmd[1].i = (component[i]->aos_start +
|
||||
offset * component[i]->aos_stride * 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS) {
|
||||
fprintf(stderr, "%s:\n", __FUNCTION__);
|
||||
for (i = 0 ; i < sz ; i++)
|
||||
fprintf(stderr, " %d: %x\n", i, tmp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void r200EmitBlit( r200ContextPtr rmesa,
|
||||
GLuint color_fmt,
|
||||
GLuint src_pitch,
|
||||
GLuint src_offset,
|
||||
GLuint dst_pitch,
|
||||
GLuint dst_offset,
|
||||
GLint srcx, GLint srcy,
|
||||
GLint dstx, GLint dsty,
|
||||
GLuint w, GLuint h )
|
||||
{
|
||||
drmRadeonCmdHeader *cmd;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
|
||||
__FUNCTION__,
|
||||
src_pitch, src_offset, srcx, srcy,
|
||||
dst_pitch, dst_offset, dstx, dsty,
|
||||
w, h);
|
||||
|
||||
assert( (src_pitch & 63) == 0 );
|
||||
assert( (dst_pitch & 63) == 0 );
|
||||
assert( (src_offset & 1023) == 0 );
|
||||
assert( (dst_offset & 1023) == 0 );
|
||||
assert( w < (1<<16) );
|
||||
assert( h < (1<<16) );
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 8 * sizeof(int),
|
||||
__FUNCTION__ );
|
||||
|
||||
|
||||
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
|
||||
cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16);
|
||||
cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
(color_fmt << 8) |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_ROP3_S |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
RADEON_GMC_CLR_CMP_CNTL_DIS |
|
||||
RADEON_GMC_WR_MSK_DIS );
|
||||
|
||||
cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
|
||||
cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
|
||||
cmd[5].i = (srcx << 16) | srcy;
|
||||
cmd[6].i = (dstx << 16) | dsty; /* dst */
|
||||
cmd[7].i = (w << 16) | h;
|
||||
}
|
||||
|
||||
|
||||
void r200EmitWait( r200ContextPtr rmesa, GLuint flags )
|
||||
{
|
||||
if (rmesa->dri.drmMinor >= 6) {
|
||||
drmRadeonCmdHeader *cmd;
|
||||
|
||||
assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 1 * sizeof(int),
|
||||
__FUNCTION__ );
|
||||
cmd[0].i = 0;
|
||||
cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
|
||||
cmd[0].wait.flags = flags;
|
||||
}
|
||||
}
|
||||
673
src/mesa/drivers/dri/r200/r200_context.c
Normal file
673
src/mesa/drivers/dri/r200/r200_context.c
Normal file
@@ -0,0 +1,673 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "api_arrayelt.h"
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "imports.h"
|
||||
#include "matrix.h"
|
||||
#include "state.h"
|
||||
#include "extensions.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "array_cache/acache.h"
|
||||
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_span.h"
|
||||
#include "r200_pixel.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_vtxfmt.h"
|
||||
#include "r200_maos.h"
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#endif
|
||||
|
||||
#define R200_DATE "20021125"
|
||||
|
||||
#ifndef R200_DEBUG
|
||||
int R200_DEBUG = (0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Return the width and height of the given buffer.
|
||||
*/
|
||||
static void r200GetBufferSize( GLframebuffer *buffer,
|
||||
GLuint *width, GLuint *height )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
*width = rmesa->dri.drawable->w;
|
||||
*height = rmesa->dri.drawable->h;
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
/* Return various strings for glGetString().
|
||||
*/
|
||||
static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
static char buffer[128];
|
||||
|
||||
switch ( name ) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *)"Tungsten Graphics, Inc.";
|
||||
|
||||
case GL_RENDERER:
|
||||
sprintf( buffer, "Mesa DRI R200 " R200_DATE);
|
||||
|
||||
/* Append any chipset-specific information. None yet.
|
||||
*/
|
||||
|
||||
/* Append any AGP-specific information.
|
||||
*/
|
||||
switch ( rmesa->r200Screen->AGPMode ) {
|
||||
case 1:
|
||||
strncat( buffer, " AGP 1x", 7 );
|
||||
break;
|
||||
case 2:
|
||||
strncat( buffer, " AGP 2x", 7 );
|
||||
break;
|
||||
case 4:
|
||||
strncat( buffer, " AGP 4x", 7 );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Append any CPU-specific information.
|
||||
*/
|
||||
#ifdef USE_X86_ASM
|
||||
if ( _mesa_x86_cpu_features ) {
|
||||
strncat( buffer, " x86", 4 );
|
||||
}
|
||||
#ifdef USE_MMX_ASM
|
||||
if ( cpu_has_mmx ) {
|
||||
strncat( buffer, "/MMX", 4 );
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_3DNOW_ASM
|
||||
if ( cpu_has_3dnow ) {
|
||||
strncat( buffer, "/3DNow!", 7 );
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SSE_ASM
|
||||
if ( cpu_has_xmm ) {
|
||||
strncat( buffer, "/SSE", 4 );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) ) {
|
||||
strncat( buffer, " TCL", 4 );
|
||||
}
|
||||
else {
|
||||
strncat( buffer, " NO-TCL", 7 );
|
||||
}
|
||||
|
||||
return (GLubyte *)buffer;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize the extensions supported by this driver.
|
||||
*/
|
||||
static void r200InitExtensions( GLcontext *ctx, r200ScreenPtr r200Screen )
|
||||
{
|
||||
_mesa_enable_imaging_extensions( ctx );
|
||||
|
||||
_mesa_enable_extension( ctx, "GL_ARB_multitexture" );
|
||||
if (r200Screen->drmSupportsCubeMaps)
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_env_add" );
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" );
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_env_dot3" );
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_mirrored_repeat" );
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_border_clamp" );
|
||||
|
||||
_mesa_enable_extension( ctx, "GL_ATI_texture_env_combine3" );
|
||||
_mesa_enable_extension( ctx, "GL_ATI_texture_mirror_once" );
|
||||
|
||||
_mesa_enable_extension( ctx, "GL_EXT_blend_logic_op" );
|
||||
/*_mesa_enable_extension( ctx, "GL_EXT_fog_coord" );*/
|
||||
_mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_edge_clamp" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_env_add" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_env_dot3" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_filter_anisotropic" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_secondary_color" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_blend_subtract" );
|
||||
_mesa_enable_extension( ctx, "GL_EXT_blend_minmax" );
|
||||
|
||||
/* _mesa_enable_extension( ctx, "GL_EXT_fog_coord" ); */
|
||||
|
||||
_mesa_enable_extension( ctx, "GL_MESA_pack_invert" );
|
||||
_mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
|
||||
_mesa_enable_extension( ctx, "GL_NV_texture_rectangle" );
|
||||
}
|
||||
|
||||
extern const struct gl_pipeline_stage _r200_render_stage;
|
||||
extern const struct gl_pipeline_stage _r200_tcl_stage;
|
||||
|
||||
static const struct gl_pipeline_stage *r200_pipeline[] = {
|
||||
|
||||
/* Try and go straight to t&l
|
||||
*/
|
||||
&_r200_tcl_stage,
|
||||
|
||||
/* Catch any t&l fallbacks
|
||||
*/
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
&_tnl_fog_coordinate_stage,
|
||||
&_tnl_texgen_stage,
|
||||
&_tnl_texture_transform_stage,
|
||||
|
||||
/* Try again to go to tcl?
|
||||
* - no good for asymmetric-twoside (do with multipass)
|
||||
* - no good for asymmetric-unfilled (do with multipass)
|
||||
* - good for material
|
||||
* - good for texgen
|
||||
* - need to manipulate a bit of state
|
||||
*
|
||||
* - worth it/not worth it?
|
||||
*/
|
||||
|
||||
/* Else do them here.
|
||||
*/
|
||||
&_r200_render_stage,
|
||||
&_tnl_render_stage, /* FALLBACK: */
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Initialize the driver's misc functions.
|
||||
*/
|
||||
static void r200InitDriverFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.GetBufferSize = r200GetBufferSize;
|
||||
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
|
||||
ctx->Driver.GetString = r200GetString;
|
||||
|
||||
ctx->Driver.Error = NULL;
|
||||
ctx->Driver.DrawPixels = NULL;
|
||||
ctx->Driver.Bitmap = NULL;
|
||||
}
|
||||
|
||||
static void add_debug_flags( const char *debug )
|
||||
{
|
||||
if (strstr(debug, "fall"))
|
||||
R200_DEBUG |= DEBUG_FALLBACKS;
|
||||
|
||||
if (strstr(debug, "tex"))
|
||||
R200_DEBUG |= DEBUG_TEXTURE;
|
||||
|
||||
if (strstr(debug, "ioctl"))
|
||||
R200_DEBUG |= DEBUG_IOCTL;
|
||||
|
||||
if (strstr(debug, "prim"))
|
||||
R200_DEBUG |= DEBUG_PRIMS;
|
||||
|
||||
if (strstr(debug, "vert"))
|
||||
R200_DEBUG |= DEBUG_VERTS;
|
||||
|
||||
if (strstr(debug, "state"))
|
||||
R200_DEBUG |= DEBUG_STATE;
|
||||
|
||||
if (strstr(debug, "code"))
|
||||
R200_DEBUG |= DEBUG_CODEGEN;
|
||||
|
||||
if (strstr(debug, "vfmt") || strstr(debug, "vtxf"))
|
||||
R200_DEBUG |= DEBUG_VFMT;
|
||||
|
||||
if (strstr(debug, "verb"))
|
||||
R200_DEBUG |= DEBUG_VERBOSE;
|
||||
|
||||
if (strstr(debug, "dri"))
|
||||
R200_DEBUG |= DEBUG_DRI;
|
||||
|
||||
if (strstr(debug, "dma"))
|
||||
R200_DEBUG |= DEBUG_DMA;
|
||||
|
||||
if (strstr(debug, "san"))
|
||||
R200_DEBUG |= DEBUG_SANITY;
|
||||
|
||||
if (strstr(debug, "sync"))
|
||||
R200_DEBUG |= DEBUG_SYNC;
|
||||
|
||||
if (strstr(debug, "pix"))
|
||||
R200_DEBUG |= DEBUG_PIXEL;
|
||||
|
||||
if (strstr(debug, "mem"))
|
||||
R200_DEBUG |= DEBUG_MEMORY;
|
||||
}
|
||||
|
||||
/* Create the device specific context.
|
||||
*/
|
||||
GLboolean r200CreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
r200ScreenPtr r200Screen = (r200ScreenPtr)(sPriv->private);
|
||||
r200ContextPtr rmesa;
|
||||
GLcontext *ctx, *shareCtx;
|
||||
int i, memPerUnit;
|
||||
|
||||
assert(glVisual);
|
||||
assert(driContextPriv);
|
||||
assert(r200Screen);
|
||||
|
||||
/* Allocate the R200 context */
|
||||
rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
|
||||
if ( !rmesa )
|
||||
return GL_FALSE;
|
||||
|
||||
/* Allocate the Mesa context */
|
||||
if (sharedContextPrivate)
|
||||
shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
|
||||
else
|
||||
shareCtx = NULL;
|
||||
rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) rmesa, GL_TRUE);
|
||||
if (!rmesa->glCtx) {
|
||||
FREE(rmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
driContextPriv->driverPrivate = rmesa;
|
||||
|
||||
/* Init r200 context data */
|
||||
rmesa->dri.context = driContextPriv;
|
||||
rmesa->dri.screen = sPriv;
|
||||
rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
|
||||
rmesa->dri.hwContext = driContextPriv->hHWContext;
|
||||
rmesa->dri.hwLock = &sPriv->pSAREA->lock;
|
||||
rmesa->dri.fd = sPriv->fd;
|
||||
rmesa->dri.drmMinor = sPriv->drmMinor;
|
||||
|
||||
rmesa->r200Screen = r200Screen;
|
||||
rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA +
|
||||
r200Screen->sarea_priv_offset);
|
||||
|
||||
|
||||
rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
|
||||
|
||||
for ( i = 0 ; i < r200Screen->numTexHeaps ; i++ ) {
|
||||
make_empty_list( &rmesa->texture.objects[i] );
|
||||
rmesa->texture.heap[i] = mmInit( 0, r200Screen->texSize[i] );
|
||||
rmesa->texture.age[i] = -1;
|
||||
}
|
||||
rmesa->texture.numHeaps = r200Screen->numTexHeaps;
|
||||
make_empty_list( &rmesa->texture.swapped );
|
||||
|
||||
rmesa->swtcl.RenderIndex = ~0;
|
||||
rmesa->lost_context = 1;
|
||||
|
||||
/* KW: Set the maximum texture size small enough that we can
|
||||
* guarentee that both texture units can bind a maximal texture
|
||||
* and have them both in on-card memory at once.
|
||||
* Test for 2 textures * 4 bytes/texel * size * size.
|
||||
*/
|
||||
ctx = rmesa->glCtx;
|
||||
memPerUnit = r200Screen->texSize[RADEON_CARD_HEAP] / 2;
|
||||
|
||||
/* XXX the following code could go into a utility file */
|
||||
if (memPerUnit >= 4 * 2048 * 2048) {
|
||||
ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 1024 * 1024) {
|
||||
ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 512 * 512) {
|
||||
ctx->Const.MaxTextureLevels = 10; /* 512x512 */
|
||||
}
|
||||
else {
|
||||
ctx->Const.MaxTextureLevels = 9; /* 256x256 */
|
||||
}
|
||||
|
||||
#if ENABLE_HW_3D_TEXTURE
|
||||
if (memPerUnit >= 4 * 256 * 256 * 256) {
|
||||
ctx->Const.Max3DTextureLevels = 9; /* 256x256x256 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 64 * 64 * 64) {
|
||||
ctx->Const.Max3DTextureLevels = 8; /* 128x128x128 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 32 * 32 * 32) {
|
||||
ctx->Const.Max3DTextureLevels = 7; /* 64x64x64 */
|
||||
}
|
||||
else { /* 256KBytes */
|
||||
ctx->Const.Max3DTextureLevels = 6; /* 32x32x32 */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memPerUnit >= 4 * 6 * 2048 * 2048) {
|
||||
ctx->Const.MaxCubeTextureLevels = 12; /* 2048x2048 */
|
||||
}
|
||||
if (memPerUnit >= 4 * 6 * 1024 * 1024) {
|
||||
ctx->Const.MaxCubeTextureLevels = 11; /* 1024x1024 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 6 * 512 * 512) {
|
||||
ctx->Const.MaxCubeTextureLevels = 10; /* 512x512 */
|
||||
}
|
||||
else if (memPerUnit >= 4 * 6 * 256 * 256) {
|
||||
ctx->Const.MaxCubeTextureLevels = 9; /* 256x256 */
|
||||
}
|
||||
else { /* 393216 bytes */
|
||||
ctx->Const.MaxCubeTextureLevels = 8; /* 128x128 */
|
||||
}
|
||||
|
||||
ctx->Const.MaxTextureUnits = 2;
|
||||
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
|
||||
|
||||
/* No wide points.
|
||||
*/
|
||||
ctx->Const.MinPointSize = 1.0;
|
||||
ctx->Const.MinPointSizeAA = 1.0;
|
||||
ctx->Const.MaxPointSize = 1.0;
|
||||
ctx->Const.MaxPointSizeAA = 1.0;
|
||||
|
||||
ctx->Const.MinLineWidth = 1.0;
|
||||
ctx->Const.MinLineWidthAA = 1.0;
|
||||
ctx->Const.MaxLineWidth = 10.0;
|
||||
ctx->Const.MaxLineWidthAA = 10.0;
|
||||
ctx->Const.LineWidthGranularity = 0.0625;
|
||||
|
||||
/* Initialize the software rasterizer and helper modules.
|
||||
*/
|
||||
_swrast_CreateContext( ctx );
|
||||
_ac_CreateContext( ctx );
|
||||
_tnl_CreateContext( ctx );
|
||||
_swsetup_CreateContext( ctx );
|
||||
_ae_create_context( ctx );
|
||||
|
||||
/* Install the customized pipeline:
|
||||
*/
|
||||
_tnl_destroy_pipeline( ctx );
|
||||
_tnl_install_pipeline( ctx, r200_pipeline );
|
||||
ctx->Driver.FlushVertices = r200FlushVertices;
|
||||
|
||||
/* Try and keep materials and vertices separate:
|
||||
*/
|
||||
_tnl_isolate_materials( ctx, GL_TRUE );
|
||||
|
||||
|
||||
/* Configure swrast to match hardware characteristics:
|
||||
*/
|
||||
_swrast_allow_pixel_fog( ctx, GL_FALSE );
|
||||
_swrast_allow_vertex_fog( ctx, GL_TRUE );
|
||||
|
||||
|
||||
_math_matrix_ctr( &rmesa->TexGenMatrix[0] );
|
||||
_math_matrix_ctr( &rmesa->TexGenMatrix[1] );
|
||||
_math_matrix_ctr( &rmesa->tmpmat );
|
||||
_math_matrix_set_identity( &rmesa->TexGenMatrix[0] );
|
||||
_math_matrix_set_identity( &rmesa->TexGenMatrix[1] );
|
||||
_math_matrix_set_identity( &rmesa->tmpmat );
|
||||
|
||||
r200InitExtensions( ctx, r200Screen );
|
||||
r200InitDriverFuncs( ctx );
|
||||
r200InitIoctlFuncs( ctx );
|
||||
r200InitStateFuncs( ctx );
|
||||
r200InitSpanFuncs( ctx );
|
||||
r200InitPixelFuncs( ctx );
|
||||
r200InitTextureFuncs( ctx );
|
||||
r200InitState( rmesa );
|
||||
r200InitSwtcl( ctx );
|
||||
|
||||
rmesa->iw.irq_seq = -1;
|
||||
rmesa->irqsEmitted = 0;
|
||||
rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 &&
|
||||
!getenv("R200_NO_IRQS") &&
|
||||
rmesa->r200Screen->irq);
|
||||
|
||||
if (!rmesa->do_irqs)
|
||||
fprintf(stderr,
|
||||
"IRQ's not enabled, falling back to busy waits: %d %d %d\n",
|
||||
rmesa->dri.drmMinor,
|
||||
!!getenv("R200_NO_IRQS"),
|
||||
rmesa->r200Screen->irq);
|
||||
|
||||
|
||||
rmesa->do_usleeps = !getenv("R200_NO_USLEEPS");
|
||||
rmesa->prefer_agp_client_texturing =
|
||||
(getenv("R200_AGP_CLIENT_TEXTURES") != 0);
|
||||
|
||||
|
||||
#if DO_DEBUG
|
||||
if (getenv("R200_DEBUG"))
|
||||
add_debug_flags( getenv("R200_DEBUG") );
|
||||
if (getenv("RADEON_DEBUG"))
|
||||
add_debug_flags( getenv("RADEON_DEBUG") );
|
||||
#endif
|
||||
|
||||
if (getenv("R200_NO_RAST")) {
|
||||
fprintf(stderr, "disabling 3D acceleration\n");
|
||||
FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
|
||||
}
|
||||
else if (getenv("R200_NO_TCL")) {
|
||||
fprintf(stderr, "disabling TCL support\n");
|
||||
TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
|
||||
}
|
||||
else {
|
||||
if (!getenv("R200_NO_VTXFMT")) {
|
||||
r200VtxfmtInit( ctx );
|
||||
}
|
||||
_tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Destroy the device specific context.
|
||||
*/
|
||||
/* Destroy the Mesa and driver specific context data.
|
||||
*/
|
||||
void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
|
||||
r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;
|
||||
|
||||
/* check if we're deleting the currently bound context */
|
||||
if (rmesa == current) {
|
||||
R200_FIREVERTICES( rmesa );
|
||||
_mesa_make_current2(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Free r200 context resources */
|
||||
assert(rmesa); /* should never be null */
|
||||
if ( rmesa ) {
|
||||
if (rmesa->glCtx->Shared->RefCount == 1) {
|
||||
/* This share group is about to go away, free our private
|
||||
* texture object data.
|
||||
*/
|
||||
r200TexObjPtr t, next_t;
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) {
|
||||
foreach_s ( t, next_t, &rmesa->texture.objects[i] ) {
|
||||
r200DestroyTexObj( rmesa, t );
|
||||
}
|
||||
mmDestroy( rmesa->texture.heap[i] );
|
||||
rmesa->texture.heap[i] = NULL;
|
||||
}
|
||||
|
||||
foreach_s ( t, next_t, &rmesa->texture.swapped ) {
|
||||
r200DestroyTexObj( rmesa, t );
|
||||
}
|
||||
}
|
||||
|
||||
_swsetup_DestroyContext( rmesa->glCtx );
|
||||
_tnl_DestroyContext( rmesa->glCtx );
|
||||
_ac_DestroyContext( rmesa->glCtx );
|
||||
_swrast_DestroyContext( rmesa->glCtx );
|
||||
|
||||
r200DestroySwtcl( rmesa->glCtx );
|
||||
|
||||
r200ReleaseArrays( rmesa->glCtx, ~0 );
|
||||
|
||||
if (rmesa->dma.current.buf) {
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
|
||||
r200FlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
}
|
||||
|
||||
if (!rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
|
||||
if (!getenv("R200_NO_VTXFMT"))
|
||||
r200VtxfmtDestroy( rmesa->glCtx );
|
||||
|
||||
/* free the Mesa context */
|
||||
rmesa->glCtx->DriverCtx = NULL;
|
||||
_mesa_destroy_context( rmesa->glCtx );
|
||||
|
||||
if (rmesa->state.scissor.pClipRects) {
|
||||
FREE(rmesa->state.scissor.pClipRects);
|
||||
rmesa->state.scissor.pClipRects = 0;
|
||||
}
|
||||
|
||||
FREE( rmesa );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
r200SwapBuffers( __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
r200ContextPtr rmesa;
|
||||
GLcontext *ctx;
|
||||
rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
ctx = rmesa->glCtx;
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
|
||||
if ( rmesa->doPageFlip ) {
|
||||
r200PageFlip( dPriv );
|
||||
}
|
||||
else {
|
||||
r200CopyBuffer( dPriv );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* XXX this shouldn't be an error but we can't handle it for now */
|
||||
_mesa_problem(NULL, "r200SwapBuffers: drawable has no context!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Force the context `c' to be the current context and associate with it
|
||||
* buffer `b'.
|
||||
*/
|
||||
GLboolean
|
||||
r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv )
|
||||
{
|
||||
if ( driContextPriv ) {
|
||||
r200ContextPtr newR200Ctx =
|
||||
(r200ContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (R200_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newR200Ctx->glCtx);
|
||||
|
||||
if ( newR200Ctx->dri.drawable != driDrawPriv ) {
|
||||
newR200Ctx->dri.drawable = driDrawPriv;
|
||||
r200UpdateWindow( newR200Ctx->glCtx );
|
||||
r200UpdateViewportOffset( newR200Ctx->glCtx );
|
||||
}
|
||||
|
||||
_mesa_make_current2( newR200Ctx->glCtx,
|
||||
(GLframebuffer *) driDrawPriv->driverPrivate,
|
||||
(GLframebuffer *) driReadPriv->driverPrivate );
|
||||
|
||||
if ( !newR200Ctx->glCtx->Viewport.Width ) {
|
||||
_mesa_set_viewport( newR200Ctx->glCtx, 0, 0,
|
||||
driDrawPriv->w, driDrawPriv->h );
|
||||
}
|
||||
|
||||
if (newR200Ctx->vb.enabled)
|
||||
r200VtxfmtMakeCurrent( newR200Ctx->glCtx );
|
||||
|
||||
_mesa_update_state( newR200Ctx->glCtx );
|
||||
r200ValidateState( newR200Ctx->glCtx );
|
||||
|
||||
} else {
|
||||
if (R200_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
|
||||
_mesa_make_current( 0, 0 );
|
||||
}
|
||||
|
||||
if (R200_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "End %s\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Force the context `c' to be unbound from its buffer.
|
||||
*/
|
||||
GLboolean
|
||||
r200UnbindContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (R200_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx);
|
||||
|
||||
r200VtxfmtUnbindContext( rmesa->glCtx );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
944
src/mesa/drivers/dri/r200/r200_context.h
Normal file
944
src/mesa/drivers/dri/r200/r200_context.h
Normal file
@@ -0,0 +1,944 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_CONTEXT_H__
|
||||
#define __R200_CONTEXT_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "dri_util.h"
|
||||
#include "radeon_common.h"
|
||||
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "r200_reg.h"
|
||||
|
||||
#define ENABLE_HW_3D_TEXTURE 0 /* XXX this is temporary! */
|
||||
|
||||
struct r200_context;
|
||||
typedef struct r200_context r200ContextRec;
|
||||
typedef struct r200_context *r200ContextPtr;
|
||||
|
||||
#include "r200_lock.h"
|
||||
#include "r200_screen.h"
|
||||
#include "mm.h"
|
||||
|
||||
/* Flags for software fallback cases */
|
||||
/* See correponding strings in r200_swtcl.c */
|
||||
#define R200_FALLBACK_TEXTURE 0x1
|
||||
#define R200_FALLBACK_DRAW_BUFFER 0x2
|
||||
#define R200_FALLBACK_STENCIL 0x4
|
||||
#define R200_FALLBACK_RENDER_MODE 0x8
|
||||
#define R200_FALLBACK_BLEND_EQ 0x10
|
||||
#define R200_FALLBACK_BLEND_FUNC 0x20
|
||||
#define R200_FALLBACK_DISABLE 0x40
|
||||
|
||||
/* The blit width for texture uploads
|
||||
*/
|
||||
#define BLIT_WIDTH_BYTES 1024
|
||||
|
||||
/* Use the templated vertex format:
|
||||
*/
|
||||
#define COLOR_IS_RGBA
|
||||
#define TAG(x) r200##x
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
typedef void (*r200_tri_func)( r200ContextPtr,
|
||||
r200Vertex *,
|
||||
r200Vertex *,
|
||||
r200Vertex * );
|
||||
|
||||
typedef void (*r200_line_func)( r200ContextPtr,
|
||||
r200Vertex *,
|
||||
r200Vertex * );
|
||||
|
||||
typedef void (*r200_point_func)( r200ContextPtr,
|
||||
r200Vertex * );
|
||||
|
||||
|
||||
struct r200_colorbuffer_state {
|
||||
GLuint clear;
|
||||
GLint drawOffset, drawPitch;
|
||||
};
|
||||
|
||||
|
||||
struct r200_depthbuffer_state {
|
||||
GLfloat scale;
|
||||
};
|
||||
|
||||
struct r200_pixel_state {
|
||||
GLint readOffset, readPitch;
|
||||
};
|
||||
|
||||
struct r200_scissor_state {
|
||||
XF86DRIClipRectRec rect;
|
||||
GLboolean enabled;
|
||||
|
||||
GLuint numClipRects; /* Cliprects active */
|
||||
GLuint numAllocedClipRects; /* Cliprects available */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
};
|
||||
|
||||
struct r200_stencilbuffer_state {
|
||||
GLboolean hwBuffer;
|
||||
GLuint clear; /* rb3d_stencilrefmask value */
|
||||
};
|
||||
|
||||
struct r200_stipple_state {
|
||||
GLuint mask[32];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define TEX_0 0x1
|
||||
#define TEX_1 0x2
|
||||
#define TEX_ALL 0x3
|
||||
|
||||
typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr;
|
||||
|
||||
/* Texture object in locally shared texture space.
|
||||
*/
|
||||
struct r200_tex_obj {
|
||||
r200TexObjPtr next, prev;
|
||||
|
||||
struct gl_texture_object *tObj; /* Mesa texture object */
|
||||
|
||||
PMemBlock memBlock; /* Memory block containing texture */
|
||||
GLuint bufAddr; /* Offset to start of locally
|
||||
shared texture block */
|
||||
|
||||
GLuint dirty_images[6]; /* Flags for whether or not
|
||||
images need to be uploaded to
|
||||
local or AGP texture space.
|
||||
Six cube faces. */
|
||||
|
||||
GLuint dirty_state; /* Flags (1 per texunit) for
|
||||
whether or not this texobj
|
||||
has dirty hardware state
|
||||
(pp_*) that needs to be
|
||||
brought into the
|
||||
texunit. */
|
||||
|
||||
GLint heap; /* Texture heap currently stored in */
|
||||
|
||||
drmRadeonTexImage image[6][RADEON_MAX_TEXTURE_LEVELS];
|
||||
/* Six, for the cube faces */
|
||||
|
||||
GLint totalSize; /* Total size of the texture
|
||||
including all mipmap levels,
|
||||
and all six cube faces */
|
||||
|
||||
GLuint pp_txfilter; /* hardware register values */
|
||||
GLuint pp_txformat;
|
||||
GLuint pp_txformat_x;
|
||||
GLuint pp_txoffset; /* Image location in texmem.
|
||||
All cube faces follow. */
|
||||
GLuint pp_txsize; /* npot only */
|
||||
GLuint pp_txpitch; /* npot only */
|
||||
GLuint pp_border_color;
|
||||
GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */
|
||||
|
||||
/* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the
|
||||
* images to upload.
|
||||
*/
|
||||
GLint firstLevel;
|
||||
GLint lastLevel;
|
||||
};
|
||||
|
||||
|
||||
struct r200_texture_env_state {
|
||||
r200TexObjPtr texobj;
|
||||
GLenum format;
|
||||
GLenum envMode;
|
||||
};
|
||||
|
||||
#define R200_MAX_TEXTURE_UNITS 3
|
||||
|
||||
struct r200_texture_state {
|
||||
struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS];
|
||||
};
|
||||
|
||||
|
||||
struct r200_state_atom {
|
||||
struct r200_state_atom *next, *prev;
|
||||
const char *name; /* for debug */
|
||||
int cmd_size; /* size in bytes */
|
||||
GLuint idx;
|
||||
int *cmd; /* one or more cmd's */
|
||||
int *lastcmd; /* one or more cmd's */
|
||||
GLboolean (*check)( GLcontext *, int ); /* is this state active? */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Trying to keep these relatively short as the variables are becoming
|
||||
* extravagently long. Drop the R200_ off the front of everything -
|
||||
* I think we know we're in the r200 driver by now, and keep the
|
||||
* prefix to 3 letters unless absolutely impossible.
|
||||
*/
|
||||
|
||||
#define CTX_CMD_0 0
|
||||
#define CTX_PP_MISC 1
|
||||
#define CTX_PP_FOG_COLOR 2
|
||||
#define CTX_RE_SOLID_COLOR 3
|
||||
#define CTX_RB3D_BLENDCNTL 4
|
||||
#define CTX_RB3D_DEPTHOFFSET 5
|
||||
#define CTX_RB3D_DEPTHPITCH 6
|
||||
#define CTX_RB3D_ZSTENCILCNTL 7
|
||||
#define CTX_CMD_1 8
|
||||
#define CTX_PP_CNTL 9
|
||||
#define CTX_RB3D_CNTL 10
|
||||
#define CTX_RB3D_COLOROFFSET 11
|
||||
#define CTX_CMD_2 12 /* why */
|
||||
#define CTX_RB3D_COLORPITCH 13 /* why */
|
||||
#define CTX_STATE_SIZE 14
|
||||
|
||||
#define SET_CMD_0 0
|
||||
#define SET_SE_CNTL 1
|
||||
#define SET_RE_CNTL 2 /* replace se_coord_fmt */
|
||||
#define SET_STATE_SIZE 3
|
||||
|
||||
#define VTE_CMD_0 0
|
||||
#define VTE_SE_VTE_CNTL 1
|
||||
#define VTE_STATE_SIZE 2
|
||||
|
||||
#define LIN_CMD_0 0
|
||||
#define LIN_RE_LINE_PATTERN 1
|
||||
#define LIN_RE_LINE_STATE 2
|
||||
#define LIN_CMD_1 3
|
||||
#define LIN_SE_LINE_WIDTH 4
|
||||
#define LIN_STATE_SIZE 5
|
||||
|
||||
#define MSK_CMD_0 0
|
||||
#define MSK_RB3D_STENCILREFMASK 1
|
||||
#define MSK_RB3D_ROPCNTL 2
|
||||
#define MSK_RB3D_PLANEMASK 3
|
||||
#define MSK_STATE_SIZE 4
|
||||
|
||||
#define VPT_CMD_0 0
|
||||
#define VPT_SE_VPORT_XSCALE 1
|
||||
#define VPT_SE_VPORT_XOFFSET 2
|
||||
#define VPT_SE_VPORT_YSCALE 3
|
||||
#define VPT_SE_VPORT_YOFFSET 4
|
||||
#define VPT_SE_VPORT_ZSCALE 5
|
||||
#define VPT_SE_VPORT_ZOFFSET 6
|
||||
#define VPT_STATE_SIZE 7
|
||||
|
||||
#define ZBS_CMD_0 0
|
||||
#define ZBS_SE_ZBIAS_FACTOR 1
|
||||
#define ZBS_SE_ZBIAS_CONSTANT 2
|
||||
#define ZBS_STATE_SIZE 3
|
||||
|
||||
#define MSC_CMD_0 0
|
||||
#define MSC_RE_MISC 1
|
||||
#define MSC_STATE_SIZE 2
|
||||
|
||||
#define TAM_CMD_0 0
|
||||
#define TAM_DEBUG3 1
|
||||
#define TAM_STATE_SIZE 2
|
||||
|
||||
#define TEX_CMD_0 0
|
||||
#define TEX_PP_TXFILTER 1 /*2c00*/
|
||||
#define TEX_PP_TXFORMAT 2 /*2c04*/
|
||||
#define TEX_PP_TXFORMAT_X 3 /*2c08*/
|
||||
#define TEX_PP_TXSIZE 4 /*2c0c*/
|
||||
#define TEX_PP_TXPITCH 5 /*2c10*/
|
||||
#define TEX_PP_BORDER_COLOR 6 /*2c14*/
|
||||
#define TEX_CMD_1 7
|
||||
#define TEX_PP_TXOFFSET 8 /*2d00 */
|
||||
#define TEX_STATE_SIZE 9
|
||||
|
||||
#define CUBE_CMD_0 0 /* 1 register follows */
|
||||
#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */
|
||||
#define CUBE_CMD_1 2 /* 5 registers follow */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */
|
||||
#define CUBE_STATE_SIZE 8
|
||||
|
||||
#define PIX_CMD_0 0
|
||||
#define PIX_PP_TXCBLEND 1
|
||||
#define PIX_PP_TXCBLEND2 2
|
||||
#define PIX_PP_TXABLEND 3
|
||||
#define PIX_PP_TXABLEND2 4
|
||||
#define PIX_STATE_SIZE 5
|
||||
|
||||
#define TF_CMD_0 0
|
||||
#define TF_TFACTOR_0 1
|
||||
#define TF_TFACTOR_1 2
|
||||
#define TF_TFACTOR_2 3
|
||||
#define TF_TFACTOR_3 4
|
||||
#define TF_TFACTOR_4 5
|
||||
#define TF_TFACTOR_5 6
|
||||
#define TF_STATE_SIZE 7
|
||||
|
||||
#define TCL_CMD_0 0
|
||||
#define TCL_LIGHT_MODEL_CTL_0 1
|
||||
#define TCL_LIGHT_MODEL_CTL_1 2
|
||||
#define TCL_PER_LIGHT_CTL_0 3
|
||||
#define TCL_PER_LIGHT_CTL_1 4
|
||||
#define TCL_PER_LIGHT_CTL_2 5
|
||||
#define TCL_PER_LIGHT_CTL_3 6
|
||||
#define TCL_CMD_1 7
|
||||
#define TCL_UCP_VERT_BLEND_CTL 8
|
||||
#define TCL_STATE_SIZE 9
|
||||
|
||||
#define MSL_CMD_0 0
|
||||
#define MSL_MATRIX_SELECT_0 1
|
||||
#define MSL_MATRIX_SELECT_1 2
|
||||
#define MSL_MATRIX_SELECT_2 3
|
||||
#define MSL_MATRIX_SELECT_3 4
|
||||
#define MSL_MATRIX_SELECT_4 5
|
||||
#define MSL_STATE_SIZE 6
|
||||
|
||||
#define TCG_CMD_0 0
|
||||
#define TCG_TEX_PROC_CTL_2 1
|
||||
#define TCG_TEX_PROC_CTL_3 2
|
||||
#define TCG_TEX_PROC_CTL_0 3
|
||||
#define TCG_TEX_PROC_CTL_1 4
|
||||
#define TCG_TEX_CYL_WRAP_CTL 5
|
||||
#define TCG_STATE_SIZE 6
|
||||
|
||||
#define MTL_CMD_0 0
|
||||
#define MTL_EMMISSIVE_RED 1
|
||||
#define MTL_EMMISSIVE_GREEN 2
|
||||
#define MTL_EMMISSIVE_BLUE 3
|
||||
#define MTL_EMMISSIVE_ALPHA 4
|
||||
#define MTL_AMBIENT_RED 5
|
||||
#define MTL_AMBIENT_GREEN 6
|
||||
#define MTL_AMBIENT_BLUE 7
|
||||
#define MTL_AMBIENT_ALPHA 8
|
||||
#define MTL_DIFFUSE_RED 9
|
||||
#define MTL_DIFFUSE_GREEN 10
|
||||
#define MTL_DIFFUSE_BLUE 11
|
||||
#define MTL_DIFFUSE_ALPHA 12
|
||||
#define MTL_SPECULAR_RED 13
|
||||
#define MTL_SPECULAR_GREEN 14
|
||||
#define MTL_SPECULAR_BLUE 15
|
||||
#define MTL_SPECULAR_ALPHA 16
|
||||
#define MTL_CMD_1 17
|
||||
#define MTL_SHININESS 18
|
||||
#define MTL_STATE_SIZE 19
|
||||
|
||||
#define VAP_CMD_0 0
|
||||
#define VAP_SE_VAP_CNTL 1
|
||||
#define VAP_STATE_SIZE 2
|
||||
|
||||
/* Replaces a lot of packet info from radeon
|
||||
*/
|
||||
#define VTX_CMD_0 0
|
||||
#define VTX_VTXFMT_0 1
|
||||
#define VTX_VTXFMT_1 2
|
||||
#define VTX_TCL_OUTPUT_VTXFMT_0 3
|
||||
#define VTX_TCL_OUTPUT_VTXFMT_1 4
|
||||
#define VTX_CMD_1 5
|
||||
#define VTX_TCL_OUTPUT_COMPSEL 6
|
||||
#define VTX_CMD_2 7
|
||||
#define VTX_STATE_CNTL 8
|
||||
#define VTX_STATE_SIZE 9
|
||||
|
||||
|
||||
#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
|
||||
R200_VTX_COLOR_MASK)
|
||||
|
||||
#define MAT_CMD_0 0
|
||||
#define MAT_ELT_0 1
|
||||
#define MAT_STATE_SIZE 17
|
||||
|
||||
#define GRD_CMD_0 0
|
||||
#define GRD_VERT_GUARD_CLIP_ADJ 1
|
||||
#define GRD_VERT_GUARD_DISCARD_ADJ 2
|
||||
#define GRD_HORZ_GUARD_CLIP_ADJ 3
|
||||
#define GRD_HORZ_GUARD_DISCARD_ADJ 4
|
||||
#define GRD_STATE_SIZE 5
|
||||
|
||||
/* position changes frequently when lighting in modelpos - separate
|
||||
* out to new state item?
|
||||
*/
|
||||
#define LIT_CMD_0 0
|
||||
#define LIT_AMBIENT_RED 1
|
||||
#define LIT_AMBIENT_GREEN 2
|
||||
#define LIT_AMBIENT_BLUE 3
|
||||
#define LIT_AMBIENT_ALPHA 4
|
||||
#define LIT_DIFFUSE_RED 5
|
||||
#define LIT_DIFFUSE_GREEN 6
|
||||
#define LIT_DIFFUSE_BLUE 7
|
||||
#define LIT_DIFFUSE_ALPHA 8
|
||||
#define LIT_SPECULAR_RED 9
|
||||
#define LIT_SPECULAR_GREEN 10
|
||||
#define LIT_SPECULAR_BLUE 11
|
||||
#define LIT_SPECULAR_ALPHA 12
|
||||
#define LIT_POSITION_X 13
|
||||
#define LIT_POSITION_Y 14
|
||||
#define LIT_POSITION_Z 15
|
||||
#define LIT_POSITION_W 16
|
||||
#define LIT_DIRECTION_X 17
|
||||
#define LIT_DIRECTION_Y 18
|
||||
#define LIT_DIRECTION_Z 19
|
||||
#define LIT_DIRECTION_W 20
|
||||
#define LIT_ATTEN_CONST 21
|
||||
#define LIT_ATTEN_LINEAR 22
|
||||
#define LIT_ATTEN_QUADRATIC 23
|
||||
#define LIT_ATTEN_XXX 24
|
||||
#define LIT_CMD_1 25
|
||||
#define LIT_SPOT_DCD 26
|
||||
#define LIT_SPOT_DCM 27
|
||||
#define LIT_SPOT_EXPONENT 28
|
||||
#define LIT_SPOT_CUTOFF 29
|
||||
#define LIT_SPECULAR_THRESH 30
|
||||
#define LIT_RANGE_CUTOFF 31 /* ? */
|
||||
#define LIT_RANGE_ATTEN 32 /* ? */
|
||||
#define LIT_STATE_SIZE 33
|
||||
|
||||
/* Fog
|
||||
*/
|
||||
#define FOG_CMD_0 0
|
||||
#define FOG_R 1
|
||||
#define FOG_C 2
|
||||
#define FOG_D 3
|
||||
#define FOG_PAD 4
|
||||
#define FOG_STATE_SIZE 5
|
||||
|
||||
/* UCP
|
||||
*/
|
||||
#define UCP_CMD_0 0
|
||||
#define UCP_X 1
|
||||
#define UCP_Y 2
|
||||
#define UCP_Z 3
|
||||
#define UCP_W 4
|
||||
#define UCP_STATE_SIZE 5
|
||||
|
||||
/* GLT - Global ambient
|
||||
*/
|
||||
#define GLT_CMD_0 0
|
||||
#define GLT_RED 1
|
||||
#define GLT_GREEN 2
|
||||
#define GLT_BLUE 3
|
||||
#define GLT_ALPHA 4
|
||||
#define GLT_STATE_SIZE 5
|
||||
|
||||
/* EYE
|
||||
*/
|
||||
#define EYE_CMD_0 0
|
||||
#define EYE_X 1
|
||||
#define EYE_Y 2
|
||||
#define EYE_Z 3
|
||||
#define EYE_RESCALE_FACTOR 4
|
||||
#define EYE_STATE_SIZE 5
|
||||
|
||||
/* CST - constant state
|
||||
*/
|
||||
#define CST_CMD_0 0
|
||||
#define CST_PP_CNTL_X 1
|
||||
#define CST_CMD_1 2
|
||||
#define CST_RB3D_DEPTHXY_OFFSET 3
|
||||
#define CST_CMD_2 4
|
||||
#define CST_RE_AUX_SCISSOR_CNTL 5
|
||||
#define CST_CMD_3 6
|
||||
#define CST_RE_SCISSOR_TL_0 7
|
||||
#define CST_RE_SCISSOR_BR_0 8
|
||||
#define CST_CMD_4 9
|
||||
#define CST_SE_VAP_CNTL_STATUS 10
|
||||
#define CST_CMD_5 11
|
||||
#define CST_RE_POINTSIZE 12
|
||||
#define CST_CMD_6 13
|
||||
#define CST_SE_TCL_INPUT_VTX_0 14
|
||||
#define CST_SE_TCL_INPUT_VTX_1 15
|
||||
#define CST_SE_TCL_INPUT_VTX_2 16
|
||||
#define CST_SE_TCL_INPUT_VTX_3 17
|
||||
#define CST_STATE_SIZE 18
|
||||
|
||||
|
||||
|
||||
|
||||
struct r200_hw_state {
|
||||
/* All state should be on one of these lists:
|
||||
*/
|
||||
struct r200_state_atom dirty; /* dirty list head placeholder */
|
||||
struct r200_state_atom clean; /* clean list head placeholder */
|
||||
|
||||
/* Hardware state, stored as cmdbuf commands:
|
||||
* -- Need to doublebuffer for
|
||||
* - reviving state after loss of context
|
||||
* - eliding noop statechange loops? (except line stipple count)
|
||||
*/
|
||||
struct r200_state_atom ctx;
|
||||
struct r200_state_atom set;
|
||||
struct r200_state_atom vte;
|
||||
struct r200_state_atom lin;
|
||||
struct r200_state_atom msk;
|
||||
struct r200_state_atom vpt;
|
||||
struct r200_state_atom vap;
|
||||
struct r200_state_atom vtx;
|
||||
struct r200_state_atom tcl;
|
||||
struct r200_state_atom msl;
|
||||
struct r200_state_atom tcg;
|
||||
struct r200_state_atom msc;
|
||||
struct r200_state_atom cst;
|
||||
struct r200_state_atom tam;
|
||||
struct r200_state_atom tf;
|
||||
struct r200_state_atom tex[2];
|
||||
struct r200_state_atom cube[2];
|
||||
struct r200_state_atom zbs;
|
||||
struct r200_state_atom mtl[2];
|
||||
struct r200_state_atom mat[5];
|
||||
struct r200_state_atom lit[8]; /* includes vec, scl commands */
|
||||
struct r200_state_atom ucp[6];
|
||||
struct r200_state_atom pix[6]; /* pixshader stages */
|
||||
struct r200_state_atom eye; /* eye pos */
|
||||
struct r200_state_atom grd; /* guard band clipping */
|
||||
struct r200_state_atom fog;
|
||||
struct r200_state_atom glt;
|
||||
};
|
||||
|
||||
struct r200_state {
|
||||
/* Derived state for internal purposes:
|
||||
*/
|
||||
struct r200_colorbuffer_state color;
|
||||
struct r200_depthbuffer_state depth;
|
||||
struct r200_pixel_state pixel;
|
||||
struct r200_scissor_state scissor;
|
||||
struct r200_stencilbuffer_state stencil;
|
||||
struct r200_stipple_state stipple;
|
||||
struct r200_texture_state texture;
|
||||
};
|
||||
|
||||
struct r200_texture {
|
||||
r200TexObj objects[R200_NR_TEX_HEAPS];
|
||||
r200TexObj swapped;
|
||||
|
||||
memHeap_t *heap[R200_NR_TEX_HEAPS];
|
||||
GLint age[R200_NR_TEX_HEAPS];
|
||||
|
||||
GLint numHeaps;
|
||||
};
|
||||
|
||||
/* Need refcounting on dma buffers:
|
||||
*/
|
||||
struct r200_dma_buffer {
|
||||
int refcount; /* the number of retained regions in buf */
|
||||
drmBufPtr buf;
|
||||
};
|
||||
|
||||
#define GET_START(rvb) (rmesa->r200Screen->agp_buffer_offset + \
|
||||
(rvb)->address - rmesa->dma.buf0_address + \
|
||||
(rvb)->start)
|
||||
|
||||
/* A retained region, eg vertices for indexed vertices.
|
||||
*/
|
||||
struct r200_dma_region {
|
||||
struct r200_dma_buffer *buf;
|
||||
char *address; /* == buf->address */
|
||||
int start, end, ptr; /* offsets from start of buf */
|
||||
int aos_start;
|
||||
int aos_stride;
|
||||
int aos_size;
|
||||
};
|
||||
|
||||
|
||||
struct r200_dma {
|
||||
/* Active dma region. Allocations for vertices and retained
|
||||
* regions come from here. Also used for emitting random vertices,
|
||||
* these may be flushed by calling flush_current();
|
||||
*/
|
||||
struct r200_dma_region current;
|
||||
|
||||
void (*flush)( r200ContextPtr );
|
||||
|
||||
char *buf0_address; /* start of buf[0], for index calcs */
|
||||
GLuint nr_released_bufs; /* flush after so many buffers released */
|
||||
};
|
||||
|
||||
struct r200_dri_mirror {
|
||||
__DRIcontextPrivate *context; /* DRI context */
|
||||
__DRIscreenPrivate *screen; /* DRI screen */
|
||||
__DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
|
||||
|
||||
drmContext hwContext;
|
||||
drmLock *hwLock;
|
||||
int fd;
|
||||
int drmMinor;
|
||||
};
|
||||
|
||||
|
||||
#define R200_CMD_BUF_SZ (8*1024)
|
||||
|
||||
struct r200_store {
|
||||
GLuint statenr;
|
||||
GLuint primnr;
|
||||
char cmd_buf[R200_CMD_BUF_SZ];
|
||||
int cmd_used;
|
||||
int elts_start;
|
||||
};
|
||||
|
||||
|
||||
/* r200_tcl.c
|
||||
*/
|
||||
struct r200_tcl_info {
|
||||
GLuint vertex_format;
|
||||
GLint last_offset;
|
||||
GLuint hw_primitive;
|
||||
|
||||
struct r200_dma_region *aos_components[8];
|
||||
GLuint nr_aos_components;
|
||||
|
||||
GLuint *Elts;
|
||||
|
||||
struct r200_dma_region indexed_verts;
|
||||
struct r200_dma_region obj;
|
||||
struct r200_dma_region rgba;
|
||||
struct r200_dma_region spec;
|
||||
struct r200_dma_region fog;
|
||||
struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
|
||||
struct r200_dma_region norm;
|
||||
};
|
||||
|
||||
|
||||
/* r200_swtcl.c
|
||||
*/
|
||||
struct r200_swtcl_info {
|
||||
GLuint SetupIndex;
|
||||
GLuint SetupNewInputs;
|
||||
GLuint RenderIndex;
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_stride_shift;
|
||||
GLuint vertex_format;
|
||||
char *verts;
|
||||
|
||||
/* Fallback rasterization functions
|
||||
*/
|
||||
r200_point_func draw_point;
|
||||
r200_line_func draw_line;
|
||||
r200_tri_func draw_tri;
|
||||
|
||||
GLuint hw_primitive;
|
||||
GLenum render_primitive;
|
||||
GLuint numverts;
|
||||
|
||||
struct r200_dma_region indexed_verts;
|
||||
};
|
||||
|
||||
|
||||
struct r200_ioctl {
|
||||
GLuint vertex_offset;
|
||||
GLuint vertex_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define R200_MAX_PRIMS 64
|
||||
|
||||
|
||||
/* Want to keep a cache of these around. Each is parameterized by
|
||||
* only a single value which has only a small range. Only expect a
|
||||
* few, so just rescan the list each time?
|
||||
*/
|
||||
struct dynfn {
|
||||
struct dynfn *next, *prev;
|
||||
int key[2];
|
||||
char *code;
|
||||
};
|
||||
|
||||
struct dfn_lists {
|
||||
struct dynfn Vertex2f;
|
||||
struct dynfn Vertex2fv;
|
||||
struct dynfn Vertex3f;
|
||||
struct dynfn Vertex3fv;
|
||||
struct dynfn Color4ub;
|
||||
struct dynfn Color4ubv;
|
||||
struct dynfn Color3ub;
|
||||
struct dynfn Color3ubv;
|
||||
struct dynfn Color4f;
|
||||
struct dynfn Color4fv;
|
||||
struct dynfn Color3f;
|
||||
struct dynfn Color3fv;
|
||||
struct dynfn SecondaryColor3ubEXT;
|
||||
struct dynfn SecondaryColor3ubvEXT;
|
||||
struct dynfn SecondaryColor3fEXT;
|
||||
struct dynfn SecondaryColor3fvEXT;
|
||||
struct dynfn Normal3f;
|
||||
struct dynfn Normal3fv;
|
||||
struct dynfn TexCoord2f;
|
||||
struct dynfn TexCoord2fv;
|
||||
struct dynfn TexCoord1f;
|
||||
struct dynfn TexCoord1fv;
|
||||
struct dynfn MultiTexCoord2fARB;
|
||||
struct dynfn MultiTexCoord2fvARB;
|
||||
struct dynfn MultiTexCoord1fARB;
|
||||
struct dynfn MultiTexCoord1fvARB;
|
||||
};
|
||||
|
||||
struct _vb;
|
||||
|
||||
struct dfn_generators {
|
||||
struct dynfn *(*Vertex2f)( GLcontext *, const int * );
|
||||
struct dynfn *(*Vertex2fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*Vertex3f)( GLcontext *, const int * );
|
||||
struct dynfn *(*Vertex3fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color4ub)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color4ubv)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color3ub)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color3ubv)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color4f)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color4fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color3f)( GLcontext *, const int * );
|
||||
struct dynfn *(*Color3fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * );
|
||||
struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * );
|
||||
struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * );
|
||||
struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * );
|
||||
struct dynfn *(*Normal3f)( GLcontext *, const int * );
|
||||
struct dynfn *(*Normal3fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*TexCoord2f)( GLcontext *, const int * );
|
||||
struct dynfn *(*TexCoord2fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*TexCoord1f)( GLcontext *, const int * );
|
||||
struct dynfn *(*TexCoord1fv)( GLcontext *, const int * );
|
||||
struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * );
|
||||
struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * );
|
||||
struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * );
|
||||
struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * );
|
||||
};
|
||||
|
||||
|
||||
struct r200_vb {
|
||||
/* Keep these first: referenced from codegen templates:
|
||||
*/
|
||||
GLint counter, initial_counter;
|
||||
GLint *dmaptr;
|
||||
void (*notify)( void );
|
||||
GLint vertex_size;
|
||||
|
||||
/* A maximum total of 15 elements per vertex: 3 floats for position, 3
|
||||
* floats for normal, 4 floats for color, 4 bytes for secondary color,
|
||||
* 2 floats for each texture unit (4 floats total).
|
||||
*
|
||||
* As soon as the 3rd TMU is supported or cube maps (or 3D textures) are
|
||||
* supported, this value will grow.
|
||||
*
|
||||
* The position data is never actually stored here, so 3 elements could be
|
||||
* trimmed out of the buffer.
|
||||
*/
|
||||
union { float f; int i; r200_color_t color; } vertex[15];
|
||||
|
||||
GLfloat *normalptr;
|
||||
GLfloat *floatcolorptr;
|
||||
r200_color_t *colorptr;
|
||||
GLfloat *floatspecptr;
|
||||
r200_color_t *specptr;
|
||||
GLfloat *texcoordptr[2];
|
||||
|
||||
GLcontext *context; /* current context : Single thread only! */
|
||||
};
|
||||
|
||||
struct r200_prim {
|
||||
GLuint start;
|
||||
GLuint end;
|
||||
GLuint prim;
|
||||
};
|
||||
|
||||
struct r200_vbinfo {
|
||||
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
|
||||
GLuint primflags;
|
||||
GLboolean enabled; /* R200_NO_VTXFMT//R200_NO_TCL env vars */
|
||||
GLboolean installed;
|
||||
GLboolean fell_back;
|
||||
GLboolean recheck;
|
||||
GLint initial_counter;
|
||||
GLint nrverts;
|
||||
GLuint vtxfmt_0, vtxfmt_1;
|
||||
|
||||
GLuint installed_vertex_format;
|
||||
GLuint installed_color_3f_sz;
|
||||
|
||||
struct r200_prim primlist[R200_MAX_PRIMS];
|
||||
int nrprims;
|
||||
|
||||
struct dfn_lists dfn_cache;
|
||||
struct dfn_generators codegen;
|
||||
GLvertexformat vtxfmt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct r200_context {
|
||||
GLcontext *glCtx; /* Mesa context */
|
||||
|
||||
/* Driver and hardware state management
|
||||
*/
|
||||
struct r200_hw_state hw;
|
||||
struct r200_state state;
|
||||
|
||||
/* Texture object bookkeeping
|
||||
*/
|
||||
struct r200_texture texture;
|
||||
|
||||
|
||||
/* Rasterization and vertex state:
|
||||
*/
|
||||
GLuint TclFallback;
|
||||
GLuint Fallback;
|
||||
GLuint NewGLState;
|
||||
|
||||
|
||||
/* Temporaries for translating away float colors:
|
||||
*/
|
||||
struct gl_client_array UbyteColor;
|
||||
struct gl_client_array UbyteSecondaryColor;
|
||||
|
||||
/* Vertex buffers
|
||||
*/
|
||||
struct r200_ioctl ioctl;
|
||||
struct r200_dma dma;
|
||||
struct r200_store store;
|
||||
|
||||
/* Page flipping
|
||||
*/
|
||||
GLuint doPageFlip;
|
||||
|
||||
/* Busy waiting
|
||||
*/
|
||||
GLuint do_usleeps;
|
||||
GLuint do_irqs;
|
||||
GLuint irqsEmitted;
|
||||
drmRadeonIrqWait iw;
|
||||
|
||||
/* Clientdata textures;
|
||||
*/
|
||||
GLuint prefer_agp_client_texturing;
|
||||
|
||||
/* Drawable, cliprect and scissor information
|
||||
*/
|
||||
GLuint numClipRects; /* Cliprects for the draw buffer */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
unsigned int lastStamp;
|
||||
GLboolean lost_context;
|
||||
r200ScreenPtr r200Screen; /* Screen private DRI data */
|
||||
RADEONSAREAPrivPtr sarea; /* Private SAREA data */
|
||||
|
||||
/* TCL stuff
|
||||
*/
|
||||
GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS];
|
||||
GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS];
|
||||
GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS];
|
||||
GLuint TexMatEnabled;
|
||||
GLuint TexMatCompSel;
|
||||
GLuint TexGenEnabled;
|
||||
GLuint TexGenInputs;
|
||||
GLuint TexGenCompSel;
|
||||
GLmatrix tmpmat;
|
||||
|
||||
/* VBI
|
||||
*/
|
||||
GLuint vbl_seq;
|
||||
|
||||
/* r200_tcl.c
|
||||
*/
|
||||
struct r200_tcl_info tcl;
|
||||
|
||||
/* r200_swtcl.c
|
||||
*/
|
||||
struct r200_swtcl_info swtcl;
|
||||
|
||||
/* r200_vtxfmt.c
|
||||
*/
|
||||
struct r200_vbinfo vb;
|
||||
|
||||
/* Mirrors of some DRI state
|
||||
*/
|
||||
struct r200_dri_mirror dri;
|
||||
};
|
||||
|
||||
#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx))
|
||||
|
||||
|
||||
static __inline GLuint r200PackColor( GLuint cpp,
|
||||
GLubyte r, GLubyte g,
|
||||
GLubyte b, GLubyte a )
|
||||
{
|
||||
switch ( cpp ) {
|
||||
case 2:
|
||||
return PACK_COLOR_565( r, g, b );
|
||||
case 4:
|
||||
return PACK_COLOR_8888( a, r, g, b );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define R200_OLD_PACKETS 0
|
||||
|
||||
|
||||
extern void r200DestroyContext( __DRIcontextPrivate *driContextPriv );
|
||||
extern GLboolean r200CreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate);
|
||||
extern void r200SwapBuffers( __DRIdrawablePrivate *dPriv );
|
||||
extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv );
|
||||
extern GLboolean r200UnbindContext( __DRIcontextPrivate *driContextPriv );
|
||||
|
||||
/* ================================================================
|
||||
* Debugging:
|
||||
*/
|
||||
#define DO_DEBUG 1
|
||||
|
||||
#if DO_DEBUG
|
||||
extern int R200_DEBUG;
|
||||
#else
|
||||
#define R200_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define DEBUG_TEXTURE 0x001
|
||||
#define DEBUG_STATE 0x002
|
||||
#define DEBUG_IOCTL 0x004
|
||||
#define DEBUG_PRIMS 0x008
|
||||
#define DEBUG_VERTS 0x010
|
||||
#define DEBUG_FALLBACKS 0x020
|
||||
#define DEBUG_VFMT 0x040
|
||||
#define DEBUG_CODEGEN 0x080
|
||||
#define DEBUG_VERBOSE 0x100
|
||||
#define DEBUG_DRI 0x200
|
||||
#define DEBUG_DMA 0x400
|
||||
#define DEBUG_SANITY 0x800
|
||||
#define DEBUG_SYNC 0x1000
|
||||
#define DEBUG_PIXEL 0x2000
|
||||
#define DEBUG_MEMORY 0x4000
|
||||
|
||||
#endif
|
||||
#endif /* __R200_CONTEXT_H__ */
|
||||
934
src/mesa/drivers/dri/r200/r200_ioctl.c
Normal file
934
src/mesa/drivers/dri/r200/r200_ioctl.c
Normal file
@@ -0,0 +1,934 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_sanity.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#define R200_TIMEOUT 512
|
||||
#define R200_IDLE_RETRY 16
|
||||
|
||||
|
||||
static void do_usleep( int nr, const char *caller )
|
||||
{
|
||||
//if (1) fprintf(stderr, "usleep %d in %s\n", nr, caller );
|
||||
if (1) usleep( nr );
|
||||
}
|
||||
|
||||
static void r200WaitForIdle( r200ContextPtr rmesa );
|
||||
|
||||
|
||||
int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
|
||||
{
|
||||
int ret, i;
|
||||
drmRadeonCmdBuffer cmd;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL) {
|
||||
fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
|
||||
|
||||
if (0 & R200_DEBUG & DEBUG_VERBOSE)
|
||||
for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 )
|
||||
fprintf(stderr, "%d: %x\n", i/4,
|
||||
*(int *)(&rmesa->store.cmd_buf[i]));
|
||||
}
|
||||
|
||||
if (R200_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__,
|
||||
rmesa->dma.nr_released_bufs);
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_SANITY) {
|
||||
if (rmesa->state.scissor.enabled)
|
||||
ret = r200SanityCmdBuffer( rmesa,
|
||||
rmesa->state.scissor.numClipRects,
|
||||
rmesa->state.scissor.pClipRects);
|
||||
else
|
||||
ret = r200SanityCmdBuffer( rmesa,
|
||||
rmesa->numClipRects,
|
||||
rmesa->pClipRects);
|
||||
if (ret) {
|
||||
fprintf(stderr, "drmSanityCommandWrite: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_MEMORY) {
|
||||
if (!r200ValidateTexObjs( rmesa )) {
|
||||
fprintf(stderr, " -- tex memory is inconsistent - expect mangled textures\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cmd.bufsz = rmesa->store.cmd_used;
|
||||
cmd.buf = rmesa->store.cmd_buf;
|
||||
|
||||
if (rmesa->state.scissor.enabled) {
|
||||
cmd.nbox = rmesa->state.scissor.numClipRects;
|
||||
cmd.boxes = (drmClipRect *)rmesa->state.scissor.pClipRects;
|
||||
} else {
|
||||
cmd.nbox = rmesa->numClipRects;
|
||||
cmd.boxes = (drmClipRect *)rmesa->pClipRects;
|
||||
}
|
||||
|
||||
ret = drmCommandWrite( rmesa->dri.fd,
|
||||
DRM_RADEON_CMDBUF,
|
||||
&cmd, sizeof(cmd) );
|
||||
|
||||
if (ret)
|
||||
fprintf(stderr, "drmCommandWrite: %d\n", ret);
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__);
|
||||
r200WaitForIdleLocked( rmesa );
|
||||
}
|
||||
|
||||
|
||||
out:
|
||||
rmesa->store.primnr = 0;
|
||||
rmesa->store.statenr = 0;
|
||||
rmesa->store.cmd_used = 0;
|
||||
rmesa->dma.nr_released_bufs = 0;
|
||||
/* rmesa->lost_context = 0; */
|
||||
rmesa->lost_context = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Note: does not emit any commands to avoid recursion on
|
||||
* r200AllocCmdBuf.
|
||||
*/
|
||||
void r200FlushCmdBuf( r200ContextPtr rmesa, const char *caller )
|
||||
{
|
||||
int ret;
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
ret = r200FlushCmdBufLocked( rmesa, caller );
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret);
|
||||
exit(ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
* Hardware vertex buffer handling
|
||||
*/
|
||||
|
||||
|
||||
void r200RefillCurrentDmaRegion( r200ContextPtr rmesa )
|
||||
{
|
||||
struct r200_dma_buffer *dmabuf;
|
||||
int fd = rmesa->dri.fd;
|
||||
int index = 0;
|
||||
int size = 0;
|
||||
drmDMAReq dma;
|
||||
int ret;
|
||||
|
||||
if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->dma.flush) {
|
||||
rmesa->dma.flush( rmesa );
|
||||
}
|
||||
|
||||
if (rmesa->dma.current.buf)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
|
||||
|
||||
if (rmesa->dma.nr_released_bufs > 4)
|
||||
r200FlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
|
||||
dma.context = rmesa->dri.hwContext;
|
||||
dma.send_count = 0;
|
||||
dma.send_list = NULL;
|
||||
dma.send_sizes = NULL;
|
||||
dma.flags = 0;
|
||||
dma.request_count = 1;
|
||||
dma.request_size = RADEON_BUFFER_SIZE;
|
||||
dma.request_list = &index;
|
||||
dma.request_sizes = &size;
|
||||
dma.granted_count = 0;
|
||||
|
||||
LOCK_HARDWARE(rmesa); /* no need to validate */
|
||||
|
||||
while (1) {
|
||||
ret = drmDMA( fd, &dma );
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
if (rmesa->dma.nr_released_bufs) {
|
||||
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
}
|
||||
|
||||
if (rmesa->do_usleeps) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
do_usleep(1, __FUNCTION__);
|
||||
LOCK_HARDWARE( rmesa );
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE(rmesa);
|
||||
|
||||
if (R200_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "Allocated buffer %d\n", index);
|
||||
|
||||
dmabuf = CALLOC_STRUCT( r200_dma_buffer );
|
||||
dmabuf->buf = &rmesa->r200Screen->buffers->list[index];
|
||||
dmabuf->refcount = 1;
|
||||
|
||||
rmesa->dma.current.buf = dmabuf;
|
||||
rmesa->dma.current.address = dmabuf->buf->address;
|
||||
rmesa->dma.current.end = dmabuf->buf->total;
|
||||
rmesa->dma.current.start = 0;
|
||||
rmesa->dma.current.ptr = 0;
|
||||
}
|
||||
|
||||
void r200ReleaseDmaRegion( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
const char *caller )
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
|
||||
|
||||
if (!region->buf)
|
||||
return;
|
||||
|
||||
if (rmesa->dma.flush)
|
||||
rmesa->dma.flush( rmesa );
|
||||
|
||||
if (--region->buf->refcount == 0) {
|
||||
drmRadeonCmdHeader *cmd;
|
||||
|
||||
if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
|
||||
fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
|
||||
region->buf->buf->idx);
|
||||
|
||||
cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sizeof(*cmd),
|
||||
__FUNCTION__ );
|
||||
cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
|
||||
cmd->dma.buf_idx = region->buf->buf->idx;
|
||||
FREE(region->buf);
|
||||
rmesa->dma.nr_released_bufs++;
|
||||
}
|
||||
|
||||
region->buf = 0;
|
||||
region->start = 0;
|
||||
}
|
||||
|
||||
/* Allocates a region from rmesa->dma.current. If there isn't enough
|
||||
* space in current, grab a new buffer (and discard what was left of current)
|
||||
*/
|
||||
void r200AllocDmaRegion( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int bytes,
|
||||
int alignment )
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
|
||||
|
||||
if (rmesa->dma.flush)
|
||||
rmesa->dma.flush( rmesa );
|
||||
|
||||
if (region->buf)
|
||||
r200ReleaseDmaRegion( rmesa, region, __FUNCTION__ );
|
||||
|
||||
alignment--;
|
||||
rmesa->dma.current.start = rmesa->dma.current.ptr =
|
||||
(rmesa->dma.current.ptr + alignment) & ~alignment;
|
||||
|
||||
if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
|
||||
r200RefillCurrentDmaRegion( rmesa );
|
||||
|
||||
region->start = rmesa->dma.current.start;
|
||||
region->ptr = rmesa->dma.current.start;
|
||||
region->end = rmesa->dma.current.start + bytes;
|
||||
region->address = rmesa->dma.current.address;
|
||||
region->buf = rmesa->dma.current.buf;
|
||||
region->buf->refcount++;
|
||||
|
||||
rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
|
||||
rmesa->dma.current.start =
|
||||
rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
|
||||
}
|
||||
|
||||
void r200AllocDmaRegionVerts( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int numverts,
|
||||
int vertsize,
|
||||
int alignment )
|
||||
{
|
||||
r200AllocDmaRegion( rmesa, region, vertsize * numverts, alignment );
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* SwapBuffers with client-side throttling
|
||||
*/
|
||||
|
||||
static GLuint r200GetLastFrame(r200ContextPtr rmesa)
|
||||
{
|
||||
drmRadeonGetParam gp;
|
||||
int ret;
|
||||
GLuint frame;
|
||||
|
||||
gp.param = RADEON_PARAM_LAST_FRAME;
|
||||
gp.value = (int *)&frame;
|
||||
ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp) );
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void r200EmitIrqLocked( r200ContextPtr rmesa )
|
||||
{
|
||||
drmRadeonIrqEmit ie;
|
||||
int ret;
|
||||
|
||||
ie.irq_seq = &rmesa->iw.irq_seq;
|
||||
ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT,
|
||||
&ie, sizeof(ie) );
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void r200WaitIrq( r200ContextPtr rmesa )
|
||||
{
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT,
|
||||
&rmesa->iw, sizeof(rmesa->iw) );
|
||||
} while (ret && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void r200WaitForFrameCompletion( r200ContextPtr rmesa )
|
||||
{
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
|
||||
if (rmesa->do_irqs) {
|
||||
if (r200GetLastFrame(rmesa) < sarea->last_frame) {
|
||||
if (!rmesa->irqsEmitted) {
|
||||
while (r200GetLastFrame (rmesa) < sarea->last_frame)
|
||||
;
|
||||
}
|
||||
else {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
r200WaitIrq( rmesa );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
}
|
||||
rmesa->irqsEmitted = 10;
|
||||
}
|
||||
|
||||
if (rmesa->irqsEmitted) {
|
||||
r200EmitIrqLocked( rmesa );
|
||||
rmesa->irqsEmitted--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (r200GetLastFrame (rmesa) < sarea->last_frame) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
if (rmesa->do_usleeps)
|
||||
do_usleep(1, __FUNCTION__);
|
||||
LOCK_HARDWARE( rmesa );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Copy the back color buffer to the front color buffer.
|
||||
*/
|
||||
void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
r200ContextPtr rmesa;
|
||||
GLint nbox, i, ret;
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
assert(dPriv->driContextPriv->driverPrivate);
|
||||
|
||||
rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_IOCTL ) {
|
||||
fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx );
|
||||
}
|
||||
|
||||
R200_FIREVERTICES( rmesa );
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
|
||||
/* Throttle the frame rate -- only allow one pending swap buffers
|
||||
* request at a time.
|
||||
*/
|
||||
r200WaitForFrameCompletion( rmesa );
|
||||
|
||||
r200WaitForVBlank( rmesa );
|
||||
|
||||
nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */
|
||||
|
||||
for ( i = 0 ; i < nbox ; ) {
|
||||
GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
|
||||
XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects;
|
||||
XF86DRIClipRectPtr b = rmesa->sarea->boxes;
|
||||
GLint n = 0;
|
||||
|
||||
for ( ; i < nr ; i++ ) {
|
||||
*b++ = box[i];
|
||||
n++;
|
||||
}
|
||||
rmesa->sarea->nbox = n;
|
||||
|
||||
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
rmesa->lost_context = 1;
|
||||
}
|
||||
|
||||
void r200PageFlip( const __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
r200ContextPtr rmesa;
|
||||
GLint ret;
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
assert(dPriv->driContextPriv->driverPrivate);
|
||||
|
||||
rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_IOCTL ) {
|
||||
fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
|
||||
rmesa->sarea->pfCurrentPage);
|
||||
}
|
||||
|
||||
R200_FIREVERTICES( rmesa );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
if (!rmesa->dri.drawable->numClipRects) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
usleep( 10000 ); /* throttle invisible client 10ms */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to do this for the perf box placement:
|
||||
*/
|
||||
{
|
||||
XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects;
|
||||
XF86DRIClipRectPtr b = rmesa->sarea->boxes;
|
||||
b[0] = box[0];
|
||||
rmesa->sarea->nbox = 1;
|
||||
}
|
||||
|
||||
/* Throttle the frame rate -- only allow a few pending swap buffers
|
||||
* request at a time.
|
||||
*/
|
||||
r200WaitForFrameCompletion( rmesa );
|
||||
|
||||
r200WaitForVBlank( rmesa );
|
||||
|
||||
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_R200_FLIP: return = %d\n", ret );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( rmesa->sarea->pfCurrentPage == 1 ) {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch;
|
||||
} else {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch;
|
||||
}
|
||||
|
||||
R200_STATECHANGE( rmesa, ctx );
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
|
||||
}
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Buffer clear
|
||||
*/
|
||||
static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
GLint cx, GLint cy, GLint cw, GLint ch )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
GLuint flags = 0;
|
||||
GLuint color_mask = 0;
|
||||
GLint ret, i;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_IOCTL ) {
|
||||
fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
|
||||
__FUNCTION__, all, cx, cy, cw, ch );
|
||||
}
|
||||
|
||||
{
|
||||
LOCK_HARDWARE( rmesa );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
if ( dPriv->numClipRects == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
r200EmitState( rmesa );
|
||||
|
||||
/* Need to cope with lostcontext here as kernel relies on
|
||||
* some residual state:
|
||||
*/
|
||||
R200_FIREVERTICES( rmesa );
|
||||
|
||||
if ( mask & DD_FRONT_LEFT_BIT ) {
|
||||
flags |= RADEON_FRONT;
|
||||
color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
|
||||
mask &= ~DD_FRONT_LEFT_BIT;
|
||||
}
|
||||
|
||||
if ( mask & DD_BACK_LEFT_BIT ) {
|
||||
flags |= RADEON_BACK;
|
||||
color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
|
||||
mask &= ~DD_BACK_LEFT_BIT;
|
||||
}
|
||||
|
||||
if ( mask & DD_DEPTH_BIT ) {
|
||||
if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */
|
||||
mask &= ~DD_DEPTH_BIT;
|
||||
}
|
||||
|
||||
if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) {
|
||||
flags |= RADEON_STENCIL;
|
||||
mask &= ~DD_STENCIL_BIT;
|
||||
}
|
||||
|
||||
if ( mask )
|
||||
_swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
|
||||
|
||||
if ( !flags )
|
||||
return;
|
||||
|
||||
/* Flip top to bottom */
|
||||
cx += dPriv->x;
|
||||
cy = dPriv->y + dPriv->h - cy - ch;
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
/* Throttle the number of clear ioctls we do.
|
||||
*/
|
||||
while ( 1 ) {
|
||||
drmRadeonGetParam gp;
|
||||
int ret;
|
||||
int clear;
|
||||
|
||||
gp.param = RADEON_PARAM_LAST_CLEAR;
|
||||
gp.value = (int *)&clear;
|
||||
ret = drmCommandWriteRead( rmesa->dri.fd,
|
||||
DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Clear throttling needs more thought.
|
||||
*/
|
||||
if ( rmesa->sarea->last_clear - clear <= 25 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rmesa->do_usleeps) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
do_usleep(1, __FUNCTION__);
|
||||
LOCK_HARDWARE( rmesa );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( i = 0 ; i < dPriv->numClipRects ; ) {
|
||||
GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
|
||||
XF86DRIClipRectPtr box = dPriv->pClipRects;
|
||||
XF86DRIClipRectPtr b = rmesa->sarea->boxes;
|
||||
drmRadeonClearType clear;
|
||||
drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
|
||||
GLint n = 0;
|
||||
|
||||
if ( !all ) {
|
||||
for ( ; i < nr ; i++ ) {
|
||||
GLint x = box[i].x1;
|
||||
GLint y = box[i].y1;
|
||||
GLint w = box[i].x2 - x;
|
||||
GLint h = box[i].y2 - y;
|
||||
|
||||
if ( x < cx ) w -= cx - x, x = cx;
|
||||
if ( y < cy ) h -= cy - y, y = cy;
|
||||
if ( x + w > cx + cw ) w = cx + cw - x;
|
||||
if ( y + h > cy + ch ) h = cy + ch - y;
|
||||
if ( w <= 0 ) continue;
|
||||
if ( h <= 0 ) continue;
|
||||
|
||||
b->x1 = x;
|
||||
b->y1 = y;
|
||||
b->x2 = x + w;
|
||||
b->y2 = y + h;
|
||||
b++;
|
||||
n++;
|
||||
}
|
||||
} else {
|
||||
for ( ; i < nr ; i++ ) {
|
||||
*b++ = box[i];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
rmesa->sarea->nbox = n;
|
||||
|
||||
clear.flags = flags;
|
||||
clear.clear_color = rmesa->state.color.clear;
|
||||
clear.clear_depth = 0; /* not used */
|
||||
clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
|
||||
clear.depth_mask = rmesa->state.stencil.clear;
|
||||
clear.depth_boxes = depth_boxes;
|
||||
|
||||
n--;
|
||||
b = rmesa->sarea->boxes;
|
||||
for ( ; n >= 0 ; n-- ) {
|
||||
depth_boxes[n].f[RADEON_CLEAR_X1] = (float)b[n].x1;
|
||||
depth_boxes[n].f[RADEON_CLEAR_Y1] = (float)b[n].y1;
|
||||
depth_boxes[n].f[RADEON_CLEAR_X2] = (float)b[n].x2;
|
||||
depth_boxes[n].f[RADEON_CLEAR_Y2] = (float)b[n].y2;
|
||||
depth_boxes[n].f[RADEON_CLEAR_DEPTH] = ctx->Depth.Clear;
|
||||
}
|
||||
|
||||
ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR,
|
||||
&clear, sizeof(drmRadeonClearType));
|
||||
|
||||
|
||||
if ( ret ) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
rmesa->lost_context = 1;
|
||||
}
|
||||
|
||||
|
||||
void r200WaitForIdleLocked( r200ContextPtr rmesa )
|
||||
{
|
||||
int ret;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE);
|
||||
if (ret)
|
||||
do_usleep( 1, __FUNCTION__ );
|
||||
} while (ret && ++i < 100);
|
||||
|
||||
if ( ret < 0 ) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
fprintf( stderr, "Error: R200 timed out... exiting\n" );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
static void r200WaitForIdle( r200ContextPtr rmesa )
|
||||
{
|
||||
LOCK_HARDWARE(rmesa);
|
||||
r200WaitForIdleLocked( rmesa );
|
||||
UNLOCK_HARDWARE(rmesa);
|
||||
}
|
||||
|
||||
|
||||
void r200WaitForVBlank( r200ContextPtr rmesa )
|
||||
{
|
||||
#if 0
|
||||
drmVBlank vbl;
|
||||
int ret;
|
||||
|
||||
if ( !rmesa->r200Screen->irq )
|
||||
return;
|
||||
|
||||
if ( getenv("LIBGL_SYNC_REFRESH") ) {
|
||||
/* Wait for until the next vertical blank */
|
||||
vbl.request.type = DRM_VBLANK_RELATIVE;
|
||||
vbl.request.sequence = 1;
|
||||
} else if ( getenv("LIBGL_THROTTLE_REFRESH") ) {
|
||||
/* Wait for at least one vertical blank since the last call */
|
||||
vbl.request.type = DRM_VBLANK_ABSOLUTE;
|
||||
vbl.request.sequence = rmesa->vbl_seq + 1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) {
|
||||
fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be"
|
||||
" working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
|
||||
" and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
|
||||
exit(1);
|
||||
} else if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret);
|
||||
|
||||
rmesa->vbl_seq = vbl.reply.sequence;
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
#endif
|
||||
}
|
||||
|
||||
void r200Flush( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->dma.flush)
|
||||
rmesa->dma.flush( rmesa );
|
||||
|
||||
if (!is_empty_list(&rmesa->hw.dirty))
|
||||
r200EmitState( rmesa );
|
||||
|
||||
if (rmesa->store.cmd_used)
|
||||
r200FlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
}
|
||||
|
||||
/* Make sure all commands have been sent to the hardware and have
|
||||
* completed processing.
|
||||
*/
|
||||
void r200Finish( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200Flush( ctx );
|
||||
|
||||
if (rmesa->do_irqs) {
|
||||
LOCK_HARDWARE( rmesa );
|
||||
r200EmitIrqLocked( rmesa );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
r200WaitIrq( rmesa );
|
||||
}
|
||||
else
|
||||
r200WaitForIdle( rmesa );
|
||||
}
|
||||
|
||||
|
||||
/* This version of AllocateMemoryNV allocates only agp memory, and
|
||||
* only does so after the point at which the driver has been
|
||||
* initialized.
|
||||
*
|
||||
* Theoretically a valid context isn't required. However, in this
|
||||
* implementation, it is, as I'm using the hardware lock to protect
|
||||
* the kernel data structures, and the current context to get the
|
||||
* device fd.
|
||||
*/
|
||||
void *r200AllocateMemoryNV(GLsizei size, GLfloat readfreq,
|
||||
GLfloat writefreq, GLfloat priority)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa;
|
||||
int region_offset;
|
||||
drmRadeonMemAlloc alloc;
|
||||
int ret;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,
|
||||
writefreq, priority);
|
||||
|
||||
if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI )
|
||||
return NULL;
|
||||
|
||||
if (getenv("R200_NO_ALLOC"))
|
||||
return NULL;
|
||||
|
||||
if (rmesa->dri.drmMinor < 6)
|
||||
return NULL;
|
||||
|
||||
alloc.region = RADEON_MEM_REGION_AGP;
|
||||
alloc.alignment = 0;
|
||||
alloc.size = size;
|
||||
alloc.region_offset = ®ion_offset;
|
||||
|
||||
ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd,
|
||||
DRM_RADEON_ALLOC,
|
||||
&alloc, sizeof(alloc));
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
char *region_start = (char *)rmesa->r200Screen->agpTextures.map;
|
||||
return (void *)(region_start + region_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Called via glXFreeMemoryNV() */
|
||||
void r200FreeMemoryNV(GLvoid *pointer)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa;
|
||||
int region_offset;
|
||||
drmRadeonMemFree memfree;
|
||||
int ret;
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);
|
||||
|
||||
if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI ) {
|
||||
fprintf(stderr, "%s: no context\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rmesa->dri.drmMinor < 6)
|
||||
return;
|
||||
|
||||
region_offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map;
|
||||
|
||||
if (region_offset < 0 ||
|
||||
region_offset > rmesa->r200Screen->agpTextures.size) {
|
||||
fprintf(stderr, "offset %d outside range 0..%d\n", region_offset,
|
||||
rmesa->r200Screen->agpTextures.size);
|
||||
return;
|
||||
}
|
||||
|
||||
memfree.region = RADEON_MEM_REGION_AGP;
|
||||
memfree.region_offset = region_offset;
|
||||
|
||||
ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd,
|
||||
DRM_RADEON_FREE,
|
||||
&memfree, sizeof(memfree));
|
||||
|
||||
if (ret)
|
||||
fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret);
|
||||
}
|
||||
|
||||
/* Called via glXGetAGPOffsetMESA() */
|
||||
GLuint r200GetAGPOffset(const GLvoid *pointer)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa;
|
||||
GLuint card_offset;
|
||||
|
||||
if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) {
|
||||
fprintf(stderr, "%s: no context\n", __FUNCTION__);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
if (!r200IsAgpMemory( rmesa, pointer, 0 ))
|
||||
return ~0;
|
||||
|
||||
if (rmesa->dri.drmMinor < 6)
|
||||
return ~0;
|
||||
|
||||
card_offset = r200AgpOffsetFromVirtual( rmesa, pointer );
|
||||
|
||||
return card_offset - rmesa->r200Screen->agp_base;
|
||||
}
|
||||
|
||||
|
||||
GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer,
|
||||
GLint size )
|
||||
{
|
||||
int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map;
|
||||
int valid = (size >= 0 &&
|
||||
offset >= 0 &&
|
||||
offset + size < rmesa->r200Screen->agpTextures.size);
|
||||
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "r200IsAgpMemory( %p ) : %d\n", pointer, valid );
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer )
|
||||
{
|
||||
int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map;
|
||||
|
||||
if (offset < 0 || offset > rmesa->r200Screen->agpTextures.size)
|
||||
return ~0;
|
||||
else
|
||||
return rmesa->r200Screen->agp_texture_offset + offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void r200InitIoctlFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.Clear = r200Clear;
|
||||
ctx->Driver.Finish = r200Finish;
|
||||
ctx->Driver.Flush = r200Flush;
|
||||
}
|
||||
|
||||
188
src/mesa/drivers/dri/r200/r200_ioctl.h
Normal file
188
src/mesa/drivers/dri/r200/r200_ioctl.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_IOCTL_H__
|
||||
#define __R200_IOCTL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "simple_list.h"
|
||||
#include "radeon_dri.h"
|
||||
#include "r200_lock.h"
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "radeon_common.h"
|
||||
|
||||
extern void r200EmitState( r200ContextPtr rmesa );
|
||||
extern void r200EmitVertexAOS( r200ContextPtr rmesa,
|
||||
GLuint vertex_size,
|
||||
GLuint offset );
|
||||
|
||||
extern void r200EmitVbufPrim( r200ContextPtr rmesa,
|
||||
GLuint primitive,
|
||||
GLuint vertex_nr );
|
||||
|
||||
extern void r200FlushElts( r200ContextPtr rmesa );
|
||||
|
||||
extern GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
|
||||
GLuint primitive,
|
||||
GLuint min_nr );
|
||||
|
||||
extern void r200EmitAOS( r200ContextPtr rmesa,
|
||||
struct r200_dma_region **regions,
|
||||
GLuint n,
|
||||
GLuint offset );
|
||||
|
||||
extern void r200EmitBlit( r200ContextPtr rmesa,
|
||||
GLuint color_fmt,
|
||||
GLuint src_pitch,
|
||||
GLuint src_offset,
|
||||
GLuint dst_pitch,
|
||||
GLuint dst_offset,
|
||||
GLint srcx, GLint srcy,
|
||||
GLint dstx, GLint dsty,
|
||||
GLuint w, GLuint h );
|
||||
|
||||
extern void r200EmitWait( r200ContextPtr rmesa, GLuint flags );
|
||||
|
||||
extern void r200FlushCmdBuf( r200ContextPtr rmesa, const char * );
|
||||
extern int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller );
|
||||
|
||||
extern void r200RefillCurrentDmaRegion( r200ContextPtr rmesa );
|
||||
|
||||
extern void r200AllocDmaRegion( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int bytes,
|
||||
int alignment );
|
||||
|
||||
extern void r200AllocDmaRegionVerts( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int numverts,
|
||||
int vertsize,
|
||||
int alignment );
|
||||
|
||||
extern void r200ReleaseDmaRegion( r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
const char *caller );
|
||||
|
||||
extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable );
|
||||
extern void r200PageFlip( const __DRIdrawablePrivate *drawable );
|
||||
extern void r200Flush( GLcontext *ctx );
|
||||
extern void r200Finish( GLcontext *ctx );
|
||||
extern void r200WaitForIdleLocked( r200ContextPtr rmesa );
|
||||
extern void r200WaitForVBlank( r200ContextPtr rmesa );
|
||||
extern void r200InitIoctlFuncs( GLcontext *ctx );
|
||||
|
||||
extern void *r200AllocateMemoryNV( GLsizei size, GLfloat readfreq,
|
||||
GLfloat writefreq, GLfloat priority );
|
||||
extern void r200FreeMemoryNV( GLvoid *pointer );
|
||||
extern GLuint r200GetAGPOffset( const GLvoid *pointer );
|
||||
extern GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer,
|
||||
GLint size );
|
||||
|
||||
extern GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa,
|
||||
const GLvoid *pointer );
|
||||
|
||||
/* ================================================================
|
||||
* Helper macros:
|
||||
*/
|
||||
|
||||
/* Close off the last primitive, if it exists.
|
||||
*/
|
||||
#define R200_NEWPRIM( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->dma.flush ) \
|
||||
rmesa->dma.flush( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
/* Can accomodate several state changes and primitive changes without
|
||||
* actually firing the buffer.
|
||||
*/
|
||||
#define R200_STATECHANGE( rmesa, ATOM ) \
|
||||
do { \
|
||||
R200_NEWPRIM( rmesa ); \
|
||||
move_to_head( &(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \
|
||||
} while (0)
|
||||
|
||||
#define R200_DB_STATE( ATOM ) \
|
||||
memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
|
||||
rmesa->hw.ATOM.cmd_size * 4)
|
||||
|
||||
static __inline int R200_DB_STATECHANGE(
|
||||
r200ContextPtr rmesa,
|
||||
struct r200_state_atom *atom )
|
||||
{
|
||||
if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) {
|
||||
int *tmp;
|
||||
R200_NEWPRIM( rmesa );
|
||||
move_to_head( &(rmesa->hw.dirty), atom );
|
||||
tmp = atom->cmd;
|
||||
atom->cmd = atom->lastcmd;
|
||||
atom->lastcmd = tmp;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Fire the buffered vertices no matter what.
|
||||
*/
|
||||
#define R200_FIREVERTICES( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \
|
||||
r200Flush( rmesa->glCtx ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Alloc space in the command buffer
|
||||
*/
|
||||
static __inline char *r200AllocCmdBuf( r200ContextPtr rmesa,
|
||||
int bytes, const char *where )
|
||||
{
|
||||
if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
|
||||
r200FlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
|
||||
{
|
||||
char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
|
||||
rmesa->store.cmd_used += bytes;
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __R200_IOCTL_H__ */
|
||||
118
src/mesa/drivers/dri/r200/r200_lock.c
Normal file
118
src/mesa/drivers/dri/r200/r200_lock.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_lock.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
|
||||
#if DEBUG_LOCKING
|
||||
char *prevLockFile = NULL;
|
||||
int prevLockLine = 0;
|
||||
#endif
|
||||
|
||||
/* Turn on/off page flipping according to the flags in the sarea:
|
||||
*/
|
||||
static void
|
||||
r200UpdatePageFlipping( r200ContextPtr rmesa )
|
||||
{
|
||||
int use_back;
|
||||
rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip;
|
||||
|
||||
use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT);
|
||||
use_back ^= (rmesa->sarea->pfCurrentPage == 1);
|
||||
|
||||
if (use_back) {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch;
|
||||
} else {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch;
|
||||
}
|
||||
|
||||
R200_STATECHANGE( rmesa, ctx );
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the hardware state. This is called if another context has
|
||||
* grabbed the hardware lock, which includes the X server. This
|
||||
* function also updates the driver's window state after the X server
|
||||
* moves, resizes or restacks a window -- the change will be reflected
|
||||
* in the drawable position and clip rects. Since the X server grabs
|
||||
* the hardware lock when it changes the window state, this routine will
|
||||
* automatically be called after such a change.
|
||||
*/
|
||||
void r200GetLock( r200ContextPtr rmesa, GLuint flags )
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
int i;
|
||||
|
||||
drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
|
||||
|
||||
/* The window might have moved, so we might need to get new clip
|
||||
* rects.
|
||||
*
|
||||
* NOTE: This releases and regrabs the hw lock to allow the X server
|
||||
* to respond to the DRI protocol request for new drawable info.
|
||||
* Since the hardware state depends on having the latest drawable
|
||||
* clip rects, all state checking must be done _after_ this call.
|
||||
*/
|
||||
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
|
||||
|
||||
if ( rmesa->lastStamp != dPriv->lastStamp ) {
|
||||
r200UpdatePageFlipping( rmesa );
|
||||
if (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT)
|
||||
r200SetCliprects( rmesa, GL_BACK_LEFT );
|
||||
else
|
||||
r200SetCliprects( rmesa, GL_FRONT_LEFT );
|
||||
r200UpdateViewportOffset( rmesa->glCtx );
|
||||
rmesa->lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
if ( sarea->ctxOwner != rmesa->dri.hwContext ) {
|
||||
sarea->ctxOwner = rmesa->dri.hwContext;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) {
|
||||
if ( sarea->texAge[i] != rmesa->texture.age[i] ) {
|
||||
r200AgeTextures( rmesa, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
111
src/mesa/drivers/dri/r200/r200_lock.h
Normal file
111
src/mesa/drivers/dri/r200/r200_lock.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_LOCK_H__
|
||||
#define __R200_LOCK_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r200GetLock( r200ContextPtr rmesa, GLuint flags );
|
||||
|
||||
/* Turn DEBUG_LOCKING on to find locking conflicts.
|
||||
*/
|
||||
#define DEBUG_LOCKING 0
|
||||
|
||||
#if DEBUG_LOCKING
|
||||
extern char *prevLockFile;
|
||||
extern int prevLockLine;
|
||||
|
||||
#define DEBUG_LOCK() \
|
||||
do { \
|
||||
prevLockFile = (__FILE__); \
|
||||
prevLockLine = (__LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_RESET() \
|
||||
do { \
|
||||
prevLockFile = 0; \
|
||||
prevLockLine = 0; \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_CHECK_LOCK() \
|
||||
do { \
|
||||
if ( prevLockFile ) { \
|
||||
fprintf( stderr, \
|
||||
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
|
||||
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
|
||||
exit( 1 ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG_LOCK()
|
||||
#define DEBUG_RESET()
|
||||
#define DEBUG_CHECK_LOCK()
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !!! We may want to separate locks from locks with validation. This
|
||||
* could be used to improve performance for those things commands that
|
||||
* do not do any drawing !!!
|
||||
*/
|
||||
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
#define LOCK_HARDWARE( rmesa ) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DEBUG_CHECK_LOCK(); \
|
||||
DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \
|
||||
(DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \
|
||||
if ( __ret ) \
|
||||
r200GetLock( rmesa, 0 ); \
|
||||
DEBUG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
/* Unlock the hardware.
|
||||
*/
|
||||
#define UNLOCK_HARDWARE( rmesa ) \
|
||||
do { \
|
||||
DRM_UNLOCK( rmesa->dri.fd, \
|
||||
rmesa->dri.hwLock, \
|
||||
rmesa->dri.hwContext ); \
|
||||
DEBUG_RESET(); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif /* __R200_LOCK_H__ */
|
||||
12
src/mesa/drivers/dri/r200/r200_maos.c
Normal file
12
src/mesa/drivers/dri/r200/r200_maos.c
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
/* If using new packets, can choose either verts or arrays.
|
||||
* Otherwise, must use verts.
|
||||
*/
|
||||
#include "r200_context.h"
|
||||
#define R200_MAOS_VERTS 0
|
||||
#if (R200_MAOS_VERTS) || (R200_OLD_PACKETS)
|
||||
#include "r200_maos_verts.c"
|
||||
#else
|
||||
#include "r200_maos_arrays.c"
|
||||
#endif
|
||||
46
src/mesa/drivers/dri/r200/r200_maos.h
Normal file
46
src/mesa/drivers/dri/r200/r200_maos.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_MAOS_H__
|
||||
#define __R200_MAOS_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200EmitArrays( GLcontext *ctx, GLuint inputs );
|
||||
extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
481
src/mesa/drivers/dri/r200/r200_maos_arrays.c
Normal file
481
src/mesa/drivers/dri/r200/r200_maos_arrays.c
Normal file
@@ -0,0 +1,481 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "math/m_translate.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_imm_debug.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_maos.h"
|
||||
|
||||
/* Usage:
|
||||
* - from r200_tcl_render
|
||||
* - call r200EmitArrays to ensure uptodate arrays in dma
|
||||
* - emit primitives (new type?) which reference the data
|
||||
* -- need to use elts for lineloop, quads, quadstrip/flat
|
||||
* -- other primitives are all well-formed (need tristrip-1,fake-poly)
|
||||
*
|
||||
*/
|
||||
static void emit_ubyte_rgba3( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d out %p\n",
|
||||
__FUNCTION__, count, stride, out);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
out->red = *data;
|
||||
out->green = *(data+1);
|
||||
out->blue = *(data+2);
|
||||
out->alpha = 0xFF;
|
||||
out++;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
#define COPY_DWORDS( dst, src, nr ) \
|
||||
do { \
|
||||
int __tmp; \
|
||||
__asm__ __volatile__( "rep ; movsl" \
|
||||
: "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
|
||||
: "0" (nr), \
|
||||
"D" ((long)dst), \
|
||||
"S" ((long)src) ); \
|
||||
} while (0)
|
||||
#else
|
||||
#define COPY_DWORDS( dst, src, nr ) \
|
||||
do { \
|
||||
int j; \
|
||||
for ( j = 0 ; j < nr ; j++ ) \
|
||||
dst[j] = ((int *)src)[j]; \
|
||||
dst += nr; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void emit_ubyte_rgba4( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 4) {
|
||||
for (i = 0; i < count; i++)
|
||||
((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
|
||||
} else {
|
||||
for (i = 0; i < count; i++) {
|
||||
*(int *)out++ = LE32_TO_CPU(*(int *)data);
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void emit_ubyte_rgba( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
if (stride == 0) {
|
||||
r200AllocDmaRegion( rmesa, rvb, 4, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
else {
|
||||
r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 1;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 3:
|
||||
emit_ubyte_rgba3( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_ubyte_rgba4( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void emit_vec8( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 8)
|
||||
COPY_DWORDS( out, data, count*2 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out += 2;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_vec12( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
|
||||
__FUNCTION__, count, stride, out, data);
|
||||
|
||||
if (stride == 12)
|
||||
COPY_DWORDS( out, data, count*3 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out[2] = *(int *)(data+8);
|
||||
out += 3;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_vec16( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 16)
|
||||
COPY_DWORDS( out, data, count*4 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out[2] = *(int *)(data+8);
|
||||
out[3] = *(int *)(data+12);
|
||||
out += 4;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void emit_vector( GLcontext *ctx,
|
||||
struct r200_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d size %d stride %d\n",
|
||||
__FUNCTION__, count, size, stride);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
if (stride == 0) {
|
||||
r200AllocDmaRegion( rmesa, rvb, size * 4, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = size;
|
||||
}
|
||||
else {
|
||||
r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = size;
|
||||
rvb->aos_size = size;
|
||||
}
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 2:
|
||||
emit_vec8( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 3:
|
||||
emit_vec12( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_vec16( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Emit any changed arrays to new agp memory, re-emit a packet to
|
||||
* update the arrays.
|
||||
*/
|
||||
void r200EmitArrays( GLcontext *ctx, GLuint inputs )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
|
||||
struct r200_dma_region **component = rmesa->tcl.aos_components;
|
||||
GLuint nr = 0;
|
||||
GLuint vfmt0 = 0, vfmt1 = 0;
|
||||
GLuint count = VB->Count;
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, inputs );
|
||||
|
||||
if (1) {
|
||||
if (!rmesa->tcl.obj.buf)
|
||||
emit_vector( ctx,
|
||||
&rmesa->tcl.obj,
|
||||
(char *)VB->ObjPtr->data,
|
||||
VB->ObjPtr->size,
|
||||
VB->ObjPtr->stride,
|
||||
count);
|
||||
|
||||
switch( VB->ObjPtr->size ) {
|
||||
case 4: vfmt0 |= R200_VTX_W0;
|
||||
case 3: vfmt0 |= R200_VTX_Z0;
|
||||
case 2:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
component[nr++] = &rmesa->tcl.obj;
|
||||
}
|
||||
|
||||
|
||||
if (inputs & VERT_BIT_NORMAL) {
|
||||
if (!rmesa->tcl.norm.buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.norm),
|
||||
(char *)VB->NormalPtr->data,
|
||||
3,
|
||||
VB->NormalPtr->stride,
|
||||
count);
|
||||
|
||||
vfmt0 |= R200_VTX_N0;
|
||||
component[nr++] = &rmesa->tcl.norm;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR0) {
|
||||
if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
|
||||
if (!rmesa->tcl.rgba.buf)
|
||||
emit_ubyte_rgba( ctx,
|
||||
&rmesa->tcl.rgba,
|
||||
(char *)VB->ColorPtr[0]->Ptr,
|
||||
VB->ColorPtr[0]->Size,
|
||||
VB->ColorPtr[0]->StrideB,
|
||||
count);
|
||||
|
||||
vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
|
||||
}
|
||||
else {
|
||||
int emitsize;
|
||||
|
||||
if (VB->ColorPtr[0]->Size == 4 &&
|
||||
(VB->ColorPtr[0]->StrideB != 0 ||
|
||||
((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) {
|
||||
vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
|
||||
emitsize = 4;
|
||||
}
|
||||
else {
|
||||
vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT;
|
||||
emitsize = 3;
|
||||
}
|
||||
|
||||
if (!rmesa->tcl.rgba.buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.rgba),
|
||||
(char *)VB->ColorPtr[0]->Ptr,
|
||||
emitsize,
|
||||
VB->ColorPtr[0]->StrideB,
|
||||
count);
|
||||
}
|
||||
|
||||
component[nr++] = &rmesa->tcl.rgba;
|
||||
}
|
||||
|
||||
|
||||
if (inputs & VERT_BIT_COLOR1) {
|
||||
if (!rmesa->tcl.spec.buf) {
|
||||
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
|
||||
r200_import_float_spec_colors( ctx );
|
||||
|
||||
emit_ubyte_rgba( ctx,
|
||||
&rmesa->tcl.spec,
|
||||
(char *)VB->SecondaryColorPtr[0]->Ptr,
|
||||
3,
|
||||
VB->SecondaryColorPtr[0]->StrideB,
|
||||
count);
|
||||
}
|
||||
|
||||
/* How does this work?
|
||||
*/
|
||||
vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT;
|
||||
component[nr++] = &rmesa->tcl.spec;
|
||||
}
|
||||
|
||||
/* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */
|
||||
/* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */
|
||||
|
||||
if (inputs & VERT_BIT_TEX0) {
|
||||
if (!rmesa->tcl.tex[0].buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.tex[0]),
|
||||
(char *)VB->TexCoordPtr[0]->data,
|
||||
VB->TexCoordPtr[0]->size,
|
||||
VB->TexCoordPtr[0]->stride,
|
||||
count );
|
||||
|
||||
vfmt1 |= VB->TexCoordPtr[0]->size << R200_VTX_TEX0_COMP_CNT_SHIFT;
|
||||
component[nr++] = &rmesa->tcl.tex[0];
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX1) {
|
||||
if (!rmesa->tcl.tex[1].buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.tex[1]),
|
||||
(char *)VB->TexCoordPtr[1]->data,
|
||||
VB->TexCoordPtr[1]->size,
|
||||
VB->TexCoordPtr[1]->stride,
|
||||
count );
|
||||
|
||||
vfmt1 |= VB->TexCoordPtr[1]->size << R200_VTX_TEX1_COMP_CNT_SHIFT;
|
||||
component[nr++] = &rmesa->tcl.tex[1];
|
||||
}
|
||||
|
||||
if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
|
||||
vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
|
||||
R200_STATECHANGE( rmesa, vtx );
|
||||
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
|
||||
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
|
||||
}
|
||||
|
||||
|
||||
/* fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */
|
||||
|
||||
rmesa->tcl.nr_aos_components = nr;
|
||||
rmesa->tcl.vertex_format = vfmt0;
|
||||
}
|
||||
|
||||
|
||||
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, newinputs );
|
||||
|
||||
if (newinputs & VERT_BIT_POS)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_NORMAL)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_COLOR0)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_COLOR1)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_TEX0)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_TEX1)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
|
||||
}
|
||||
378
src/mesa/drivers/dri/r200/r200_maos_vbtmp.h
Normal file
378
src/mesa/drivers/dri/r200/r200_maos_vbtmp.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef LOCALVARS
|
||||
#define LOCALVARS
|
||||
#endif
|
||||
|
||||
#undef TCL_DEBUG
|
||||
#ifndef TCL_DEBUG
|
||||
#define TCL_DEBUG 0
|
||||
#endif
|
||||
|
||||
static void TAG(emit)( GLcontext *ctx,
|
||||
GLuint start, GLuint end,
|
||||
void *dest )
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLuint (*tc0)[4], (*tc1)[4];
|
||||
GLfloat *fog;
|
||||
GLuint (*tc2)[4], (*norm)[3];
|
||||
GLubyte (*col)[4], (*spec)[4];
|
||||
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
|
||||
GLuint tc2_stride, norm_stride;
|
||||
GLuint (*coord)[4];
|
||||
GLuint coord_stride;
|
||||
GLubyte dummy[4];
|
||||
int i;
|
||||
|
||||
union emit_union *v = (union emit_union *)dest;
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* The vertex code expects Obj to be clean to element 3. To fix
|
||||
* this, add more vertex code (for obj-2, obj-3) or preferably move
|
||||
* to maos.
|
||||
*/
|
||||
if (VB->ObjPtr->size < 3) {
|
||||
if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 2 );
|
||||
}
|
||||
|
||||
if (DO_W && VB->ObjPtr->size < 4) {
|
||||
if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 3 );
|
||||
}
|
||||
|
||||
coord = (GLuint (*)[4])VB->ObjPtr->data;
|
||||
coord_stride = VB->ObjPtr->stride;
|
||||
|
||||
if (DO_TEX2) {
|
||||
const GLuint t2 = GET_TEXSOURCE(2);
|
||||
tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data;
|
||||
tc2_stride = VB->TexCoordPtr[t2]->stride;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) {
|
||||
if (VB->TexCoordPtr[t2]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_TEX2, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t2], VB->Count, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TEX1) {
|
||||
if (VB->TexCoordPtr[1]) {
|
||||
const GLuint t1 = GET_TEXSOURCE(1);
|
||||
tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data;
|
||||
tc1_stride = VB->TexCoordPtr[t1]->stride;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) {
|
||||
if (VB->TexCoordPtr[t1]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_TEX1, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t1], VB->Count, 3 );
|
||||
}
|
||||
} else {
|
||||
tc1 = (GLuint (*)[4])&ctx->Current.Texcoord[1]; /* could be anything, really */
|
||||
tc1_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TEX0) {
|
||||
if (VB->TexCoordPtr[0]) {
|
||||
const GLuint t0 = GET_TEXSOURCE(0);
|
||||
tc0_stride = VB->TexCoordPtr[t0]->stride;
|
||||
tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) {
|
||||
if (VB->TexCoordPtr[t0]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_TEX0, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t0], VB->Count, 3 );
|
||||
}
|
||||
} else {
|
||||
tc0 = (GLuint (*)[4])&ctx->Current.Texcoord[0]; /* could be anything, really */
|
||||
tc0_stride = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DO_NORM) {
|
||||
if (VB->NormalPtr) {
|
||||
norm_stride = VB->NormalPtr->stride;
|
||||
norm = (GLuint (*)[3])VB->NormalPtr->data;
|
||||
} else {
|
||||
norm_stride = 0;
|
||||
norm = (GLuint (*)[3])&ctx->Current.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_RGBA) {
|
||||
if (VB->ColorPtr[0]) {
|
||||
/* This is incorrect when colormaterial is enabled:
|
||||
*/
|
||||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) {
|
||||
if (0) fprintf(stderr, "IMPORTING FLOAT COLORS\n");
|
||||
IMPORT_FLOAT_COLORS( ctx );
|
||||
}
|
||||
col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr;
|
||||
col_stride = VB->ColorPtr[0]->StrideB;
|
||||
} else {
|
||||
col = &dummy; /* any old memory is fine */
|
||||
col_stride = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DO_SPEC) {
|
||||
if (VB->SecondaryColorPtr[0]) {
|
||||
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
|
||||
IMPORT_FLOAT_SPEC_COLORS( ctx );
|
||||
spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr;
|
||||
spec_stride = VB->SecondaryColorPtr[0]->StrideB;
|
||||
} else {
|
||||
spec = &dummy;
|
||||
spec_stride = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DO_FOG) {
|
||||
if (VB->FogCoordPtr) {
|
||||
fog = VB->FogCoordPtr->data;
|
||||
fog_stride = VB->FogCoordPtr->stride;
|
||||
} else {
|
||||
fog = (GLfloat *)&dummy; *fog = 0;
|
||||
fog_stride = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (VB->importable_data) {
|
||||
if (start) {
|
||||
coord = (GLuint (*)[4])((GLubyte *)coord + start * coord_stride);
|
||||
if (DO_TEX0)
|
||||
tc0 = (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride);
|
||||
if (DO_TEX1)
|
||||
tc1 = (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride);
|
||||
if (DO_TEX2)
|
||||
tc2 = (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride);
|
||||
if (DO_NORM)
|
||||
norm = (GLuint (*)[3])((GLubyte *)norm + start * norm_stride);
|
||||
if (DO_RGBA)
|
||||
STRIDE_4UB(col, start * col_stride);
|
||||
if (DO_SPEC)
|
||||
STRIDE_4UB(spec, start * spec_stride);
|
||||
if (DO_FOG)
|
||||
STRIDE_F(fog, start * fog_stride);
|
||||
}
|
||||
|
||||
for (i=start; i < end; i++) {
|
||||
v[0].ui = coord[0][0];
|
||||
v[1].ui = coord[0][1];
|
||||
v[2].ui = coord[0][2];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%d: %.2f %.2f %.2f ", i, v[0].f, v[1].f, v[2].f);
|
||||
if (DO_W) {
|
||||
v[3].ui = coord[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[3].f);
|
||||
v += 4;
|
||||
}
|
||||
else
|
||||
v += 3;
|
||||
coord = (GLuint (*)[4])((GLubyte *)coord + coord_stride);
|
||||
|
||||
if (DO_NORM) {
|
||||
v[0].ui = norm[0][0];
|
||||
v[1].ui = norm[0][1];
|
||||
v[2].ui = norm[0][2];
|
||||
if (TCL_DEBUG) fprintf(stderr, "norm: %.2f %.2f %.2f ", v[0].f, v[1].f, v[2].f);
|
||||
v += 3;
|
||||
norm = (GLuint (*)[3])((GLubyte *)norm + norm_stride);
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
v[0].ui = LE32_TO_CPU(*(GLuint *)&col[0]);
|
||||
STRIDE_4UB(col, col_stride);
|
||||
if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
|
||||
v++;
|
||||
}
|
||||
if (DO_SPEC || DO_FOG) {
|
||||
if (DO_SPEC) {
|
||||
v[0].ub[0] = spec[0][0];
|
||||
v[0].ub[1] = spec[0][1];
|
||||
v[0].ub[2] = spec[0][2];
|
||||
STRIDE_4UB(spec, spec_stride);
|
||||
}
|
||||
if (DO_FOG) {
|
||||
v[0].ub[3] = fog[0] * 255.0;
|
||||
STRIDE_F(fog, fog_stride);
|
||||
}
|
||||
if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
|
||||
v++;
|
||||
}
|
||||
if (DO_TEX0) {
|
||||
v[0].ui = tc0[0][0];
|
||||
v[1].ui = tc0[0][1];
|
||||
if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f);
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc0[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc0 = (GLuint (*)[4])((GLubyte *)tc0 + tc0_stride);
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
v[0].ui = tc1[0][0];
|
||||
v[1].ui = tc1[0][1];
|
||||
if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f);
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc1[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc1 = (GLuint (*)[4])((GLubyte *)tc1 + tc1_stride);
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
v[0].ui = tc2[0][0];
|
||||
v[1].ui = tc2[0][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc2[0][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc2 = (GLuint (*)[4])((GLubyte *)tc2 + tc2_stride);
|
||||
}
|
||||
if (TCL_DEBUG) fprintf(stderr, "\n");
|
||||
}
|
||||
} else {
|
||||
for (i=start; i < end; i++) {
|
||||
v[0].ui = coord[i][0];
|
||||
v[1].ui = coord[i][1];
|
||||
v[2].ui = coord[i][2];
|
||||
if (DO_W) {
|
||||
v[3].ui = coord[i][3];
|
||||
v += 4;
|
||||
}
|
||||
else
|
||||
v += 3;
|
||||
|
||||
if (DO_NORM) {
|
||||
v[0].ui = norm[i][0];
|
||||
v[1].ui = norm[i][1];
|
||||
v[2].ui = norm[i][2];
|
||||
v += 3;
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
v[0].ui = LE32_TO_CPU(*(GLuint *)&col[i]);
|
||||
v++;
|
||||
}
|
||||
if (DO_SPEC || DO_FOG) {
|
||||
if (DO_SPEC) {
|
||||
v[0].ub[0] = spec[i][0];
|
||||
v[0].ub[1] = spec[i][1];
|
||||
v[0].ub[2] = spec[i][2];
|
||||
}
|
||||
if (DO_FOG) {
|
||||
v[0].ub[3] = fog[i] * 255.0;
|
||||
}
|
||||
v++;
|
||||
}
|
||||
if (DO_TEX0) {
|
||||
v[0].ui = tc0[i][0];
|
||||
v[1].ui = tc0[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc0[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
v[0].ui = tc1[i][0];
|
||||
v[1].ui = tc1[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc1[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
v[0].ui = tc2[i][0];
|
||||
v[1].ui = tc2[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc2[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void TAG(init)( void )
|
||||
{
|
||||
int sz = 3;
|
||||
if (DO_W) sz++;
|
||||
if (DO_NORM) sz += 3;
|
||||
if (DO_RGBA) sz++;
|
||||
if (DO_SPEC || DO_FOG) sz++;
|
||||
if (DO_TEX0) sz += 2;
|
||||
if (DO_TEX0 && DO_PTEX) sz++;
|
||||
if (DO_TEX1) sz += 2;
|
||||
if (DO_TEX1 && DO_PTEX) sz++;
|
||||
if (DO_TEX2) sz += 2;
|
||||
if (DO_TEX2 && DO_PTEX) sz++;
|
||||
|
||||
setup_tab[IDX].emit = TAG(emit);
|
||||
setup_tab[IDX].vertex_format = IND;
|
||||
setup_tab[IDX].vertex_size = sz;
|
||||
}
|
||||
|
||||
|
||||
#undef IND
|
||||
#undef TAG
|
||||
#undef IDX
|
||||
338
src/mesa/drivers/dri/r200/r200_maos_verts.c
Normal file
338
src/mesa/drivers/dri/r200/r200_maos_verts.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "mtypes.h"
|
||||
#include "enums.h"
|
||||
#include "colormac.h"
|
||||
#include "light.h"
|
||||
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "tnl/t_imm_debug.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_maos.h"
|
||||
|
||||
|
||||
#define R200_TCL_MAX_SETUP 13
|
||||
|
||||
union emit_union { float f; GLuint ui; GLubyte ub[4]; };
|
||||
|
||||
static struct {
|
||||
void (*emit)( GLcontext *, GLuint, GLuint, void * );
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_format;
|
||||
} setup_tab[R200_TCL_MAX_SETUP];
|
||||
|
||||
#define DO_W (IND & R200_CP_VC_FRMT_W0)
|
||||
#define DO_RGBA (IND & R200_CP_VC_FRMT_PKCOLOR)
|
||||
#define DO_SPEC (IND & R200_CP_VC_FRMT_PKSPEC)
|
||||
#define DO_FOG (IND & R200_CP_VC_FRMT_PKSPEC)
|
||||
#define DO_TEX0 (IND & R200_CP_VC_FRMT_ST0)
|
||||
#define DO_TEX1 (IND & R200_CP_VC_FRMT_ST1)
|
||||
#define DO_PTEX (IND & R200_CP_VC_FRMT_Q0)
|
||||
#define DO_NORM (IND & R200_CP_VC_FRMT_N0)
|
||||
|
||||
#define DO_TEX2 0
|
||||
#define DO_TEX3 0
|
||||
|
||||
#define GET_TEXSOURCE(n) n
|
||||
#define GET_UBYTE_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteColor
|
||||
#define GET_UBYTE_SPEC_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteSecondaryColor
|
||||
|
||||
#define IMPORT_FLOAT_COLORS r200_import_float_colors
|
||||
#define IMPORT_FLOAT_SPEC_COLORS r200_import_float_spec_colors
|
||||
|
||||
/***********************************************************************
|
||||
* Generate vertex emit functions *
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/* Defined in order of increasing vertex size:
|
||||
*/
|
||||
#define IDX 0
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR)
|
||||
#define TAG(x) x##_rgba
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 1
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 2
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_ST0)
|
||||
#define TAG(x) x##_rgba_st
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 3
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgba_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 4
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_st_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 5
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_ST1)
|
||||
#define TAG(x) x##_rgba_st_st
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 6
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgba_st_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 7
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_PKSPEC| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_ST1)
|
||||
#define TAG(x) x##_rgba_spec_st_st
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 8
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_ST1| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_st_st_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 9
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_PKSPEC| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_ST1| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgpa_spec_st_st_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 10
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_Q0)
|
||||
#define TAG(x) x##_rgba_stq
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 11
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_ST1| \
|
||||
R200_CP_VC_FRMT_Q1| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_Q0)
|
||||
#define TAG(x) x##_rgba_stq_stq
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
#define IDX 12
|
||||
#define IND (R200_CP_VC_FRMT_XY| \
|
||||
R200_CP_VC_FRMT_Z| \
|
||||
R200_CP_VC_FRMT_W0| \
|
||||
R200_CP_VC_FRMT_PKCOLOR| \
|
||||
R200_CP_VC_FRMT_PKSPEC| \
|
||||
R200_CP_VC_FRMT_ST0| \
|
||||
R200_CP_VC_FRMT_Q0| \
|
||||
R200_CP_VC_FRMT_ST1| \
|
||||
R200_CP_VC_FRMT_Q1| \
|
||||
R200_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_w_rgpa_spec_stq_stq_n
|
||||
#include "r200_maos_vbtmp.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialization
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
static void init_tcl_verts( void )
|
||||
{
|
||||
init_rgba();
|
||||
init_n();
|
||||
init_rgba_n();
|
||||
init_rgba_st();
|
||||
init_st_n();
|
||||
init_rgba_st_st();
|
||||
init_rgba_st_n();
|
||||
init_rgba_spec_st_st();
|
||||
init_st_st_n();
|
||||
init_rgpa_spec_st_st_n();
|
||||
init_rgba_stq();
|
||||
init_rgba_stq_stq();
|
||||
init_w_rgpa_spec_stq_stq_n();
|
||||
}
|
||||
|
||||
|
||||
void r200EmitArrays( GLcontext *ctx, GLuint inputs )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLuint req = 0;
|
||||
GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
|
||||
~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1));
|
||||
int i;
|
||||
static int firsttime = 1;
|
||||
|
||||
if (firsttime) {
|
||||
init_tcl_verts();
|
||||
firsttime = 0;
|
||||
}
|
||||
|
||||
if (1) {
|
||||
req |= R200_CP_VC_FRMT_Z;
|
||||
if (VB->ObjPtr->size == 4) {
|
||||
req |= R200_CP_VC_FRMT_W0;
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_NORMAL) {
|
||||
req |= R200_CP_VC_FRMT_N0;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR0) {
|
||||
req |= R200_CP_VC_FRMT_PKCOLOR;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR1) {
|
||||
req |= R200_CP_VC_FRMT_PKSPEC;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX0) {
|
||||
req |= R200_CP_VC_FRMT_ST0;
|
||||
|
||||
if (VB->TexCoordPtr[0]->size == 4) {
|
||||
req |= R200_CP_VC_FRMT_Q0;
|
||||
vtx |= R200_TCL_VTX_Q0;
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX1) {
|
||||
req |= R200_CP_VC_FRMT_ST1;
|
||||
|
||||
if (VB->TexCoordPtr[1]->size == 4) {
|
||||
req |= R200_CP_VC_FRMT_Q1;
|
||||
vtx |= R200_TCL_VTX_Q1;
|
||||
}
|
||||
}
|
||||
|
||||
if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
|
||||
R200_STATECHANGE( rmesa, tcl );
|
||||
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < R200_TCL_MAX_SETUP ; i++)
|
||||
if ((setup_tab[i].vertex_format & req) == req)
|
||||
break;
|
||||
|
||||
if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format &&
|
||||
rmesa->tcl.indexed_verts.buf)
|
||||
return;
|
||||
|
||||
if (rmesa->tcl.indexed_verts.buf)
|
||||
r200ReleaseArrays( ctx, ~0 );
|
||||
|
||||
r200AllocDmaRegionVerts( rmesa,
|
||||
&rmesa->tcl.indexed_verts,
|
||||
VB->Count,
|
||||
setup_tab[i].vertex_size * 4,
|
||||
4);
|
||||
|
||||
setup_tab[i].emit( ctx, 0, VB->Count,
|
||||
rmesa->tcl.indexed_verts.address +
|
||||
rmesa->tcl.indexed_verts.start );
|
||||
|
||||
rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
|
||||
rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts );
|
||||
rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size;
|
||||
rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size;
|
||||
|
||||
rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts;
|
||||
rmesa->tcl.nr_aos_components = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, newinputs );
|
||||
|
||||
if (newinputs)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ );
|
||||
}
|
||||
494
src/mesa/drivers/dri/r200/r200_pixel.c
Normal file
494
src/mesa/drivers/dri/r200/r200_pixel.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "enums.h"
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "texutil.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_pixel.h"
|
||||
#include "r200_swtcl.h"
|
||||
|
||||
|
||||
|
||||
static GLboolean
|
||||
check_color( const GLcontext *ctx, GLenum type, GLenum format,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
const void *pixels, GLint sz, GLint pitch )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint cpp = rmesa->r200Screen->cpp;
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if ( (pitch & 63) ||
|
||||
ctx->_ImageTransferState ||
|
||||
packing->SwapBytes ||
|
||||
packing->LsbFirst) {
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&
|
||||
cpp == 4 &&
|
||||
format == GL_BGRA ) {
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: failed\n", __FUNCTION__);
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
check_color_per_fragment_ops( const GLcontext *ctx )
|
||||
{
|
||||
int result;
|
||||
result = (!( ctx->Color.AlphaEnabled ||
|
||||
ctx->Depth.Test ||
|
||||
ctx->Fog.Enabled ||
|
||||
ctx->Scissor.Enabled ||
|
||||
ctx->Stencil.Enabled ||
|
||||
!ctx->Color.ColorMask[0] ||
|
||||
!ctx->Color.ColorMask[1] ||
|
||||
!ctx->Color.ColorMask[2] ||
|
||||
!ctx->Color.ColorMask[3] ||
|
||||
ctx->Color.ColorLogicOpEnabled ||
|
||||
ctx->Texture._EnabledUnits ||
|
||||
ctx->Depth.OcclusionTest
|
||||
) &&
|
||||
ctx->Current.RasterPosValid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static GLboolean
|
||||
clip_pixelrect( const GLcontext *ctx,
|
||||
const GLframebuffer *buffer,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height,
|
||||
GLint *size )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
/* left clipping */
|
||||
if (*x < buffer->_Xmin) {
|
||||
*width -= (buffer->_Xmin - *x);
|
||||
*x = buffer->_Xmin;
|
||||
}
|
||||
|
||||
/* right clipping */
|
||||
if (*x + *width > buffer->_Xmax)
|
||||
*width -= (*x + *width - buffer->_Xmax - 1);
|
||||
|
||||
if (*width <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
/* bottom clipping */
|
||||
if (*y < buffer->_Ymin) {
|
||||
*height -= (buffer->_Ymin - *y);
|
||||
*y = buffer->_Ymin;
|
||||
}
|
||||
|
||||
/* top clipping */
|
||||
if (*y + *height > buffer->_Ymax)
|
||||
*height -= (*y + *height - buffer->_Ymax - 1);
|
||||
|
||||
if (*height <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
*size = ((*y + *height - 1) * rmesa->r200Screen->frontPitch +
|
||||
(*x + *width - 1) * rmesa->r200Screen->cpp);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
r200TryReadPixels( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *pack,
|
||||
GLvoid *pixels )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLint size;
|
||||
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
||||
GLint blit_format;
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* Only accelerate reading to agp buffers.
|
||||
*/
|
||||
if ( !r200IsAgpMemory(rmesa, pixels,
|
||||
pitch * height * rmesa->r200Screen->cpp ) ) {
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
|
||||
* blitter:
|
||||
*/
|
||||
if (!pack->Invert) {
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (!check_color(ctx, type, format, pack, pixels, size, pitch))
|
||||
return GL_FALSE;
|
||||
|
||||
switch ( rmesa->r200Screen->cpp ) {
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Although the blits go on the command buffer, need to do this and
|
||||
* fire with lock held to guarentee cliprects and drawOffset are
|
||||
* correct.
|
||||
*
|
||||
* This is an unusual situation however, as the code which flushes
|
||||
* a full command buffer expects to be called unlocked. As a
|
||||
* workaround, immediately flush the buffer on aquiring the lock.
|
||||
*/
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
if (rmesa->store.cmd_used)
|
||||
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
|
||||
if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height,
|
||||
&size)) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s totally clipped -- nothing to do\n",
|
||||
__FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
int nbox = dPriv->numClipRects;
|
||||
int src_offset = rmesa->state.color.drawOffset;
|
||||
int src_pitch = rmesa->state.color.drawPitch * rmesa->r200Screen->cpp;
|
||||
int dst_offset = r200AgpOffsetFromVirtual( rmesa, pixels);
|
||||
int dst_pitch = pitch * rmesa->r200Screen->cpp;
|
||||
XF86DRIClipRectRec *box = dPriv->pClipRects;
|
||||
int i;
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
y = dPriv->h - y - height;
|
||||
x += dPriv->x;
|
||||
y += dPriv->y;
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
|
||||
src_pitch, dst_pitch);
|
||||
|
||||
for (i = 0 ; i < nbox ; i++)
|
||||
{
|
||||
GLint bx = box[i].x1;
|
||||
GLint by = box[i].y1;
|
||||
GLint bw = box[i].x2 - bx;
|
||||
GLint bh = box[i].y2 - by;
|
||||
|
||||
if (bx < x) bw -= x - bx, bx = x;
|
||||
if (by < y) bh -= y - by, by = y;
|
||||
if (bx + bw > x + width) bw = x + width - bx;
|
||||
if (by + bh > y + height) bh = y + height - by;
|
||||
if (bw <= 0) continue;
|
||||
if (bh <= 0) continue;
|
||||
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
src_pitch, src_offset,
|
||||
dst_pitch, dst_offset,
|
||||
bx, by,
|
||||
bx - x, by - y,
|
||||
bw, bh );
|
||||
}
|
||||
|
||||
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
}
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
r200Finish( ctx ); /* required by GL */
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
r200ReadPixels( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *pack,
|
||||
GLvoid *pixels )
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (!r200TryReadPixels( ctx, x, y, width, height, format, type, pack,
|
||||
pixels))
|
||||
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
|
||||
pixels);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void do_draw_pix( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLint pitch,
|
||||
const void *pixels,
|
||||
GLuint dest, GLuint planemask)
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
XF86DRIClipRectPtr box = dPriv->pClipRects;
|
||||
int nbox = dPriv->numClipRects;
|
||||
int i;
|
||||
int blit_format;
|
||||
int size;
|
||||
int src_offset = r200AgpOffsetFromVirtual( rmesa, pixels);
|
||||
int src_pitch = pitch * rmesa->r200Screen->cpp;
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
switch ( rmesa->r200Screen->cpp ) {
|
||||
case 2:
|
||||
blit_format = R200_CP_COLOR_FORMAT_RGB565;
|
||||
break;
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
if (rmesa->store.cmd_used)
|
||||
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
|
||||
y -= height; /* cope with pixel zoom */
|
||||
|
||||
if (!clip_pixelrect(ctx, ctx->DrawBuffer,
|
||||
&x, &y, &width, &height,
|
||||
&size)) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return;
|
||||
}
|
||||
|
||||
y = dPriv->h - y - height; /* convert from gl to hardware coords */
|
||||
x += dPriv->x;
|
||||
y += dPriv->y;
|
||||
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
for (i = 0 ; i < nbox ; i++ )
|
||||
{
|
||||
GLint bx = box[i].x1;
|
||||
GLint by = box[i].y1;
|
||||
GLint bw = box[i].x2 - bx;
|
||||
GLint bh = box[i].y2 - by;
|
||||
|
||||
if (bx < x) bw -= x - bx, bx = x;
|
||||
if (by < y) bh -= y - by, by = y;
|
||||
if (bx + bw > x + width) bw = x + width - bx;
|
||||
if (by + bh > y + height) bh = y + height - by;
|
||||
if (bw <= 0) continue;
|
||||
if (bh <= 0) continue;
|
||||
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
src_pitch, src_offset,
|
||||
rmesa->state.color.drawPitch * rmesa->r200Screen->cpp,
|
||||
rmesa->state.color.drawOffset,
|
||||
bx - x, by - y,
|
||||
bx, by,
|
||||
bw, bh );
|
||||
}
|
||||
|
||||
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
r200WaitForIdleLocked( rmesa ); /* required by GL */
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static GLboolean
|
||||
r200TryDrawPixels( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
|
||||
GLuint dest, planemask;
|
||||
GLuint cpp = rmesa->r200Screen->cpp;
|
||||
GLint size = width * pitch * cpp;
|
||||
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
switch (format) {
|
||||
case GL_RGB:
|
||||
case GL_RGBA:
|
||||
case GL_BGRA:
|
||||
dest = rmesa->state.color.drawOffset;
|
||||
|
||||
planemask = r200PackColor(cpp,
|
||||
ctx->Color.ColorMask[RCOMP],
|
||||
ctx->Color.ColorMask[GCOMP],
|
||||
ctx->Color.ColorMask[BCOMP],
|
||||
ctx->Color.ColorMask[ACOMP]);
|
||||
|
||||
if (cpp == 2)
|
||||
planemask |= planemask << 16;
|
||||
|
||||
if (planemask != ~0)
|
||||
return GL_FALSE; /* fix me -- should be possible */
|
||||
|
||||
/* Can't do conversions on agp reads/draws.
|
||||
*/
|
||||
if ( !r200IsAgpMemory( rmesa, pixels, size ) ) {
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (!check_color_per_fragment_ops(ctx)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx->Pixel.ZoomX != 1.0F ||
|
||||
ctx->Pixel.ZoomY != -1.0F)
|
||||
return GL_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if ( r200IsAgpMemory(rmesa, pixels, size) )
|
||||
{
|
||||
do_draw_pix( ctx, x, y, width, height, pitch, pixels,
|
||||
dest, planemask );
|
||||
return GL_TRUE;
|
||||
}
|
||||
else if (0)
|
||||
{
|
||||
/* Pixels is in regular memory -- get dma buffers and perform
|
||||
* upload through them.
|
||||
*/
|
||||
}
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
r200DrawPixels( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels )
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_PIXEL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (!r200TryDrawPixels( ctx, x, y, width, height, format, type,
|
||||
unpack, pixels ))
|
||||
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
|
||||
unpack, pixels );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
r200Bitmap( GLcontext *ctx, GLint px, GLint py,
|
||||
GLsizei width, GLsizei height,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLubyte *bitmap )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (rmesa->Fallback)
|
||||
_swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap );
|
||||
else
|
||||
r200PointsBitmap( ctx, px, py, width, height, unpack, bitmap );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void r200InitPixelFuncs( GLcontext *ctx )
|
||||
{
|
||||
/* Pixel path fallbacks.
|
||||
*/
|
||||
ctx->Driver.Accum = _swrast_Accum;
|
||||
ctx->Driver.Bitmap = _swrast_Bitmap;
|
||||
ctx->Driver.CopyPixels = _swrast_CopyPixels;
|
||||
ctx->Driver.DrawPixels = _swrast_DrawPixels;
|
||||
ctx->Driver.ReadPixels = _swrast_ReadPixels;
|
||||
|
||||
if (!getenv("R200_NO_BLITS") && R200_CONTEXT(ctx)->dri.drmMinor >= 6) {
|
||||
ctx->Driver.ReadPixels = r200ReadPixels;
|
||||
ctx->Driver.DrawPixels = r200DrawPixels;
|
||||
if (getenv("R200_HW_BITMAP"))
|
||||
ctx->Driver.Bitmap = r200Bitmap;
|
||||
}
|
||||
}
|
||||
43
src/mesa/drivers/dri/r200/r200_pixel.h
Normal file
43
src/mesa/drivers/dri/r200/r200_pixel.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_PIXEL_H__
|
||||
#define __R200_PIXEL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r200InitPixelFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
1438
src/mesa/drivers/dri/r200/r200_reg.h
Normal file
1438
src/mesa/drivers/dri/r200/r200_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
1436
src/mesa/drivers/dri/r200/r200_sanity.c
Normal file
1436
src/mesa/drivers/dri/r200/r200_sanity.c
Normal file
File diff suppressed because it is too large
Load Diff
11
src/mesa/drivers/dri/r200/r200_sanity.h
Normal file
11
src/mesa/drivers/dri/r200/r200_sanity.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef R200_SANITY_H
|
||||
#define R200_SANITY_H
|
||||
|
||||
extern int r200SanityCmdBuffer( r200ContextPtr rmesa,
|
||||
int nbox,
|
||||
XF86DRIClipRectRec *boxes );
|
||||
|
||||
|
||||
extern int r200ValidateTexObjs( r200ContextPtr rmesa );
|
||||
|
||||
#endif
|
||||
434
src/mesa/drivers/dri/r200/r200_screen.c
Normal file
434
src/mesa/drivers/dri/r200/r200_screen.c
Normal file
@@ -0,0 +1,434 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
|
||||
#include "r200_screen.h"
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
|
||||
|
||||
#if 1
|
||||
/* Including xf86PciInfo.h introduces a bunch of errors...
|
||||
*/
|
||||
#define PCI_CHIP_R200_QD 0x5144
|
||||
#define PCI_CHIP_R200_QE 0x5145
|
||||
#define PCI_CHIP_R200_QF 0x5146
|
||||
#define PCI_CHIP_R200_QG 0x5147
|
||||
#define PCI_CHIP_R200_QY 0x5159
|
||||
#define PCI_CHIP_R200_QZ 0x515A
|
||||
#define PCI_CHIP_R200_LW 0x4C57
|
||||
#define PCI_CHIP_R200_LY 0x4C59
|
||||
#define PCI_CHIP_R200_LZ 0x4C5A
|
||||
#define PCI_CHIP_RV200_QW 0x5157
|
||||
#endif
|
||||
|
||||
static r200ScreenPtr __r200Screen;
|
||||
|
||||
/* Create the device specific screen private data struct.
|
||||
*/
|
||||
static r200ScreenPtr
|
||||
r200CreateScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
r200ScreenPtr r200Screen;
|
||||
RADEONDRIPtr r200DRIPriv = (RADEONDRIPtr)sPriv->pDevPriv;
|
||||
|
||||
/* Check the DRI extension version */
|
||||
if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) {
|
||||
__driUtilMessage( "R200 DRI driver expected DRI version 4.0.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->driMajor, sPriv->driMinor, sPriv->driPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that the DDX driver version is compatible */
|
||||
if ( sPriv->ddxMajor != 4 ||
|
||||
sPriv->ddxMinor < 0 ) {
|
||||
__driUtilMessage( "R200 DRI driver expected DDX driver version 4.0.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that the DRM driver version is compatible
|
||||
* -- R200 support added at 1.5.0.
|
||||
*/
|
||||
if ( sPriv->drmMajor != 1 ||
|
||||
sPriv->drmMinor < 5) {
|
||||
__driUtilMessage( "R200 DRI driver expected DRM driver version 1.5.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate the private area */
|
||||
r200Screen = (r200ScreenPtr) CALLOC( sizeof(*r200Screen) );
|
||||
if ( !r200Screen ) {
|
||||
__driUtilMessage("%s: CALLOC r200Screen struct failed",
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if kernel module is new enough to support cube maps */
|
||||
if (sPriv->drmMajor * 100 + sPriv->drmMinor >= 107)
|
||||
r200Screen->drmSupportsCubeMaps = GL_TRUE;
|
||||
else
|
||||
r200Screen->drmSupportsCubeMaps = GL_FALSE;
|
||||
|
||||
switch ( r200DRIPriv->deviceID ) {
|
||||
case PCI_CHIP_R200_QD:
|
||||
case PCI_CHIP_R200_QE:
|
||||
case PCI_CHIP_R200_QF:
|
||||
case PCI_CHIP_R200_QG:
|
||||
case PCI_CHIP_R200_QY:
|
||||
case PCI_CHIP_R200_QZ:
|
||||
case PCI_CHIP_RV200_QW:
|
||||
case PCI_CHIP_R200_LW:
|
||||
case PCI_CHIP_R200_LY:
|
||||
case PCI_CHIP_R200_LZ:
|
||||
__driUtilMessage("r200CreateScreen(): Device isn't an r200!\n");
|
||||
FREE( r200Screen );
|
||||
return NULL;
|
||||
default:
|
||||
r200Screen->chipset = R200_CHIPSET_R200;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* This is first since which regions we map depends on whether or
|
||||
* not we are using a PCI card.
|
||||
*/
|
||||
r200Screen->IsPCI = r200DRIPriv->IsPCI;
|
||||
|
||||
{
|
||||
int ret;
|
||||
drmRadeonGetParam gp;
|
||||
|
||||
gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET;
|
||||
gp.value = &r200Screen->agp_buffer_offset;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( r200Screen );
|
||||
fprintf(stderr, "drmR200GetParam: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r200Screen->agp_texture_offset =
|
||||
r200Screen->agp_buffer_offset + 2*1024*1024;
|
||||
|
||||
|
||||
if (sPriv->drmMinor >= 6) {
|
||||
gp.param = RADEON_PARAM_AGP_BASE;
|
||||
gp.value = &r200Screen->agp_base;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( r200Screen );
|
||||
fprintf(stderr, "drmR200GetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (sPriv->drmMinor >= 6) {
|
||||
gp.param = RADEON_PARAM_IRQ_NR;
|
||||
gp.value = &r200Screen->irq;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( r200Screen );
|
||||
fprintf(stderr, "drmR200GetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
r200Screen->mmio.handle = r200DRIPriv->registerHandle;
|
||||
r200Screen->mmio.size = r200DRIPriv->registerSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
r200Screen->mmio.handle,
|
||||
r200Screen->mmio.size,
|
||||
&r200Screen->mmio.map ) ) {
|
||||
FREE( r200Screen );
|
||||
__driUtilMessage("r200CreateScreen(): drmMap failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r200Screen->status.handle = r200DRIPriv->statusHandle;
|
||||
r200Screen->status.size = r200DRIPriv->statusSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
r200Screen->status.handle,
|
||||
r200Screen->status.size,
|
||||
&r200Screen->status.map ) ) {
|
||||
drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size );
|
||||
FREE( r200Screen );
|
||||
__driUtilMessage("r200CreateScreen(): drmMap (2) failed\n");
|
||||
return NULL;
|
||||
}
|
||||
r200Screen->scratch = (__volatile__ GLuint *)
|
||||
((GLubyte *)r200Screen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
||||
|
||||
r200Screen->buffers = drmMapBufs( sPriv->fd );
|
||||
if ( !r200Screen->buffers ) {
|
||||
drmUnmap( r200Screen->status.map, r200Screen->status.size );
|
||||
drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size );
|
||||
FREE( r200Screen );
|
||||
__driUtilMessage("r200CreateScreen(): drmMapBufs failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !r200Screen->IsPCI ) {
|
||||
r200Screen->agpTextures.handle = r200DRIPriv->agpTexHandle;
|
||||
r200Screen->agpTextures.size = r200DRIPriv->agpTexMapSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
r200Screen->agpTextures.handle,
|
||||
r200Screen->agpTextures.size,
|
||||
(drmAddressPtr)&r200Screen->agpTextures.map ) ) {
|
||||
drmUnmapBufs( r200Screen->buffers );
|
||||
drmUnmap( r200Screen->status.map, r200Screen->status.size );
|
||||
drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size );
|
||||
FREE( r200Screen );
|
||||
__driUtilMessage("r200CreateScreen(): IsPCI failed\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
r200Screen->cpp = r200DRIPriv->bpp / 8;
|
||||
r200Screen->AGPMode = r200DRIPriv->AGPMode;
|
||||
|
||||
r200Screen->frontOffset = r200DRIPriv->frontOffset;
|
||||
r200Screen->frontPitch = r200DRIPriv->frontPitch;
|
||||
r200Screen->backOffset = r200DRIPriv->backOffset;
|
||||
r200Screen->backPitch = r200DRIPriv->backPitch;
|
||||
r200Screen->depthOffset = r200DRIPriv->depthOffset;
|
||||
r200Screen->depthPitch = r200DRIPriv->depthPitch;
|
||||
|
||||
r200Screen->texOffset[RADEON_CARD_HEAP] = r200DRIPriv->textureOffset;
|
||||
r200Screen->texSize[RADEON_CARD_HEAP] = r200DRIPriv->textureSize;
|
||||
r200Screen->logTexGranularity[RADEON_CARD_HEAP] =
|
||||
r200DRIPriv->log2TexGran;
|
||||
|
||||
if ( r200Screen->IsPCI ) {
|
||||
r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
|
||||
r200Screen->texOffset[RADEON_AGP_HEAP] = 0;
|
||||
r200Screen->texSize[RADEON_AGP_HEAP] = 0;
|
||||
r200Screen->logTexGranularity[RADEON_AGP_HEAP] = 0;
|
||||
} else {
|
||||
r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
|
||||
r200Screen->texOffset[RADEON_AGP_HEAP] =
|
||||
r200DRIPriv->agpTexOffset + R200_AGP_TEX_OFFSET;
|
||||
r200Screen->texSize[RADEON_AGP_HEAP] = r200DRIPriv->agpTexMapSize;
|
||||
r200Screen->logTexGranularity[RADEON_AGP_HEAP] =
|
||||
r200DRIPriv->log2AGPTexGran;
|
||||
}
|
||||
|
||||
|
||||
r200Screen->driScreen = sPriv;
|
||||
r200Screen->sarea_priv_offset = r200DRIPriv->sarea_priv_offset;
|
||||
return r200Screen;
|
||||
}
|
||||
|
||||
/* Destroy the device specific screen private data struct.
|
||||
*/
|
||||
static void
|
||||
r200DestroyScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
r200ScreenPtr r200Screen = (r200ScreenPtr)sPriv->private;
|
||||
|
||||
if (!r200Screen)
|
||||
return;
|
||||
|
||||
if ( !r200Screen->IsPCI ) {
|
||||
drmUnmap( r200Screen->agpTextures.map,
|
||||
r200Screen->agpTextures.size );
|
||||
}
|
||||
drmUnmapBufs( r200Screen->buffers );
|
||||
drmUnmap( r200Screen->status.map, r200Screen->status.size );
|
||||
drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size );
|
||||
|
||||
FREE( r200Screen );
|
||||
sPriv->private = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the driver specific screen private data.
|
||||
*/
|
||||
static GLboolean
|
||||
r200InitDriver( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
__r200Screen = r200CreateScreen( sPriv );
|
||||
|
||||
sPriv->private = (void *) __r200Screen;
|
||||
|
||||
return sPriv->private ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create and initialize the Mesa and driver specific pixmap buffer
|
||||
* data.
|
||||
*/
|
||||
static GLboolean
|
||||
r200CreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
const __GLcontextModes *mesaVis,
|
||||
GLboolean isPixmap )
|
||||
{
|
||||
if (isPixmap) {
|
||||
return GL_FALSE; /* not implemented */
|
||||
}
|
||||
else {
|
||||
const GLboolean swDepth = GL_FALSE;
|
||||
const GLboolean swAlpha = GL_FALSE;
|
||||
const GLboolean swAccum = mesaVis->accumRedBits > 0;
|
||||
const GLboolean swStencil = mesaVis->stencilBits > 0 &&
|
||||
mesaVis->depthBits != 24;
|
||||
driDrawPriv->driverPrivate = (void *)
|
||||
_mesa_create_framebuffer( mesaVis,
|
||||
swDepth,
|
||||
swStencil,
|
||||
swAccum,
|
||||
swAlpha );
|
||||
return (driDrawPriv->driverPrivate != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
||||
{
|
||||
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Fullscreen mode isn't used for much -- could be a way to shrink
|
||||
* front/back buffers & get more texture memory if the client has
|
||||
* changed the video resolution.
|
||||
*
|
||||
* Pageflipping is now done automatically whenever there is a single
|
||||
* 3d client.
|
||||
*/
|
||||
static GLboolean
|
||||
r200OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static struct __DriverAPIRec r200API = {
|
||||
r200InitDriver,
|
||||
r200DestroyScreen,
|
||||
r200CreateContext,
|
||||
r200DestroyContext,
|
||||
r200CreateBuffer,
|
||||
r200DestroyBuffer,
|
||||
r200SwapBuffers,
|
||||
r200MakeCurrent,
|
||||
r200UnbindContext,
|
||||
r200OpenCloseFullScreen,
|
||||
r200OpenCloseFullScreen
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
* Return: pointer to a __DRIscreenPrivate.
|
||||
*
|
||||
*/
|
||||
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
|
||||
int numConfigs, __GLXvisualConfig *config)
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API);
|
||||
return (void *) psp;
|
||||
}
|
||||
|
||||
|
||||
/* This function is called by libGL.so to allow the driver to dynamically
|
||||
* extend libGL. We can add new GLX functions and/or new GL functions.
|
||||
* Note that _mesa_create_context() will probably add most of the newer
|
||||
* OpenGL extension functions into the dispatcher.
|
||||
*/
|
||||
void
|
||||
__driRegisterExtensions( void )
|
||||
{
|
||||
/* dlopen ourself */
|
||||
void *dll = dlopen(NULL, RTLD_GLOBAL);
|
||||
if (dll) {
|
||||
typedef void *(*registerFunc)(const char *funcName, void *funcAddr);
|
||||
typedef void (*registerString)(const char *extName);
|
||||
|
||||
/* Get pointers to libGL's __glXRegisterGLXFunction
|
||||
* and __glXRegisterGLXExtensionString, if they exist.
|
||||
*/
|
||||
registerFunc regFunc = (registerFunc) dlsym(dll, "__glXRegisterGLXFunction");
|
||||
registerString regString = (registerString) dlsym(dll, "__glXRegisterGLXExtensionString");
|
||||
|
||||
if (regFunc) {
|
||||
/* register our GLX extensions with libGL */
|
||||
void *p;
|
||||
p = regFunc("glXAllocateMemoryNV", (void *) r200AllocateMemoryNV);
|
||||
if (p)
|
||||
; /* XXX already registered - what to do, wrap? */
|
||||
|
||||
p = regFunc("glXFreeMemoryNV", (void *) r200FreeMemoryNV);
|
||||
if (p)
|
||||
; /* XXX already registered - what to do, wrap? */
|
||||
|
||||
p = regFunc("glXGetAGPOffsetMESA", (void *) r200GetAGPOffset);
|
||||
if (p)
|
||||
; /* XXX already registered - what to do, wrap? */
|
||||
}
|
||||
|
||||
if (regString) {
|
||||
regString("GLX_NV_vertex_array_range");
|
||||
regString("GLX_MESA_agp_offset");
|
||||
}
|
||||
|
||||
dlclose(dll);
|
||||
}
|
||||
}
|
||||
96
src/mesa/drivers/dri/r200/r200_screen.h
Normal file
96
src/mesa/drivers/dri/r200/r200_screen.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_SCREEN_H__
|
||||
#define __R200_SCREEN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "dri_util.h"
|
||||
#include "radeon_common.h"
|
||||
#include "radeon_sarea.h"
|
||||
|
||||
typedef struct {
|
||||
drmHandle handle; /* Handle to the DRM region */
|
||||
drmSize size; /* Size of the DRM region */
|
||||
drmAddress map; /* Mapping of the DRM region */
|
||||
} r200RegionRec, *r200RegionPtr;
|
||||
|
||||
#define R200_CHIPSET_R200 1
|
||||
#define R200_CHIPSET_MOBILITY 2
|
||||
|
||||
|
||||
#define R200_NR_TEX_HEAPS 2
|
||||
|
||||
typedef struct {
|
||||
|
||||
int chipset;
|
||||
int cpp;
|
||||
int IsPCI; /* Current card is a PCI card */
|
||||
int AGPMode;
|
||||
unsigned int irq; /* IRQ number (0 means none) */
|
||||
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int backOffset;
|
||||
unsigned int backPitch;
|
||||
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthPitch;
|
||||
|
||||
/* Shared texture data */
|
||||
int numTexHeaps;
|
||||
int texOffset[R200_NR_TEX_HEAPS];
|
||||
int texSize[R200_NR_TEX_HEAPS];
|
||||
int logTexGranularity[R200_NR_TEX_HEAPS];
|
||||
|
||||
r200RegionRec mmio;
|
||||
r200RegionRec status;
|
||||
r200RegionRec agpTextures;
|
||||
|
||||
drmBufMapPtr buffers;
|
||||
|
||||
__volatile__ GLuint *scratch;
|
||||
|
||||
__DRIscreenPrivate *driScreen;
|
||||
unsigned int sarea_priv_offset;
|
||||
unsigned int agp_buffer_offset; /* offset in card memory space */
|
||||
unsigned int agp_texture_offset; /* offset in card memory space */
|
||||
unsigned int agp_base;
|
||||
|
||||
GLboolean drmSupportsCubeMaps; /* need radeon kernel module >=1.7 */
|
||||
} r200ScreenRec, *r200ScreenPtr;
|
||||
|
||||
#endif
|
||||
#endif /* __R200_SCREEN_H__ */
|
||||
430
src/mesa/drivers/dri/r200/r200_span.c
Normal file
430
src/mesa/drivers/dri/r200/r200_span.c
Normal file
@@ -0,0 +1,430 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_span.h"
|
||||
#include "r200_tex.h"
|
||||
|
||||
#define DBG 0
|
||||
|
||||
#define LOCAL_VARS \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
r200ScreenPtr r200Screen = rmesa->r200Screen; \
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
GLuint pitch = r200Screen->frontPitch * r200Screen->cpp; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(sPriv->pFB + \
|
||||
rmesa->state.color.drawOffset + \
|
||||
(dPriv->x * r200Screen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
char *read_buf = (char *)(sPriv->pFB + \
|
||||
rmesa->state.pixel.readOffset + \
|
||||
(dPriv->x * r200Screen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
GLuint p; \
|
||||
(void) read_buf; (void) buf; (void) p
|
||||
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
r200ScreenPtr r200Screen = rmesa->r200Screen; \
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLuint xo = dPriv->x; \
|
||||
GLuint yo = dPriv->y; \
|
||||
char *buf = (char *)(sPriv->pFB + r200Screen->depthOffset); \
|
||||
(void) buf
|
||||
|
||||
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
|
||||
|
||||
|
||||
#define CLIPPIXEL( _x, _y ) \
|
||||
((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
|
||||
|
||||
|
||||
#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
|
||||
if ( _y < miny || _y >= maxy ) { \
|
||||
_n1 = 0, _x1 = x; \
|
||||
} else { \
|
||||
_n1 = _n; \
|
||||
_x1 = _x; \
|
||||
if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
|
||||
if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
|
||||
}
|
||||
|
||||
#define Y_FLIP( _y ) (height - _y - 1)
|
||||
|
||||
|
||||
#define HW_LOCK()
|
||||
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
int _nc = dPriv->numClipRects; \
|
||||
\
|
||||
while ( _nc-- ) { \
|
||||
int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
|
||||
int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
|
||||
int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
|
||||
int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
|
||||
|
||||
#define HW_ENDCLIPLOOP() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HW_UNLOCK()
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Color buffer
|
||||
*/
|
||||
|
||||
/* 16 bit, RGB565 color spanline and pixel functions
|
||||
*/
|
||||
#define INIT_MONO_PIXEL(p, color) \
|
||||
p = PACK_COLOR_565( color[0], color[1], color[2] )
|
||||
|
||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
|
||||
(((int)g & 0xfc) << 3) | \
|
||||
(((int)b & 0xf8) >> 3))
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = p
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
|
||||
rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
|
||||
rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[3] = 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) r200##x##_RGB565
|
||||
#include "spantmp.h"
|
||||
|
||||
/* 32 bit, ARGB8888 color spanline and pixel functions
|
||||
*/
|
||||
#undef INIT_MONO_PIXEL
|
||||
#define INIT_MONO_PIXEL(p, color) \
|
||||
p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
|
||||
|
||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
||||
do { \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
|
||||
(g << 8) | \
|
||||
(r << 16) | \
|
||||
(a << 24) ); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
do { \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = p; \
|
||||
} while (0)
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \
|
||||
GLuint p = *ptr; \
|
||||
rgba[0] = (p >> 16) & 0xff; \
|
||||
rgba[1] = (p >> 8) & 0xff; \
|
||||
rgba[2] = (p >> 0) & 0xff; \
|
||||
rgba[3] = (p >> 24) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) r200##x##_ARGB8888
|
||||
#include "spantmp.h"
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Depth buffer
|
||||
*/
|
||||
|
||||
/* The R200 has depth tiling on all the time, so we have to convert
|
||||
* the x,y coordinates into the memory bus address (mba) in the same
|
||||
* manner as the engine. In each case, the linear block address (ba)
|
||||
* is calculated, and then wired with x and y to produce the final
|
||||
* memory address.
|
||||
*/
|
||||
|
||||
#define BIT(x,b) ((x & (1<<b))>>b)
|
||||
static GLuint r200_mba_z32( r200ContextPtr rmesa,
|
||||
GLint x, GLint y )
|
||||
{
|
||||
GLuint pitch = rmesa->r200Screen->frontPitch;
|
||||
GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x3FF) >> 5);
|
||||
GLuint a =
|
||||
(BIT(x,0) << 2) |
|
||||
(BIT(y,0) << 3) |
|
||||
(BIT(x,1) << 4) |
|
||||
(BIT(y,1) << 5) |
|
||||
(BIT(x,3) << 6) |
|
||||
(BIT(x,4) << 7) |
|
||||
(BIT(x,2) << 8) |
|
||||
(BIT(y,2) << 9) |
|
||||
(BIT(y,3) << 10) |
|
||||
(((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
|
||||
((b >> 1) << 12);
|
||||
return a;
|
||||
}
|
||||
|
||||
static GLuint r200_mba_z16( r200ContextPtr rmesa, GLint x, GLint y )
|
||||
{
|
||||
GLuint pitch = rmesa->r200Screen->frontPitch;
|
||||
GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x3FF) >> 6);
|
||||
GLuint a =
|
||||
(BIT(x,0) << 1) |
|
||||
(BIT(y,0) << 2) |
|
||||
(BIT(x,1) << 3) |
|
||||
(BIT(y,1) << 4) |
|
||||
(BIT(x,2) << 5) |
|
||||
(BIT(x,4) << 6) |
|
||||
(BIT(x,5) << 7) |
|
||||
(BIT(x,3) << 8) |
|
||||
(BIT(y,2) << 9) |
|
||||
(BIT(y,3) << 10) |
|
||||
(((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
|
||||
((b >> 1) << 12);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/* 16-bit depth buffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
*(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo )) = d;
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo ));
|
||||
|
||||
#define TAG(x) r200##x##_16
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
tmp |= ((d) & 0x00ffffff); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + r200_mba_z32( rmesa, _x + xo, \
|
||||
_y + yo )) & 0x00ffffff;
|
||||
|
||||
#define TAG(x) r200##x##_24_8
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Stencil buffer
|
||||
*/
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_STENCIL( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0x00ffffff; \
|
||||
tmp |= (((d) & 0xff) << 24); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
do { \
|
||||
GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
d = tmp >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) r200##x##_24_8
|
||||
#include "stenciltmp.h"
|
||||
|
||||
|
||||
/*
|
||||
* This function is called to specify which buffer to read and write
|
||||
* for software rasterization (swrast) fallbacks. This doesn't necessarily
|
||||
* correspond to glDrawBuffer() or glReadBuffer() calls.
|
||||
*/
|
||||
static void r200SetBuffer( GLcontext *ctx,
|
||||
GLframebuffer *colorBuffer,
|
||||
GLuint bufferBit )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
switch ( bufferBit ) {
|
||||
case FRONT_LEFT_BIT:
|
||||
if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) {
|
||||
rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->r200Screen->backPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch;
|
||||
} else {
|
||||
rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->r200Screen->frontPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch;
|
||||
}
|
||||
break;
|
||||
case BACK_LEFT_BIT:
|
||||
if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) {
|
||||
rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->r200Screen->frontPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch;
|
||||
} else {
|
||||
rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->r200Screen->backPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Bad bufferBit in r200SetBuffer()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move locking out to get reasonable span performance (10x better
|
||||
* than doing this in HW_LOCK above). WaitForIdle() is the main
|
||||
* culprit.
|
||||
*/
|
||||
|
||||
static void r200SpanRenderStart( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
|
||||
R200_FIREVERTICES( rmesa );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
r200WaitForIdleLocked( rmesa );
|
||||
|
||||
/* Read & rewrite the first pixel in the frame buffer. This should
|
||||
* be a noop, right? In fact without this conform fails as reading
|
||||
* from the framebuffer sometimes produces old results -- the
|
||||
* on-card read cache gets mixed up and doesn't notice that the
|
||||
* framebuffer has been updated.
|
||||
*
|
||||
* In the worst case this is buggy too as p might get the wrong
|
||||
* value first time, so really need a hidden pixel somewhere for this.
|
||||
*/
|
||||
{
|
||||
int p;
|
||||
volatile int *read_buf = (volatile int *)(rmesa->dri.screen->pFB +
|
||||
rmesa->state.pixel.readOffset);
|
||||
p = *read_buf;
|
||||
*read_buf = p;
|
||||
}
|
||||
}
|
||||
|
||||
static void r200SpanRenderFinish( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
_swrast_flush( ctx );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
void r200InitSpanFuncs( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
|
||||
|
||||
swdd->SetBuffer = r200SetBuffer;
|
||||
|
||||
switch ( rmesa->r200Screen->cpp ) {
|
||||
case 2:
|
||||
swdd->WriteRGBASpan = r200WriteRGBASpan_RGB565;
|
||||
swdd->WriteRGBSpan = r200WriteRGBSpan_RGB565;
|
||||
swdd->WriteMonoRGBASpan = r200WriteMonoRGBASpan_RGB565;
|
||||
swdd->WriteRGBAPixels = r200WriteRGBAPixels_RGB565;
|
||||
swdd->WriteMonoRGBAPixels = r200WriteMonoRGBAPixels_RGB565;
|
||||
swdd->ReadRGBASpan = r200ReadRGBASpan_RGB565;
|
||||
swdd->ReadRGBAPixels = r200ReadRGBAPixels_RGB565;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
swdd->WriteRGBASpan = r200WriteRGBASpan_ARGB8888;
|
||||
swdd->WriteRGBSpan = r200WriteRGBSpan_ARGB8888;
|
||||
swdd->WriteMonoRGBASpan = r200WriteMonoRGBASpan_ARGB8888;
|
||||
swdd->WriteRGBAPixels = r200WriteRGBAPixels_ARGB8888;
|
||||
swdd->WriteMonoRGBAPixels = r200WriteMonoRGBAPixels_ARGB8888;
|
||||
swdd->ReadRGBASpan = r200ReadRGBASpan_ARGB8888;
|
||||
swdd->ReadRGBAPixels = r200ReadRGBAPixels_ARGB8888;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( rmesa->glCtx->Visual.depthBits ) {
|
||||
case 16:
|
||||
swdd->ReadDepthSpan = r200ReadDepthSpan_16;
|
||||
swdd->WriteDepthSpan = r200WriteDepthSpan_16;
|
||||
swdd->ReadDepthPixels = r200ReadDepthPixels_16;
|
||||
swdd->WriteDepthPixels = r200WriteDepthPixels_16;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
swdd->ReadDepthSpan = r200ReadDepthSpan_24_8;
|
||||
swdd->WriteDepthSpan = r200WriteDepthSpan_24_8;
|
||||
swdd->ReadDepthPixels = r200ReadDepthPixels_24_8;
|
||||
swdd->WriteDepthPixels = r200WriteDepthPixels_24_8;
|
||||
|
||||
swdd->ReadStencilSpan = r200ReadStencilSpan_24_8;
|
||||
swdd->WriteStencilSpan = r200WriteStencilSpan_24_8;
|
||||
swdd->ReadStencilPixels = r200ReadStencilPixels_24_8;
|
||||
swdd->WriteStencilPixels = r200WriteStencilPixels_24_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
swdd->SpanRenderStart = r200SpanRenderStart;
|
||||
swdd->SpanRenderFinish = r200SpanRenderFinish;
|
||||
}
|
||||
43
src/mesa/drivers/dri/r200/r200_span.h
Normal file
43
src/mesa/drivers/dri/r200/r200_span.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_SPAN_H__
|
||||
#define __R200_SPAN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r200InitSpanFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
2155
src/mesa/drivers/dri/r200/r200_state.c
Normal file
2155
src/mesa/drivers/dri/r200/r200_state.c
Normal file
File diff suppressed because it is too large
Load Diff
68
src/mesa/drivers/dri/r200/r200_state.h
Normal file
68
src/mesa/drivers/dri/r200/r200_state.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_STATE_H__
|
||||
#define __R200_STATE_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200InitState( r200ContextPtr rmesa );
|
||||
extern void r200InitStateFuncs( GLcontext *ctx );
|
||||
|
||||
extern void r200UpdateMaterial( GLcontext *ctx );
|
||||
|
||||
extern void r200SetCliprects( r200ContextPtr rmesa, GLenum mode );
|
||||
extern void r200RecalcScissorRects( r200ContextPtr rmesa );
|
||||
extern void r200UpdateViewportOffset( GLcontext *ctx );
|
||||
extern void r200UpdateWindow( GLcontext *ctx );
|
||||
|
||||
extern void r200ValidateState( GLcontext *ctx );
|
||||
|
||||
extern void r200PrintDirty( r200ContextPtr rmesa,
|
||||
const char *msg );
|
||||
|
||||
|
||||
extern void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
#define FALLBACK( rmesa, bit, mode ) do { \
|
||||
if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
|
||||
__FUNCTION__, bit, mode ); \
|
||||
r200Fallback( rmesa->glCtx, bit, mode ); \
|
||||
} while (0)
|
||||
|
||||
extern void r200LightingSpaceChange( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
692
src/mesa/drivers/dri/r200/r200_state_init.c
Normal file
692
src/mesa/drivers/dri/r200/r200_state_init.c
Normal file
@@ -0,0 +1,692 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "enums.h"
|
||||
#include "colormac.h"
|
||||
#include "api_arrayelt.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_vtxfmt.h"
|
||||
|
||||
/* =============================================================
|
||||
* State initialization
|
||||
*/
|
||||
|
||||
void r200PrintDirty( r200ContextPtr rmesa, const char *msg )
|
||||
{
|
||||
struct r200_state_atom *l;
|
||||
|
||||
fprintf(stderr, msg);
|
||||
fprintf(stderr, ": ");
|
||||
|
||||
foreach(l, &(rmesa->hw.dirty)) {
|
||||
fprintf(stderr, "%s, ", l->name);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static int cmdpkt( int id )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.packet.cmd_type = RADEON_CMD_PACKET;
|
||||
h.packet.packet_id = id;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
static int cmdvec( int offset, int stride, int count )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.vectors.cmd_type = RADEON_CMD_VECTORS;
|
||||
h.vectors.offset = offset;
|
||||
h.vectors.stride = stride;
|
||||
h.vectors.count = count;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
static int cmdscl( int offset, int stride, int count )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.scalars.cmd_type = RADEON_CMD_SCALARS;
|
||||
h.scalars.offset = offset;
|
||||
h.scalars.stride = stride;
|
||||
h.scalars.count = count;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
static int cmdscl2( int offset, int stride, int count )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.scalars.cmd_type = RADEON_CMD_SCALARS2;
|
||||
h.scalars.offset = offset - 0x100;
|
||||
h.scalars.stride = stride;
|
||||
h.scalars.count = count;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
#define CHECK( NM, FLAG ) \
|
||||
static GLboolean check_##NM( GLcontext *ctx, int idx ) \
|
||||
{ \
|
||||
(void) idx; \
|
||||
return FLAG; \
|
||||
}
|
||||
|
||||
#define TCL_CHECK( NM, FLAG ) \
|
||||
static GLboolean check_##NM( GLcontext *ctx, int idx ) \
|
||||
{ \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
(void) idx; \
|
||||
return !rmesa->TclFallback && (FLAG); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
CHECK( always, GL_TRUE )
|
||||
CHECK( tex_any, ctx->Texture._EnabledUnits )
|
||||
CHECK( tex, ctx->Texture.Unit[idx]._ReallyEnabled )
|
||||
CHECK( fog, ctx->Fog.Enabled )
|
||||
TCL_CHECK( tcl, GL_TRUE )
|
||||
TCL_CHECK( tcl_tex_any, ctx->Texture._EnabledUnits )
|
||||
TCL_CHECK( tcl_tex, ctx->Texture.Unit[idx]._ReallyEnabled )
|
||||
TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
|
||||
TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled )
|
||||
TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[idx].Enabled )
|
||||
TCL_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << idx)) )
|
||||
/* TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled ) */
|
||||
|
||||
|
||||
static GLboolean check_tcl_eyespace_or_fog( GLcontext *ctx, int idx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int res;
|
||||
(void) idx;
|
||||
res = !rmesa->TclFallback && (ctx->_NeedEyeCoords || ctx->Fog.Enabled);
|
||||
fprintf(stderr, "%s: %d\n", __FUNCTION__, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the context's hardware state.
|
||||
*/
|
||||
void r200InitState( r200ContextPtr rmesa )
|
||||
{
|
||||
GLcontext *ctx = rmesa->glCtx;
|
||||
GLuint color_fmt, depth_fmt, i;
|
||||
|
||||
switch ( rmesa->r200Screen->cpp ) {
|
||||
case 2:
|
||||
color_fmt = R200_COLOR_FORMAT_RGB565;
|
||||
break;
|
||||
case 4:
|
||||
color_fmt = R200_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
rmesa->state.color.clear = 0x00000000;
|
||||
|
||||
switch ( ctx->Visual.depthBits ) {
|
||||
case 16:
|
||||
rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff;
|
||||
depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
|
||||
rmesa->state.stencil.clear = 0x00000000;
|
||||
break;
|
||||
case 24:
|
||||
rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff;
|
||||
depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
|
||||
rmesa->state.stencil.clear = 0xff000000;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
|
||||
ctx->Visual.depthBits );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
/* Only have hw stencil when depth buffer is 24 bits deep */
|
||||
rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 &&
|
||||
ctx->Visual.depthBits == 24 );
|
||||
|
||||
rmesa->Fallback = 0;
|
||||
|
||||
if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch;
|
||||
} else {
|
||||
rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch;
|
||||
}
|
||||
|
||||
rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch;
|
||||
|
||||
/* Initialize lists:
|
||||
*/
|
||||
make_empty_list(&(rmesa->hw.dirty)); rmesa->hw.dirty.name = "DIRTY";
|
||||
make_empty_list(&(rmesa->hw.clean)); rmesa->hw.clean.name = "CLEAN";
|
||||
|
||||
|
||||
#define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX ) \
|
||||
do { \
|
||||
rmesa->hw.ATOM.cmd_size = SZ; \
|
||||
rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \
|
||||
rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \
|
||||
rmesa->hw.ATOM.name = NM; \
|
||||
rmesa->hw.ATOM.idx = IDX; \
|
||||
rmesa->hw.ATOM.check = check_##CHK; \
|
||||
insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Allocate state buffers:
|
||||
*/
|
||||
ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 );
|
||||
ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 );
|
||||
ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 );
|
||||
ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 );
|
||||
ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 );
|
||||
ALLOC_STATE( vtx, always, VTX_STATE_SIZE, "VTX/vertex", 0 );
|
||||
ALLOC_STATE( vap, always, VAP_STATE_SIZE, "VAP/vap", 0 );
|
||||
ALLOC_STATE( vte, always, VTE_STATE_SIZE, "VTE/vte", 0 );
|
||||
ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 );
|
||||
ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 );
|
||||
ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 );
|
||||
ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 );
|
||||
ALLOC_STATE( tf, tex_any, TF_STATE_SIZE, "TF/tfactor", 0 );
|
||||
ALLOC_STATE( tex[0], tex_any, TEX_STATE_SIZE, "TEX/tex-0", 0 );
|
||||
ALLOC_STATE( tex[1], tex_any, TEX_STATE_SIZE, "TEX/tex-1", 1 );
|
||||
ALLOC_STATE( cube[0], tex_any, CUBE_STATE_SIZE, "CUBE/tex-0", 0 );
|
||||
ALLOC_STATE( cube[1], tex_any, CUBE_STATE_SIZE, "CUBE/tex-1", 1 );
|
||||
|
||||
ALLOC_STATE( tcl, tcl, TCL_STATE_SIZE, "TCL/tcl", 0 );
|
||||
ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 );
|
||||
ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 );
|
||||
ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 );
|
||||
ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 );
|
||||
ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 );
|
||||
ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 );
|
||||
ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 );
|
||||
ALLOC_STATE( mat[R200_MTX_MV], tcl, MAT_STATE_SIZE, "MAT/modelview", 0 );
|
||||
ALLOC_STATE( mat[R200_MTX_IMV], tcl, MAT_STATE_SIZE, "MAT/it-modelview", 0 );
|
||||
ALLOC_STATE( mat[R200_MTX_MVP], tcl, MAT_STATE_SIZE, "MAT/modelproject", 0 );
|
||||
ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex, MAT_STATE_SIZE, "MAT/texmat0", 0 );
|
||||
ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex, MAT_STATE_SIZE, "MAT/texmat1", 1 );
|
||||
ALLOC_STATE( ucp[0], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-0", 0 );
|
||||
ALLOC_STATE( ucp[1], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
|
||||
ALLOC_STATE( ucp[2], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-2", 2 );
|
||||
ALLOC_STATE( ucp[3], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-3", 3 );
|
||||
ALLOC_STATE( ucp[4], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-4", 4 );
|
||||
ALLOC_STATE( ucp[5], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-5", 5 );
|
||||
ALLOC_STATE( lit[0], tcl_light, LIT_STATE_SIZE, "LIT/light-0", 0 );
|
||||
ALLOC_STATE( lit[1], tcl_light, LIT_STATE_SIZE, "LIT/light-1", 1 );
|
||||
ALLOC_STATE( lit[2], tcl_light, LIT_STATE_SIZE, "LIT/light-2", 2 );
|
||||
ALLOC_STATE( lit[3], tcl_light, LIT_STATE_SIZE, "LIT/light-3", 3 );
|
||||
ALLOC_STATE( lit[4], tcl_light, LIT_STATE_SIZE, "LIT/light-4", 4 );
|
||||
ALLOC_STATE( lit[5], tcl_light, LIT_STATE_SIZE, "LIT/light-5", 5 );
|
||||
ALLOC_STATE( lit[6], tcl_light, LIT_STATE_SIZE, "LIT/light-6", 6 );
|
||||
ALLOC_STATE( lit[7], tcl_light, LIT_STATE_SIZE, "LIT/light-7", 7 );
|
||||
ALLOC_STATE( pix[0], always, PIX_STATE_SIZE, "PIX/pixstage-0", 0 );
|
||||
ALLOC_STATE( pix[1], tex, PIX_STATE_SIZE, "PIX/pixstage-1", 1 );
|
||||
|
||||
|
||||
/* Fill in the packet headers:
|
||||
*/
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC);
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL);
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH);
|
||||
rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN);
|
||||
rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH);
|
||||
rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK);
|
||||
rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE);
|
||||
rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL);
|
||||
rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC);
|
||||
rmesa->hw.cst.cmd[CST_CMD_0] = cmdpkt(R200_EMIT_PP_CNTL_X);
|
||||
rmesa->hw.cst.cmd[CST_CMD_1] = cmdpkt(R200_EMIT_RB3D_DEPTHXY_OFFSET);
|
||||
rmesa->hw.cst.cmd[CST_CMD_2] = cmdpkt(R200_EMIT_RE_AUX_SCISSOR_CNTL);
|
||||
rmesa->hw.cst.cmd[CST_CMD_3] = cmdpkt(R200_EMIT_RE_SCISSOR_TL_0);
|
||||
rmesa->hw.cst.cmd[CST_CMD_4] = cmdpkt(R200_EMIT_SE_VAP_CNTL_STATUS);
|
||||
rmesa->hw.cst.cmd[CST_CMD_5] = cmdpkt(R200_EMIT_RE_POINTSIZE);
|
||||
rmesa->hw.cst.cmd[CST_CMD_6] = cmdpkt(R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0);
|
||||
rmesa->hw.tam.cmd[TAM_CMD_0] = cmdpkt(R200_EMIT_PP_TAM_DEBUG3);
|
||||
rmesa->hw.tf.cmd[TF_CMD_0] = cmdpkt(R200_EMIT_TFACTOR_0);
|
||||
rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_0);
|
||||
rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_0);
|
||||
rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_1);
|
||||
rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_1);
|
||||
rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_0);
|
||||
rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_0);
|
||||
rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_1);
|
||||
rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_1);
|
||||
rmesa->hw.pix[0].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_0);
|
||||
rmesa->hw.pix[1].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_1);
|
||||
rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR);
|
||||
rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(R200_EMIT_TCL_LIGHT_MODEL_CTL_0);
|
||||
rmesa->hw.tcl.cmd[TCL_CMD_1] = cmdpkt(R200_EMIT_TCL_UCP_VERT_BLEND_CTL);
|
||||
rmesa->hw.tcg.cmd[TCG_CMD_0] = cmdpkt(R200_EMIT_TEX_PROC_CTL_2);
|
||||
rmesa->hw.msl.cmd[MSL_CMD_0] = cmdpkt(R200_EMIT_MATRIX_SELECT_0);
|
||||
rmesa->hw.vap.cmd[VAP_CMD_0] = cmdpkt(R200_EMIT_VAP_CTL);
|
||||
rmesa->hw.vtx.cmd[VTX_CMD_0] = cmdpkt(R200_EMIT_VTX_FMT_0);
|
||||
rmesa->hw.vtx.cmd[VTX_CMD_1] = cmdpkt(R200_EMIT_OUTPUT_VTX_COMP_SEL);
|
||||
rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(R200_EMIT_SE_VTX_STATE_CNTL);
|
||||
rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(R200_EMIT_VTE_CNTL);
|
||||
rmesa->hw.mtl[0].cmd[MTL_CMD_0] =
|
||||
cmdvec( R200_VS_MAT_0_EMISS, 1, 16 );
|
||||
rmesa->hw.mtl[0].cmd[MTL_CMD_1] =
|
||||
cmdscl2( R200_SS_MAT_0_SHININESS, 1, 1 );
|
||||
rmesa->hw.grd.cmd[GRD_CMD_0] =
|
||||
cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 );
|
||||
rmesa->hw.fog.cmd[FOG_CMD_0] =
|
||||
cmdvec( R200_VS_FOG_PARAM_ADDR, 1, 4 );
|
||||
rmesa->hw.glt.cmd[GLT_CMD_0] =
|
||||
cmdvec( R200_VS_GLOBAL_AMBIENT_ADDR, 1, 4 );
|
||||
rmesa->hw.eye.cmd[EYE_CMD_0] =
|
||||
cmdvec( R200_VS_EYE_VECTOR_ADDR, 1, 4 );
|
||||
|
||||
rmesa->hw.mat[R200_MTX_MV].cmd[MAT_CMD_0] =
|
||||
cmdvec( R200_VS_MATRIX_0_MV, 1, 16);
|
||||
rmesa->hw.mat[R200_MTX_IMV].cmd[MAT_CMD_0] =
|
||||
cmdvec( R200_VS_MATRIX_1_INV_MV, 1, 16);
|
||||
rmesa->hw.mat[R200_MTX_MVP].cmd[MAT_CMD_0] =
|
||||
cmdvec( R200_VS_MATRIX_2_MVP, 1, 16);
|
||||
rmesa->hw.mat[R200_MTX_TEX0].cmd[MAT_CMD_0] =
|
||||
cmdvec( R200_VS_MATRIX_3_TEX0, 1, 16);
|
||||
rmesa->hw.mat[R200_MTX_TEX1].cmd[MAT_CMD_0] =
|
||||
cmdvec( R200_VS_MATRIX_4_TEX1, 1, 16);
|
||||
|
||||
for (i = 0 ; i < 8; i++) {
|
||||
rmesa->hw.lit[i].cmd[LIT_CMD_0] =
|
||||
cmdvec( R200_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 );
|
||||
rmesa->hw.lit[i].cmd[LIT_CMD_1] =
|
||||
cmdscl( R200_SS_LIGHT_DCD_ADDR + i, 8, 7 );
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 6; i++) {
|
||||
rmesa->hw.ucp[i].cmd[UCP_CMD_0] =
|
||||
cmdvec( R200_VS_UCP_ADDR + i, 1, 4 );
|
||||
}
|
||||
|
||||
/* Initial Harware state:
|
||||
*/
|
||||
rmesa->hw.ctx.cmd[CTX_PP_MISC] = (R200_ALPHA_TEST_PASS
|
||||
/* | R200_RIGHT_HAND_CUBE_OGL*/);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (R200_FOG_VERTEX |
|
||||
R200_FOG_USE_SPEC_ALPHA);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP |
|
||||
R200_SRC_BLEND_GL_ONE |
|
||||
R200_DST_BLEND_GL_ZERO );
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] =
|
||||
rmesa->r200Screen->depthOffset;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] =
|
||||
((rmesa->r200Screen->depthPitch &
|
||||
R200_DEPTHPITCH_MASK) |
|
||||
R200_DEPTH_ENDIAN_NO_SWAP);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt |
|
||||
R200_Z_TEST_LESS |
|
||||
R200_STENCIL_TEST_ALWAYS |
|
||||
R200_STENCIL_FAIL_KEEP |
|
||||
R200_STENCIL_ZPASS_KEEP |
|
||||
R200_STENCIL_ZFAIL_KEEP |
|
||||
R200_Z_WRITE_ENABLE);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (R200_ANTI_ALIAS_NONE
|
||||
| R200_TEX_BLEND_0_ENABLE);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = color_fmt;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset &
|
||||
R200_COLOROFFSET_MASK);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
|
||||
R200_COLORPITCH_MASK) |
|
||||
R200_COLOR_ENDIAN_NO_SWAP);
|
||||
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW |
|
||||
R200_BFACE_SOLID |
|
||||
R200_FFACE_SOLID |
|
||||
R200_FLAT_SHADE_VTX_LAST |
|
||||
R200_DIFFUSE_SHADE_GOURAUD |
|
||||
R200_ALPHA_SHADE_GOURAUD |
|
||||
R200_SPECULAR_SHADE_GOURAUD |
|
||||
R200_FOG_SHADE_GOURAUD |
|
||||
R200_VTX_PIX_CENTER_OGL |
|
||||
R200_ROUND_MODE_TRUNC |
|
||||
R200_ROUND_PREC_8TH_PIX);
|
||||
|
||||
rmesa->hw.set.cmd[SET_RE_CNTL] = (R200_PERSPECTIVE_ENABLE |
|
||||
R200_SCISSOR_ENABLE);
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff);
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] =
|
||||
((0 << R200_LINE_CURRENT_PTR_SHIFT) |
|
||||
(1 << R200_LINE_CURRENT_COUNT_SHIFT));
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4);
|
||||
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] =
|
||||
((0x00 << R200_STENCIL_REF_SHIFT) |
|
||||
(0xff << R200_STENCIL_MASK_SHIFT) |
|
||||
(0xff << R200_STENCIL_WRITEMASK_SHIFT));
|
||||
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = R200_ROP_COPY;
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff;
|
||||
|
||||
rmesa->hw.tam.cmd[TAM_DEBUG3] = 0;
|
||||
|
||||
rmesa->hw.msc.cmd[MSC_RE_MISC] =
|
||||
((0 << R200_STIPPLE_X_OFFSET_SHIFT) |
|
||||
(0 << R200_STIPPLE_Y_OFFSET_SHIFT) |
|
||||
R200_STIPPLE_BIG_BIT_ORDER);
|
||||
|
||||
|
||||
rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
|
||||
rmesa->hw.cst.cmd[CST_RB3D_DEPTHXY_OFFSET] = 0;
|
||||
rmesa->hw.cst.cmd[CST_RE_AUX_SCISSOR_CNTL] = 0x0;
|
||||
rmesa->hw.cst.cmd[CST_RE_SCISSOR_TL_0] = 0;
|
||||
rmesa->hw.cst.cmd[CST_RE_SCISSOR_BR_0] = 0;
|
||||
rmesa->hw.cst.cmd[CST_SE_VAP_CNTL_STATUS] =
|
||||
#ifdef MESA_BIG_ENDIAN
|
||||
R200_VC_32BIT_SWAP;
|
||||
#else
|
||||
R200_VC_NO_SWAP;
|
||||
#endif
|
||||
rmesa->hw.cst.cmd[CST_RE_POINTSIZE] = 0x100010;
|
||||
rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_0] =
|
||||
(0x0 << R200_VERTEX_POSITION_ADDR__SHIFT);
|
||||
rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_1] =
|
||||
(0x02 << R200_VTX_COLOR_0_ADDR__SHIFT) |
|
||||
(0x03 << R200_VTX_COLOR_1_ADDR__SHIFT);
|
||||
rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_2] =
|
||||
(0x06 << R200_VTX_TEX_0_ADDR__SHIFT) |
|
||||
(0x07 << R200_VTX_TEX_1_ADDR__SHIFT) |
|
||||
(0x08 << R200_VTX_TEX_2_ADDR__SHIFT) |
|
||||
(0x09 << R200_VTX_TEX_3_ADDR__SHIFT);
|
||||
rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_3] =
|
||||
(0x0A << R200_VTX_TEX_4_ADDR__SHIFT) |
|
||||
(0x0B << R200_VTX_TEX_5_ADDR__SHIFT);
|
||||
|
||||
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000;
|
||||
|
||||
for (i = 0; i < 2; i++) { /* 2 texture units for now */
|
||||
rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] = R200_BORDER_MODE_OGL;
|
||||
rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT] =
|
||||
((i << R200_TXFORMAT_ST_ROUTE_SHIFT) | /* <-- note i */
|
||||
(2 << R200_TXFORMAT_WIDTH_SHIFT) |
|
||||
(2 << R200_TXFORMAT_HEIGHT_SHIFT));
|
||||
rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = 0;
|
||||
rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0;
|
||||
rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT_X] =
|
||||
(/* R200_TEXCOORD_PROJ | */
|
||||
0x100000); /* Small default bias */
|
||||
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0;
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F1] = 0;
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F2] = 0;
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F3] = 0;
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F4] = 0;
|
||||
rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_F5] = 0;
|
||||
}
|
||||
|
||||
rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND] =
|
||||
(R200_TXC_ARG_A_ZERO |
|
||||
R200_TXC_ARG_B_ZERO |
|
||||
R200_TXC_ARG_C_DIFFUSE_COLOR |
|
||||
R200_TXC_OP_MADD);
|
||||
|
||||
rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND2] =
|
||||
((0 << R200_TXC_TFACTOR_SEL_SHIFT) |
|
||||
R200_TXC_SCALE_1X |
|
||||
R200_TXC_CLAMP_0_1 |
|
||||
R200_TXC_OUTPUT_REG_R0);
|
||||
|
||||
rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND] =
|
||||
(R200_TXA_ARG_A_ZERO |
|
||||
R200_TXA_ARG_B_ZERO |
|
||||
R200_TXA_ARG_C_DIFFUSE_ALPHA |
|
||||
R200_TXA_OP_MADD);
|
||||
|
||||
rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND2] =
|
||||
((0 << R200_TXA_TFACTOR_SEL_SHIFT) |
|
||||
R200_TXA_SCALE_1X |
|
||||
R200_TXA_CLAMP_0_1 |
|
||||
R200_TXA_OUTPUT_REG_R0);
|
||||
|
||||
rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND] =
|
||||
(R200_TXC_ARG_A_ZERO |
|
||||
R200_TXC_ARG_B_ZERO |
|
||||
R200_TXC_ARG_C_DIFFUSE_COLOR |
|
||||
R200_TXC_OP_MADD);
|
||||
|
||||
rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND2] =
|
||||
((0 << R200_TXC_TFACTOR_SEL_SHIFT) |
|
||||
R200_TXC_SCALE_1X |
|
||||
R200_TXC_CLAMP_0_1 |
|
||||
R200_TXC_OUTPUT_REG_R0);
|
||||
|
||||
rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND] =
|
||||
(R200_TXA_ARG_A_ZERO |
|
||||
R200_TXA_ARG_B_ZERO |
|
||||
R200_TXA_ARG_C_DIFFUSE_ALPHA |
|
||||
R200_TXA_OP_MADD);
|
||||
|
||||
rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND2] =
|
||||
((0 << R200_TXA_TFACTOR_SEL_SHIFT) |
|
||||
R200_TXA_SCALE_1X |
|
||||
R200_TXA_CLAMP_0_1 |
|
||||
R200_TXA_OUTPUT_REG_R0);
|
||||
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_0] = 0;
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_1] = 0;
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_2] = 0;
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_3] = 0;
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_4] = 0;
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_5] = 0;
|
||||
|
||||
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] =
|
||||
(R200_VAP_TCL_ENABLE |
|
||||
(0x9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT));
|
||||
|
||||
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] =
|
||||
(R200_VPORT_X_SCALE_ENA |
|
||||
R200_VPORT_Y_SCALE_ENA |
|
||||
R200_VPORT_Z_SCALE_ENA |
|
||||
R200_VPORT_X_OFFSET_ENA |
|
||||
R200_VPORT_Y_OFFSET_ENA |
|
||||
R200_VPORT_Z_OFFSET_ENA |
|
||||
/* FIXME: Turn on for tex rect only */
|
||||
R200_VTX_ST_DENORMALIZED |
|
||||
R200_VTX_W0_FMT);
|
||||
|
||||
|
||||
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = 0;
|
||||
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = 0;
|
||||
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] =
|
||||
((R200_VTX_Z0 | R200_VTX_W0 |
|
||||
(R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)));
|
||||
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] = 0;
|
||||
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = (R200_OUTPUT_XYZW);
|
||||
rmesa->hw.vtx.cmd[VTX_STATE_CNTL] = R200_VSC_UPDATE_USER_COLOR_0_ENABLE;
|
||||
|
||||
|
||||
/* Matrix selection */
|
||||
rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_0] =
|
||||
(R200_MTX_MV << R200_MODELVIEW_0_SHIFT);
|
||||
|
||||
rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_1] =
|
||||
(R200_MTX_IMV << R200_IT_MODELVIEW_0_SHIFT);
|
||||
|
||||
rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_2] =
|
||||
(R200_MTX_MVP << R200_MODELPROJECT_0_SHIFT);
|
||||
|
||||
rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_3] =
|
||||
((R200_MTX_TEX0 << R200_TEXMAT_0_SHIFT) |
|
||||
(R200_MTX_TEX1 << R200_TEXMAT_1_SHIFT) |
|
||||
(R200_MTX_TEX2 << R200_TEXMAT_2_SHIFT) |
|
||||
(R200_MTX_TEX3 << R200_TEXMAT_3_SHIFT));
|
||||
|
||||
rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_4] =
|
||||
((R200_MTX_TEX4 << R200_TEXMAT_4_SHIFT) |
|
||||
(R200_MTX_TEX5 << R200_TEXMAT_5_SHIFT));
|
||||
|
||||
|
||||
/* General TCL state */
|
||||
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] =
|
||||
(R200_SPECULAR_LIGHTS |
|
||||
R200_DIFFUSE_SPECULAR_COMBINE |
|
||||
R200_LOCAL_LIGHT_VEC_GL);
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] =
|
||||
((R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_AMBIENT_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
|
||||
(R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_SPECULAR_SOURCE_SHIFT));
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_0] = 0; /* filled in via callbacks */
|
||||
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_1] = 0;
|
||||
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_2] = 0;
|
||||
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_3] = 0;
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] =
|
||||
(R200_UCP_IN_CLIP_SPACE |
|
||||
R200_CULL_FRONT_IS_CCW);
|
||||
|
||||
/* Texgen/Texmat state */
|
||||
rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x0; /* masks??? */
|
||||
rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_3] =
|
||||
((0 << R200_TEXGEN_0_INPUT_TEX_SHIFT) |
|
||||
(1 << R200_TEXGEN_1_INPUT_TEX_SHIFT) |
|
||||
(2 << R200_TEXGEN_2_INPUT_TEX_SHIFT) |
|
||||
(3 << R200_TEXGEN_3_INPUT_TEX_SHIFT) |
|
||||
(4 << R200_TEXGEN_4_INPUT_TEX_SHIFT) |
|
||||
(5 << R200_TEXGEN_5_INPUT_TEX_SHIFT));
|
||||
rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = 0;
|
||||
rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] =
|
||||
((0 << R200_TEXGEN_0_INPUT_SHIFT) |
|
||||
(1 << R200_TEXGEN_1_INPUT_SHIFT) |
|
||||
(2 << R200_TEXGEN_2_INPUT_SHIFT) |
|
||||
(3 << R200_TEXGEN_3_INPUT_SHIFT) |
|
||||
(4 << R200_TEXGEN_4_INPUT_SHIFT) |
|
||||
(5 << R200_TEXGEN_5_INPUT_SHIFT));
|
||||
rmesa->hw.tcg.cmd[TCG_TEX_CYL_WRAP_CTL] = 0;
|
||||
|
||||
rmesa->TexGenInputs = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1];
|
||||
|
||||
|
||||
for (i = 0 ; i < 8; i++) {
|
||||
struct gl_light *l = &ctx->Light.Light[i];
|
||||
GLenum p = GL_LIGHT0 + i;
|
||||
*(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX;
|
||||
|
||||
ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION,
|
||||
&l->ConstantAttenuation );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION,
|
||||
&l->LinearAttenuation );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION,
|
||||
&l->QuadraticAttenuation );
|
||||
}
|
||||
|
||||
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT,
|
||||
ctx->Light.Model.Ambient );
|
||||
|
||||
TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
|
||||
|
||||
for (i = 0 ; i < 6; i++) {
|
||||
ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL );
|
||||
}
|
||||
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 );
|
||||
|
||||
rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE;
|
||||
|
||||
rmesa->hw.eye.cmd[EYE_X] = 0;
|
||||
rmesa->hw.eye.cmd[EYE_Y] = 0;
|
||||
rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE;
|
||||
rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE;
|
||||
|
||||
r200LightingSpaceChange( ctx );
|
||||
|
||||
rmesa->lost_context = 1;
|
||||
}
|
||||
1286
src/mesa/drivers/dri/r200/r200_swtcl.c
Normal file
1286
src/mesa/drivers/dri/r200/r200_swtcl.c
Normal file
File diff suppressed because it is too large
Load Diff
80
src/mesa/drivers/dri/r200/r200_swtcl.h
Normal file
80
src/mesa/drivers/dri/r200/r200_swtcl.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_SWTCL_H__
|
||||
#define __R200_SWTCL_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200InitSwtcl( GLcontext *ctx );
|
||||
extern void r200DestroySwtcl( GLcontext *ctx );
|
||||
|
||||
extern void r200FlushVertices( GLcontext *ctx, GLuint flags );
|
||||
extern void r200ChooseRenderState( GLcontext *ctx );
|
||||
extern void r200ChooseVertexState( GLcontext *ctx );
|
||||
|
||||
extern void r200CheckTexSizes( GLcontext *ctx );
|
||||
|
||||
extern void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count,
|
||||
GLuint newinputs );
|
||||
|
||||
extern void r200PrintSetupFlags(char *msg, GLuint flags );
|
||||
|
||||
|
||||
extern void r200_emit_contiguous_verts( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count );
|
||||
|
||||
extern void r200_emit_indexed_verts( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count );
|
||||
|
||||
extern void r200_translate_vertex( GLcontext *ctx,
|
||||
const r200Vertex *src,
|
||||
SWvertex *dst );
|
||||
|
||||
extern void r200_print_vertex( GLcontext *ctx, const r200Vertex *v );
|
||||
|
||||
extern void r200_import_float_colors( GLcontext *ctx );
|
||||
extern void r200_import_float_spec_colors( GLcontext *ctx );
|
||||
|
||||
extern void r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
|
||||
GLsizei width, GLsizei height,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLubyte *bitmap );
|
||||
|
||||
|
||||
#endif
|
||||
555
src/mesa/drivers/dri/r200/r200_tcl.c
Normal file
555
src/mesa/drivers/dri/r200/r200_tcl.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "mtypes.h"
|
||||
#include "enums.h"
|
||||
#include "colormac.h"
|
||||
#include "light.h"
|
||||
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_maos.h"
|
||||
|
||||
|
||||
|
||||
#define HAVE_POINTS 1
|
||||
#define HAVE_LINES 1
|
||||
#define HAVE_LINE_LOOP 0
|
||||
#define HAVE_LINE_STRIPS 1
|
||||
#define HAVE_TRIANGLES 1
|
||||
#define HAVE_TRI_STRIPS 1
|
||||
#define HAVE_TRI_STRIP_1 0
|
||||
#define HAVE_TRI_FANS 1
|
||||
#define HAVE_QUADS 0 /* hw quad verts in wrong order??? */
|
||||
#define HAVE_QUAD_STRIPS 1
|
||||
#define HAVE_POLYGONS 1
|
||||
#define HAVE_ELTS 1
|
||||
|
||||
|
||||
#define HW_POINTS R200_VF_PRIM_POINTS
|
||||
#define HW_LINES R200_VF_PRIM_LINES
|
||||
#define HW_LINE_LOOP 0
|
||||
#define HW_LINE_STRIP R200_VF_PRIM_LINE_STRIP
|
||||
#define HW_TRIANGLES R200_VF_PRIM_TRIANGLES
|
||||
#define HW_TRIANGLE_STRIP_0 R200_VF_PRIM_TRIANGLE_STRIP
|
||||
#define HW_TRIANGLE_STRIP_1 0
|
||||
#define HW_TRIANGLE_FAN R200_VF_PRIM_TRIANGLE_FAN
|
||||
#define HW_QUADS R200_VF_PRIM_QUADS
|
||||
#define HW_QUAD_STRIP R200_VF_PRIM_QUAD_STRIP
|
||||
#define HW_POLYGON R200_VF_PRIM_POLYGON
|
||||
|
||||
|
||||
static GLboolean discrete_prim[0x10] = {
|
||||
0, /* 0 none */
|
||||
1, /* 1 points */
|
||||
1, /* 2 lines */
|
||||
0, /* 3 line_strip */
|
||||
1, /* 4 tri_list */
|
||||
0, /* 5 tri_fan */
|
||||
0, /* 6 tri_strip */
|
||||
0, /* 7 tri_w_flags */
|
||||
1, /* 8 rect list (unused) */
|
||||
1, /* 9 3vert point */
|
||||
1, /* a 3vert line */
|
||||
0, /* b point sprite */
|
||||
0, /* c line loop */
|
||||
1, /* d quads */
|
||||
0, /* e quad strip */
|
||||
0, /* f polygon */
|
||||
};
|
||||
|
||||
|
||||
#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
|
||||
#define ELTS_VARS GLushort *dest
|
||||
|
||||
#define ELT_INIT(prim, hw_prim) \
|
||||
r200TclPrimitive( ctx, prim, hw_prim | R200_VF_PRIM_WALK_IND )
|
||||
|
||||
#define GET_ELTS() rmesa->tcl.Elts
|
||||
|
||||
|
||||
#define NEW_PRIMITIVE() R200_NEWPRIM( rmesa )
|
||||
#define NEW_BUFFER() r200RefillCurrentDmaRegion( rmesa )
|
||||
|
||||
/* Don't really know how many elts will fit in what's left of cmdbuf,
|
||||
* as there is state to emit, etc:
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define GET_CURRENT_VB_MAX_ELTS() \
|
||||
((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
|
||||
#define GET_SUBSEQUENT_VB_MAX_ELTS() ((R200_CMD_BUF_SZ - 16) / 2)
|
||||
#else
|
||||
/* Testing on isosurf shows a maximum around here. Don't know if it's
|
||||
* the card or driver or kernel module that is causing the behaviour.
|
||||
*/
|
||||
#define GET_CURRENT_VB_MAX_ELTS() 300
|
||||
#define GET_SUBSEQUENT_VB_MAX_ELTS() 300
|
||||
#endif
|
||||
|
||||
#define RESET_STIPPLE() do { \
|
||||
R200_STATECHANGE( rmesa, lin ); \
|
||||
r200EmitState( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
#define AUTO_STIPPLE( mode ) do { \
|
||||
R200_STATECHANGE( rmesa, lin ); \
|
||||
if (mode) \
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \
|
||||
R200_LINE_PATTERN_AUTO_RESET; \
|
||||
else \
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \
|
||||
~R200_LINE_PATTERN_AUTO_RESET; \
|
||||
r200EmitState( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* How do you extend an existing primitive?
|
||||
*/
|
||||
#define ALLOC_ELTS(nr) \
|
||||
do { \
|
||||
if (rmesa->dma.flush == r200FlushElts && \
|
||||
rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) { \
|
||||
\
|
||||
dest = (GLushort *)(rmesa->store.cmd_buf + \
|
||||
rmesa->store.cmd_used); \
|
||||
rmesa->store.cmd_used += nr*2; \
|
||||
} \
|
||||
else { \
|
||||
if (rmesa->dma.flush) \
|
||||
rmesa->dma.flush( rmesa ); \
|
||||
\
|
||||
r200EmitAOS( rmesa, \
|
||||
rmesa->tcl.aos_components, \
|
||||
rmesa->tcl.nr_aos_components, \
|
||||
0 ); \
|
||||
\
|
||||
dest = r200AllocEltsOpenEnded( rmesa, \
|
||||
rmesa->tcl.hw_primitive, \
|
||||
nr ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/* TODO: Try to extend existing primitive if both are identical,
|
||||
* discrete and there are no intervening state changes. (Somewhat
|
||||
* duplicates changes to DrawArrays code)
|
||||
*/
|
||||
static void EMIT_PRIM( GLcontext *ctx,
|
||||
GLenum prim,
|
||||
GLuint hwprim,
|
||||
GLuint start,
|
||||
GLuint count)
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT( ctx );
|
||||
r200TclPrimitive( ctx, prim, hwprim );
|
||||
|
||||
r200EmitAOS( rmesa,
|
||||
rmesa->tcl.aos_components,
|
||||
rmesa->tcl.nr_aos_components,
|
||||
start );
|
||||
|
||||
/* Why couldn't this packet have taken an offset param?
|
||||
*/
|
||||
r200EmitVbufPrim( rmesa,
|
||||
rmesa->tcl.hw_primitive,
|
||||
count - start );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Try & join small primitives
|
||||
*/
|
||||
#if 0
|
||||
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0
|
||||
#else
|
||||
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) \
|
||||
((NR) < 20 || \
|
||||
((NR) < 40 && \
|
||||
rmesa->tcl.hw_primitive == (PRIM| \
|
||||
R200_VF_TCL_OUTPUT_VTX_ENABLE| \
|
||||
R200_VF_PRIM_WALK_IND)))
|
||||
#endif
|
||||
|
||||
#ifdef MESA_BIG_ENDIAN
|
||||
/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
|
||||
#define EMIT_ELT(offset, x) do { \
|
||||
int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
|
||||
GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
|
||||
(des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
|
||||
#else
|
||||
#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
|
||||
#endif
|
||||
#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
|
||||
#define INCR_ELTS( nr ) dest += nr
|
||||
#define RELEASE_ELT_VERTS() \
|
||||
r200ReleaseArrays( ctx, ~0 )
|
||||
|
||||
|
||||
|
||||
#define TAG(x) tcl_##x
|
||||
#include "tnl_dd/t_dd_dmatmp2.h"
|
||||
|
||||
/**********************************************************************/
|
||||
/* External entrypoints */
|
||||
/**********************************************************************/
|
||||
|
||||
void r200EmitPrimitive( GLcontext *ctx,
|
||||
GLuint first,
|
||||
GLuint last,
|
||||
GLuint flags )
|
||||
{
|
||||
tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
|
||||
}
|
||||
|
||||
void r200EmitEltPrimitive( GLcontext *ctx,
|
||||
GLuint first,
|
||||
GLuint last,
|
||||
GLuint flags )
|
||||
{
|
||||
tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
|
||||
}
|
||||
|
||||
void r200TclPrimitive( GLcontext *ctx,
|
||||
GLenum prim,
|
||||
int hw_prim )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE;
|
||||
|
||||
if (newprim != rmesa->tcl.hw_primitive ||
|
||||
!discrete_prim[hw_prim&0xf]) {
|
||||
R200_NEWPRIM( rmesa );
|
||||
rmesa->tcl.hw_primitive = newprim;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Render pipeline stage */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/* TCL render.
|
||||
*/
|
||||
static GLboolean r200_run_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i,flags = 0,length;
|
||||
|
||||
/* TODO: separate this from the swtnl pipeline
|
||||
*/
|
||||
if (rmesa->TclFallback)
|
||||
return GL_TRUE; /* fallback to software t&l */
|
||||
|
||||
if (R200_DEBUG & DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (VB->Count == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
r200ReleaseArrays( ctx, stage->changed_inputs );
|
||||
r200EmitArrays( ctx, stage->inputs );
|
||||
|
||||
rmesa->tcl.Elts = VB->Elts;
|
||||
|
||||
for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
|
||||
{
|
||||
flags = VB->Primitive[i];
|
||||
length = VB->PrimitiveLength[i];
|
||||
|
||||
if (R200_DEBUG & DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s: prim %s %d..%d\n",
|
||||
__FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK),
|
||||
i, i+length);
|
||||
|
||||
if (!length)
|
||||
continue;
|
||||
|
||||
if (rmesa->tcl.Elts)
|
||||
r200EmitEltPrimitive( ctx, i, i+length, flags );
|
||||
else
|
||||
r200EmitPrimitive( ctx, i, i+length, flags );
|
||||
}
|
||||
|
||||
return GL_FALSE; /* finished the pipe */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void r200_check_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint inputs = VERT_BIT_POS;
|
||||
|
||||
/* Validate state:
|
||||
*/
|
||||
if (rmesa->NewGLState)
|
||||
r200ValidateState( ctx );
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s: RE %d TGE %d NN %d\n",
|
||||
__FUNCTION__,
|
||||
ctx->Texture.Unit[0]._ReallyEnabled,
|
||||
ctx->Texture.Unit[0].TexGenEnabled,
|
||||
rmesa->TexGenNeedNormals[0]);
|
||||
|
||||
if (ctx->RenderMode == GL_RENDER) {
|
||||
/* Make all this event-driven:
|
||||
*/
|
||||
if (ctx->Light.Enabled) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
|
||||
if (ctx->Light.ColorMaterialEnabled) {
|
||||
inputs |= VERT_BIT_COLOR0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
inputs |= VERT_BIT_COLOR0;
|
||||
|
||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
|
||||
inputs |= VERT_BIT_COLOR1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[0].TexGenEnabled) {
|
||||
if (rmesa->TexGenNeedNormals[0]) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
inputs |= VERT_BIT_TEX0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[1].TexGenEnabled) {
|
||||
if (rmesa->TexGenNeedNormals[1]) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
inputs |= VERT_BIT_TEX1;
|
||||
}
|
||||
}
|
||||
|
||||
stage->inputs = inputs;
|
||||
stage->active = 1;
|
||||
}
|
||||
else
|
||||
stage->active = 0;
|
||||
}
|
||||
|
||||
static void r200_init_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
stage->check = r200_check_tcl_render;
|
||||
stage->check( ctx, stage );
|
||||
}
|
||||
|
||||
static void dtr( struct gl_pipeline_stage *stage )
|
||||
{
|
||||
(void)stage;
|
||||
}
|
||||
|
||||
|
||||
/* Initial state for tcl stage.
|
||||
*/
|
||||
const struct gl_pipeline_stage _r200_tcl_stage =
|
||||
{
|
||||
"r200 render",
|
||||
(_DD_NEW_SEPARATE_SPECULAR |
|
||||
_NEW_LIGHT|
|
||||
_NEW_TEXTURE|
|
||||
_NEW_FOG|
|
||||
_NEW_RENDERMODE), /* re-check (new inputs) */
|
||||
0, /* re-run (always runs) */
|
||||
GL_TRUE, /* active */
|
||||
0, 0, /* inputs (set in check_render), outputs */
|
||||
0, 0, /* changed_inputs, private */
|
||||
dtr, /* destructor */
|
||||
r200_init_tcl_render, /* check - initially set to alloc data */
|
||||
r200_run_tcl_render /* run */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Validate state at pipeline start */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Manage TCL fallbacks
|
||||
*/
|
||||
|
||||
|
||||
static void transition_to_swtnl( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
|
||||
R200_NEWPRIM( rmesa );
|
||||
rmesa->swtcl.vertex_format = 0;
|
||||
|
||||
r200ChooseVertexState( ctx );
|
||||
r200ChooseRenderState( ctx );
|
||||
|
||||
_mesa_validate_all_lighting_tables( ctx );
|
||||
|
||||
tnl->Driver.NotifyMaterialChange =
|
||||
_mesa_validate_all_lighting_tables;
|
||||
|
||||
r200ReleaseArrays( ctx, ~0 );
|
||||
|
||||
/* Still using the D3D based hardware-rasterizer from the radeon;
|
||||
* need to put the card into D3D mode to make it work:
|
||||
*/
|
||||
R200_STATECHANGE( rmesa, vap );
|
||||
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE;
|
||||
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_D3D_TEX_DEFAULT;
|
||||
|
||||
R200_STATECHANGE( rmesa, vte );
|
||||
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~R200_VTX_W0_FMT;
|
||||
|
||||
R200_STATECHANGE( rmesa, set );
|
||||
rmesa->hw.set.cmd[SET_RE_CNTL] |= (R200_VTX_STQ0_D3D |
|
||||
R200_VTX_STQ1_D3D);
|
||||
}
|
||||
|
||||
|
||||
static void transition_to_hwtnl( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
|
||||
_tnl_need_projected_coords( ctx, GL_FALSE );
|
||||
|
||||
r200UpdateMaterial( ctx );
|
||||
|
||||
tnl->Driver.NotifyMaterialChange = r200UpdateMaterial;
|
||||
|
||||
if ( rmesa->dma.flush )
|
||||
rmesa->dma.flush( rmesa );
|
||||
|
||||
rmesa->dma.flush = 0;
|
||||
rmesa->swtcl.vertex_format = 0;
|
||||
|
||||
if (rmesa->swtcl.indexed_verts.buf)
|
||||
r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
|
||||
__FUNCTION__ );
|
||||
|
||||
R200_STATECHANGE( rmesa, vap );
|
||||
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
|
||||
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_FORCE_W_TO_ONE |
|
||||
R200_VAP_D3D_TEX_DEFAULT);
|
||||
|
||||
R200_STATECHANGE( rmesa, vte );
|
||||
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
|
||||
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
|
||||
|
||||
R200_STATECHANGE( rmesa, set );
|
||||
rmesa->hw.set.cmd[SET_RE_CNTL] &= ~(R200_VTX_STQ0_D3D |
|
||||
R200_VTX_STQ1_D3D);
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "R200 end tcl fallback\n");
|
||||
}
|
||||
|
||||
|
||||
static char *fallbackStrings[] = {
|
||||
"Rasterization fallback",
|
||||
"Unfilled triangles",
|
||||
"Twosided lighting, differing materials",
|
||||
"Materials in VB (maybe between begin/end)",
|
||||
"Texgen unit 0",
|
||||
"Texgen unit 1",
|
||||
"Texgen unit 2",
|
||||
"User disable"
|
||||
};
|
||||
|
||||
|
||||
static char *getFallbackString(GLuint bit)
|
||||
{
|
||||
int i = 0;
|
||||
while (bit > 1) {
|
||||
i++;
|
||||
bit >>= 1;
|
||||
}
|
||||
return fallbackStrings[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint oldfallback = rmesa->TclFallback;
|
||||
|
||||
if (mode) {
|
||||
rmesa->TclFallback |= bit;
|
||||
if (oldfallback == 0) {
|
||||
if (R200_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "R200 begin tcl fallback %s\n",
|
||||
getFallbackString( bit ));
|
||||
transition_to_swtnl( ctx );
|
||||
}
|
||||
}
|
||||
else {
|
||||
rmesa->TclFallback &= ~bit;
|
||||
if (oldfallback == bit) {
|
||||
if (R200_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "R200 end tcl fallback %s\n",
|
||||
getFallbackString( bit ));
|
||||
transition_to_hwtnl( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/mesa/drivers/dri/r200/r200_tcl.h
Normal file
66
src/mesa/drivers/dri/r200/r200_tcl.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_TCL_H__
|
||||
#define __R200_TCL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200TclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim );
|
||||
extern void r200EmitEltPrimitive( GLcontext *ctx, GLuint first, GLuint last,
|
||||
GLuint flags );
|
||||
extern void r200EmitPrimitive( GLcontext *ctx, GLuint first, GLuint last,
|
||||
GLuint flags );
|
||||
|
||||
extern void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
|
||||
#define R200_TCL_FALLBACK_RASTER 0x1 /* rasterization */
|
||||
#define R200_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */
|
||||
#define R200_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */
|
||||
#define R200_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */
|
||||
#define R200_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */
|
||||
#define R200_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */
|
||||
#define R200_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */
|
||||
#define R200_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */
|
||||
#define R200_TCL_FALLBACK_BITMAP 0x100 /* draw bitmap with points */
|
||||
|
||||
#define R200_MAX_TCL_VERTSIZE (4*4) /* using maos now... */
|
||||
|
||||
#define TCL_FALLBACK( ctx, bit, mode ) r200TclFallback( ctx, bit, mode )
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
988
src/mesa/drivers/dri/r200/r200_tex.c
Normal file
988
src/mesa/drivers/dri/r200/r200_tex.c
Normal file
@@ -0,0 +1,988 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "colormac.h"
|
||||
#include "context.h"
|
||||
#include "enums.h"
|
||||
#include "image.h"
|
||||
#include "mmath.h"
|
||||
#include "simple_list.h"
|
||||
#include "texformat.h"
|
||||
#include "texstore.h"
|
||||
#include "texutil.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_tex.h"
|
||||
|
||||
|
||||
/* =============================================================
|
||||
* Utility functions:
|
||||
*/
|
||||
|
||||
static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap )
|
||||
{
|
||||
t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK);
|
||||
|
||||
switch ( swrap ) {
|
||||
case GL_REPEAT:
|
||||
t->pp_txfilter |= R200_CLAMP_S_WRAP;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
t->pp_txfilter |= R200_CLAMP_S_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT_ARB:
|
||||
t->pp_txfilter |= R200_CLAMP_S_MIRROR;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_ATI:
|
||||
t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE_ATI:
|
||||
t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_LAST;
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap");
|
||||
}
|
||||
|
||||
switch ( twrap ) {
|
||||
case GL_REPEAT:
|
||||
t->pp_txfilter |= R200_CLAMP_T_WRAP;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
t->pp_txfilter |= R200_CLAMP_T_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT_ARB:
|
||||
t->pp_txfilter |= R200_CLAMP_T_MIRROR;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_ATI:
|
||||
t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE_ATI:
|
||||
t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_LAST;
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap");
|
||||
}
|
||||
|
||||
t->pp_txformat_x &= ~R200_CLAMP_Q_MASK;
|
||||
|
||||
switch ( rwrap ) {
|
||||
case GL_REPEAT:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_WRAP;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT_ARB:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_ATI:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE_ATI:
|
||||
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST;
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "bad R wrap mode in r200SetTexWrap");
|
||||
}
|
||||
}
|
||||
|
||||
static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max )
|
||||
{
|
||||
t->pp_txfilter &= ~R200_MAX_ANISO_MASK;
|
||||
|
||||
if ( max == 1.0 ) {
|
||||
t->pp_txfilter |= R200_MAX_ANISO_1_TO_1;
|
||||
} else if ( max <= 2.0 ) {
|
||||
t->pp_txfilter |= R200_MAX_ANISO_2_TO_1;
|
||||
} else if ( max <= 4.0 ) {
|
||||
t->pp_txfilter |= R200_MAX_ANISO_4_TO_1;
|
||||
} else if ( max <= 8.0 ) {
|
||||
t->pp_txfilter |= R200_MAX_ANISO_8_TO_1;
|
||||
} else {
|
||||
t->pp_txfilter |= R200_MAX_ANISO_16_TO_1;
|
||||
}
|
||||
}
|
||||
|
||||
static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf )
|
||||
{
|
||||
GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK);
|
||||
|
||||
t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK);
|
||||
t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK;
|
||||
|
||||
if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) {
|
||||
switch ( minf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ( minf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_ANISO_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note we don't have 3D mipmaps so only use the mag filter setting
|
||||
* to set the 3D texture filter mode.
|
||||
*/
|
||||
switch ( magf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= R200_MAG_FILTER_NEAREST;
|
||||
t->pp_txformat_x |= R200_VOLUME_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= R200_MAG_FILTER_LINEAR;
|
||||
t->pp_txformat_x |= R200_VOLUME_FILTER_LINEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void r200SetTexBorderColor( r200TexObjPtr t, GLubyte c[4] )
|
||||
{
|
||||
t->pp_border_color = r200PackColor( 4, c[0], c[1], c[2], c[3] );
|
||||
}
|
||||
|
||||
|
||||
static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj )
|
||||
{
|
||||
r200TexObjPtr t;
|
||||
|
||||
t = CALLOC_STRUCT( r200_tex_obj );
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t );
|
||||
}
|
||||
|
||||
t->tObj = texObj;
|
||||
make_empty_list( t );
|
||||
|
||||
/* Initialize non-image-dependent parts of the state:
|
||||
*/
|
||||
r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR );
|
||||
r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
|
||||
r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
|
||||
r200SetTexBorderColor( t, texObj->_BorderChan );
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static const struct gl_texture_format *
|
||||
r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
|
||||
GLenum format, GLenum type )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
const GLboolean do32bpt = ( rmesa->r200Screen->cpp == 4 );
|
||||
|
||||
switch ( internalFormat ) {
|
||||
case 4:
|
||||
case GL_RGBA:
|
||||
if ( format == GL_BGRA ) {
|
||||
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
||||
return &_mesa_texformat_argb8888;
|
||||
}
|
||||
else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
|
||||
return &_mesa_texformat_argb4444;
|
||||
}
|
||||
else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
|
||||
return &_mesa_texformat_argb1555;
|
||||
}
|
||||
}
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444;
|
||||
|
||||
case 3:
|
||||
case GL_RGB:
|
||||
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
|
||||
return &_mesa_texformat_rgb565;
|
||||
}
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_RGBA8:
|
||||
case GL_RGB10_A2:
|
||||
case GL_RGBA12:
|
||||
case GL_RGBA16:
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444;
|
||||
|
||||
case GL_RGBA4:
|
||||
case GL_RGBA2:
|
||||
return &_mesa_texformat_argb4444;
|
||||
|
||||
case GL_RGB5_A1:
|
||||
return &_mesa_texformat_argb1555;
|
||||
|
||||
case GL_RGB8:
|
||||
case GL_RGB10:
|
||||
case GL_RGB12:
|
||||
case GL_RGB16:
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_RGB5:
|
||||
case GL_RGB4:
|
||||
case GL_R3_G3_B2:
|
||||
return &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_ALPHA:
|
||||
case GL_ALPHA4:
|
||||
case GL_ALPHA8:
|
||||
case GL_ALPHA12:
|
||||
case GL_ALPHA16:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case 1:
|
||||
case GL_LUMINANCE:
|
||||
case GL_LUMINANCE4:
|
||||
case GL_LUMINANCE8:
|
||||
case GL_LUMINANCE12:
|
||||
case GL_LUMINANCE16:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case 2:
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
case GL_LUMINANCE4_ALPHA4:
|
||||
case GL_LUMINANCE6_ALPHA2:
|
||||
case GL_LUMINANCE8_ALPHA8:
|
||||
case GL_LUMINANCE12_ALPHA4:
|
||||
case GL_LUMINANCE12_ALPHA12:
|
||||
case GL_LUMINANCE16_ALPHA16:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case GL_INTENSITY:
|
||||
case GL_INTENSITY4:
|
||||
case GL_INTENSITY8:
|
||||
case GL_INTENSITY12:
|
||||
case GL_INTENSITY16:
|
||||
/* At the moment, glean & conform both fail using the i8 internal
|
||||
* format.
|
||||
*/
|
||||
return &_mesa_texformat_al88;
|
||||
/* return &_mesa_texformat_i8; */
|
||||
|
||||
case GL_YCBCR_MESA:
|
||||
if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
|
||||
type == GL_UNSIGNED_BYTE)
|
||||
return &_mesa_texformat_ycbcr;
|
||||
else
|
||||
return &_mesa_texformat_ycbcr_rev;
|
||||
|
||||
default:
|
||||
_mesa_problem(ctx, "unexpected texture format in r200ChoosTexFormat");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL; /* never get here */
|
||||
}
|
||||
|
||||
|
||||
static GLboolean
|
||||
r200ValidateClientStorage( GLcontext *ctx, GLenum target,
|
||||
GLint internalFormat,
|
||||
GLint srcWidth, GLint srcHeight,
|
||||
GLenum format, GLenum type, const void *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage)
|
||||
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int texelBytes;
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "intformat %s format %s type %s\n",
|
||||
_mesa_lookup_enum_by_nr( internalFormat ),
|
||||
_mesa_lookup_enum_by_nr( format ),
|
||||
_mesa_lookup_enum_by_nr( type ));
|
||||
|
||||
if (!ctx->Unpack.ClientStorage)
|
||||
return 0;
|
||||
|
||||
if (ctx->_ImageTransferState ||
|
||||
texImage->IsCompressed ||
|
||||
texObj->GenerateMipmap)
|
||||
return 0;
|
||||
|
||||
|
||||
/* This list is incomplete, may be different on ppc???
|
||||
*/
|
||||
switch ( internalFormat ) {
|
||||
case GL_RGBA:
|
||||
if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
||||
texImage->TexFormat = &_mesa_texformat_argb8888;
|
||||
texelBytes = 4;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case GL_YCBCR_MESA:
|
||||
if ( format == GL_YCBCR_MESA &&
|
||||
type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
|
||||
texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
|
||||
texelBytes = 2;
|
||||
}
|
||||
else if ( format == GL_YCBCR_MESA &&
|
||||
(type == GL_UNSIGNED_SHORT_8_8_APPLE ||
|
||||
type == GL_UNSIGNED_BYTE)) {
|
||||
texImage->TexFormat = &_mesa_texformat_ycbcr;
|
||||
texelBytes = 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Could deal with these packing issues, but currently don't:
|
||||
*/
|
||||
if (packing->SkipPixels ||
|
||||
packing->SkipRows ||
|
||||
packing->SwapBytes ||
|
||||
packing->LsbFirst) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
|
||||
format, type);
|
||||
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s: srcRowStride %d/%x\n",
|
||||
__FUNCTION__, srcRowStride, srcRowStride);
|
||||
|
||||
/* Could check this later in upload, pitch restrictions could be
|
||||
* relaxed, but would need to store the image pitch somewhere,
|
||||
* as packing details might change before image is uploaded:
|
||||
*/
|
||||
if (!r200IsAgpMemory( rmesa, pixels, srcHeight * srcRowStride ) ||
|
||||
(srcRowStride & 63))
|
||||
return 0;
|
||||
|
||||
|
||||
/* Have validated that _mesa_transfer_teximage would be a straight
|
||||
* memcpy at this point. NOTE: future calls to TexSubImage will
|
||||
* overwrite the client data. This is explicitly mentioned in the
|
||||
* extension spec.
|
||||
*/
|
||||
texImage->Data = (void *)pixels;
|
||||
texImage->IsClientData = GL_TRUE;
|
||||
texImage->RowStride = srcRowStride / texelBytes;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj( texObj );
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
/* Note, this will call r200ChooseTextureFormat */
|
||||
_mesa_store_teximage1d(ctx, target, level, internalFormat,
|
||||
width, border, format, type, pixels,
|
||||
&ctx->Unpack, texObj, texImage);
|
||||
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint xoffset,
|
||||
GLsizei width,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData;
|
||||
|
||||
assert( t ); /* this _should_ be true */
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
|
||||
format, type, pixels, packing, texObj,
|
||||
texImage);
|
||||
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint height, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData;
|
||||
GLuint face;
|
||||
|
||||
/* which cube face or ordinary 2D image */
|
||||
switch (target) {
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
ASSERT(face < 6);
|
||||
break;
|
||||
default:
|
||||
face = 0;
|
||||
}
|
||||
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj( texObj );
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
texImage->IsClientData = GL_FALSE;
|
||||
|
||||
if (r200ValidateClientStorage( ctx, target,
|
||||
internalFormat,
|
||||
width, height,
|
||||
format, type, pixels,
|
||||
packing, texObj, texImage)) {
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
|
||||
}
|
||||
else {
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
|
||||
|
||||
/* Normal path: copy (to cached memory) and eventually upload
|
||||
* via another copy to agp memory and then a blit... Could
|
||||
* eliminate one copy by going straight to (permanent) agp.
|
||||
*
|
||||
* Note, this will call r200ChooseTextureFormat.
|
||||
*/
|
||||
_mesa_store_teximage2d(ctx, target, level, internalFormat,
|
||||
width, height, border, format, type, pixels,
|
||||
&ctx->Unpack, texObj, texImage);
|
||||
|
||||
t->dirty_images[face] |= (1 << level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
GLuint face;
|
||||
|
||||
/* fprintf(stderr, "%s\n", __FUNCTION__); */
|
||||
|
||||
/* which cube face or ordinary 2D image */
|
||||
switch (target) {
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
ASSERT(face < 6);
|
||||
break;
|
||||
default:
|
||||
face = 0;
|
||||
}
|
||||
|
||||
assert( t ); /* this _should_ be true */
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
|
||||
height, format, type, pixels, packing, texObj,
|
||||
texImage);
|
||||
|
||||
t->dirty_images[face] |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint height, GLint depth,
|
||||
GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData;
|
||||
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj( texObj );
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
texImage->IsClientData = GL_FALSE;
|
||||
|
||||
#if 0
|
||||
if (r200ValidateClientStorage( ctx, target,
|
||||
internalFormat,
|
||||
width, height,
|
||||
format, type, pixels,
|
||||
packing, texObj, texImage)) {
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
|
||||
|
||||
/* Normal path: copy (to cached memory) and eventually upload
|
||||
* via another copy to agp memory and then a blit... Could
|
||||
* eliminate one copy by going straight to (permanent) agp.
|
||||
*
|
||||
* Note, this will call r200ChooseTextureFormat.
|
||||
*/
|
||||
_mesa_store_teximage3d(ctx, target, level, internalFormat,
|
||||
width, height, depth, border,
|
||||
format, type, pixels,
|
||||
&ctx->Unpack, texObj, texImage);
|
||||
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
|
||||
/* fprintf(stderr, "%s\n", __FUNCTION__); */
|
||||
|
||||
assert( t ); /* this _should_ be true */
|
||||
if ( t ) {
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = r200AllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
_mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
|
||||
width, height, depth,
|
||||
format, type, pixels, packing, texObj, texImage);
|
||||
|
||||
t->dirty_images[0] |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void r200TexEnv( GLcontext *ctx, GLenum target,
|
||||
GLenum pname, const GLfloat *param )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
||||
|
||||
if ( R200_DEBUG & DEBUG_STATE ) {
|
||||
fprintf( stderr, "%s( %s )\n",
|
||||
__FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
|
||||
}
|
||||
|
||||
/* This is incorrect: Need to maintain this data for each of
|
||||
* GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
|
||||
* between them according to _ReallyEnabled.
|
||||
*/
|
||||
switch ( pname ) {
|
||||
case GL_TEXTURE_ENV_COLOR: {
|
||||
GLubyte c[4];
|
||||
GLuint envColor;
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
|
||||
envColor = r200PackColor( 4, c[0], c[1], c[2], c[3] );
|
||||
if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) {
|
||||
R200_STATECHANGE( rmesa, tf );
|
||||
rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GL_TEXTURE_LOD_BIAS_EXT: {
|
||||
GLfloat bias;
|
||||
GLuint b;
|
||||
const int fixed_one = 0x8000000;
|
||||
|
||||
/* The R200's LOD bias is a signed 2's complement value with a
|
||||
* range of -16.0 <= bias < 16.0.
|
||||
*
|
||||
* NOTE: Add a small bias to the bias for conform mipsel.c test.
|
||||
*/
|
||||
bias = *param + .01;
|
||||
bias = CLAMP( bias, -16.0, 16.0 );
|
||||
b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK;
|
||||
|
||||
if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) {
|
||||
R200_STATECHANGE( rmesa, tex[unit] );
|
||||
rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] &= ~R200_LOD_BIAS_MASK;
|
||||
rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] |= b;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void r200TexParameter( GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum pname, const GLfloat *params )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %s )\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr( pname ) );
|
||||
}
|
||||
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
switch ( pname ) {
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
|
||||
r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
case GL_TEXTURE_WRAP_T:
|
||||
case GL_TEXTURE_WRAP_R:
|
||||
r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
r200SetTexBorderColor( t, texObj->_BorderChan );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BASE_LEVEL:
|
||||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative for R200. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark this texobj as dirty (one bit per tex unit)
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void r200BindTexture( GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit );
|
||||
}
|
||||
|
||||
if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) {
|
||||
if ( !t ) {
|
||||
t = r200AllocTexObj( texObj );
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void r200DeleteTexture( GLcontext *ctx,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj );
|
||||
}
|
||||
|
||||
if ( t ) {
|
||||
if ( rmesa ) {
|
||||
R200_FIREVERTICES( rmesa );
|
||||
}
|
||||
r200DestroyTexObj( rmesa, t );
|
||||
texObj->DriverData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean r200IsTextureResident( GLcontext *ctx,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData;
|
||||
|
||||
return ( t && t->memBlock );
|
||||
}
|
||||
|
||||
|
||||
static void r200InitTextureObjects( GLcontext *ctx )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
struct gl_texture_object *texObj;
|
||||
GLuint tmp = ctx->Texture.CurrentUnit;
|
||||
|
||||
ctx->Texture.CurrentUnit = 0;
|
||||
|
||||
texObj = ctx->Texture.Unit[0].Current1D;
|
||||
r200BindTexture( ctx, GL_TEXTURE_1D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(r200TexObjPtr)texObj->DriverData );
|
||||
|
||||
texObj = ctx->Texture.Unit[0].Current2D;
|
||||
r200BindTexture( ctx, GL_TEXTURE_2D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(r200TexObjPtr)texObj->DriverData );
|
||||
|
||||
ctx->Texture.CurrentUnit = 1;
|
||||
|
||||
texObj = ctx->Texture.Unit[1].Current1D;
|
||||
r200BindTexture( ctx, GL_TEXTURE_1D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(r200TexObjPtr)texObj->DriverData );
|
||||
|
||||
texObj = ctx->Texture.Unit[1].Current2D;
|
||||
r200BindTexture( ctx, GL_TEXTURE_2D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(r200TexObjPtr)texObj->DriverData );
|
||||
|
||||
ctx->Texture.CurrentUnit = tmp;
|
||||
}
|
||||
|
||||
/* Need:
|
||||
* - Same GEN_MODE for all active bits
|
||||
* - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
|
||||
* - STRQ presumably all supported (matrix means incoming R values
|
||||
* can end up in STQ, this has implications for vertex support,
|
||||
* presumably ok if maos is used, though?)
|
||||
*
|
||||
* Basically impossible to do this on the fly - just collect some
|
||||
* basic info & do the checks from ValidateState().
|
||||
*/
|
||||
static void r200TexGen( GLcontext *ctx,
|
||||
GLenum coord,
|
||||
GLenum pname,
|
||||
const GLfloat *params )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
rmesa->recheck_texgen[unit] = GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void r200InitTextureFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.ChooseTextureFormat = r200ChooseTextureFormat;
|
||||
ctx->Driver.TexImage1D = r200TexImage1D;
|
||||
ctx->Driver.TexImage2D = r200TexImage2D;
|
||||
#if ENABLE_HW_3D_TEXTURE
|
||||
ctx->Driver.TexImage3D = r200TexImage3D;
|
||||
#else
|
||||
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
|
||||
#endif
|
||||
ctx->Driver.TexSubImage1D = r200TexSubImage1D;
|
||||
ctx->Driver.TexSubImage2D = r200TexSubImage2D;
|
||||
#if ENABLE_HW_3D_TEXTURE
|
||||
ctx->Driver.TexSubImage3D = r200TexSubImage3D;
|
||||
#else
|
||||
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
|
||||
#endif
|
||||
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
|
||||
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
|
||||
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
|
||||
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
|
||||
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
|
||||
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
|
||||
|
||||
ctx->Driver.BindTexture = r200BindTexture;
|
||||
ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */
|
||||
ctx->Driver.DeleteTexture = r200DeleteTexture;
|
||||
ctx->Driver.IsTextureResident = r200IsTextureResident;
|
||||
ctx->Driver.PrioritizeTexture = NULL;
|
||||
ctx->Driver.ActiveTexture = NULL;
|
||||
ctx->Driver.UpdateTexturePalette = NULL;
|
||||
|
||||
ctx->Driver.TexEnv = r200TexEnv;
|
||||
ctx->Driver.TexParameter = r200TexParameter;
|
||||
ctx->Driver.TexGen = r200TexGen;
|
||||
|
||||
r200InitTextureObjects( ctx );
|
||||
}
|
||||
55
src/mesa/drivers/dri/r200/r200_tex.h
Normal file
55
src/mesa/drivers/dri/r200/r200_tex.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_TEX_H__
|
||||
#define __R200_TEX_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r200UpdateTextureState( GLcontext *ctx );
|
||||
|
||||
extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face );
|
||||
|
||||
extern void r200AgeTextures( r200ContextPtr rmesa, int heap );
|
||||
extern void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t );
|
||||
extern void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t );
|
||||
|
||||
extern void r200PrintLocalLRU( r200ContextPtr rmesa, int heap );
|
||||
extern void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap );
|
||||
extern void r200UpdateTexLRU( r200ContextPtr rmesa, r200TexObjPtr t );
|
||||
|
||||
extern void r200InitTextureFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif /* __R200_TEX_H__ */
|
||||
811
src/mesa/drivers/dri/r200/r200_texmem.c
Normal file
811
src/mesa/drivers/dri/r200/r200_texmem.c
Normal file
@@ -0,0 +1,811 @@
|
||||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (C) Tungsten Graphics 2002. All Rights Reserved.
|
||||
The Weather Channel, Inc. funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86
|
||||
license. This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation on the rights to use, copy, modify, merge, publish,
|
||||
distribute, sub license, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR
|
||||
SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
#include "colormac.h"
|
||||
#include "mmath.h"
|
||||
#include "macros.h"
|
||||
#include "simple_list.h"
|
||||
#include "radeon_reg.h" /* gets definition for usleep */
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_swtcl.h"
|
||||
#include "r200_tex.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
#include <errno.h>
|
||||
|
||||
/* Destroy hardware state associated with texture `t'.
|
||||
*/
|
||||
void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t )
|
||||
{
|
||||
if ( !t )
|
||||
return;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
|
||||
}
|
||||
|
||||
if ( t->memBlock ) {
|
||||
mmFreeMem( t->memBlock );
|
||||
t->memBlock = NULL;
|
||||
}
|
||||
|
||||
if ( t->tObj )
|
||||
t->tObj->DriverData = NULL;
|
||||
|
||||
if ( rmesa ) {
|
||||
if ( t == rmesa->state.texture.unit[0].texobj ) {
|
||||
rmesa->state.texture.unit[0].texobj = NULL;
|
||||
remove_from_list( &rmesa->hw.tex[0] );
|
||||
make_empty_list( &rmesa->hw.tex[0] );
|
||||
remove_from_list( &rmesa->hw.cube[0] );
|
||||
make_empty_list( &rmesa->hw.cube[0] );
|
||||
}
|
||||
|
||||
if ( t == rmesa->state.texture.unit[1].texobj ) {
|
||||
rmesa->state.texture.unit[1].texobj = NULL;
|
||||
remove_from_list( &rmesa->hw.tex[1] );
|
||||
make_empty_list( &rmesa->hw.tex[1] );
|
||||
remove_from_list( &rmesa->hw.cube[1] );
|
||||
make_empty_list( &rmesa->hw.cube[1] );
|
||||
}
|
||||
}
|
||||
|
||||
remove_from_list( t );
|
||||
FREE( t );
|
||||
}
|
||||
|
||||
|
||||
/* Keep track of swapped out texture objects.
|
||||
*/
|
||||
void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t )
|
||||
{
|
||||
GLuint face;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
|
||||
}
|
||||
|
||||
if (t->memBlock) {
|
||||
mmFreeMem( t->memBlock );
|
||||
t->memBlock = NULL;
|
||||
}
|
||||
|
||||
if (!t->tObj) {
|
||||
remove_from_list( t );
|
||||
FREE( t );
|
||||
}
|
||||
else {
|
||||
for (face = 0; face < 6; face++)
|
||||
t->dirty_images[face] = ~0;
|
||||
move_to_tail( &rmesa->texture.swapped, t );
|
||||
}
|
||||
}
|
||||
|
||||
/* Print out debugging information about texture LRU.
|
||||
*/
|
||||
void r200PrintLocalLRU( r200ContextPtr rmesa, int heap )
|
||||
{
|
||||
r200TexObjPtr t;
|
||||
int sz = 1 << (rmesa->r200Screen->logTexGranularity[heap]);
|
||||
|
||||
fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
|
||||
|
||||
foreach ( t, &rmesa->texture.objects[heap] ) {
|
||||
if (!t->memBlock)
|
||||
continue;
|
||||
if (!t->tObj) {
|
||||
fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
|
||||
t->memBlock->ofs / sz,
|
||||
t->memBlock->ofs,
|
||||
t->memBlock->size );
|
||||
} else {
|
||||
fprintf( stderr, "Texture at 0x%x sz 0x%x\n",
|
||||
t->memBlock->ofs,
|
||||
t->memBlock->size );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap )
|
||||
{
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int i, j;
|
||||
|
||||
fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
|
||||
|
||||
for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
|
||||
fprintf( stderr, "list[%d] age %d next %d prev %d\n",
|
||||
j, list[j].age, list[j].next, list[j].prev );
|
||||
j = list[j].next;
|
||||
if ( j == RADEON_NR_TEX_REGIONS ) break;
|
||||
}
|
||||
|
||||
if ( j != RADEON_NR_TEX_REGIONS ) {
|
||||
fprintf( stderr, "Loop detected in global LRU\n" );
|
||||
for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
|
||||
fprintf( stderr, "list[%d] age %d next %d prev %d\n",
|
||||
i, list[i].age, list[i].next, list[i].prev );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
/* Reset the global texture LRU.
|
||||
*/
|
||||
static void r200ResetGlobalLRU( r200ContextPtr rmesa, int heap )
|
||||
{
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int sz = 1 << rmesa->r200Screen->logTexGranularity[heap];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* (Re)initialize the global circular LRU list. The last element in
|
||||
* the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at
|
||||
* the end of the array allows it to be addressed rationally when
|
||||
* looking up objects at a particular location in texture memory.
|
||||
*/
|
||||
for ( i = 0 ; (i+1) * sz <= rmesa->r200Screen->texSize[heap] ; i++ ) {
|
||||
list[i].prev = i-1;
|
||||
list[i].next = i+1;
|
||||
list[i].age = 0;
|
||||
}
|
||||
|
||||
i--;
|
||||
list[0].prev = RADEON_NR_TEX_REGIONS;
|
||||
list[i].prev = i-1;
|
||||
list[i].next = RADEON_NR_TEX_REGIONS;
|
||||
list[RADEON_NR_TEX_REGIONS].prev = i;
|
||||
list[RADEON_NR_TEX_REGIONS].next = 0;
|
||||
rmesa->sarea->texAge[heap] = 0;
|
||||
}
|
||||
|
||||
/* Update the local and glock texture LRUs.
|
||||
*/
|
||||
void r200UpdateTexLRU(r200ContextPtr rmesa, r200TexObjPtr t )
|
||||
{
|
||||
int heap = t->heap;
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int sz = rmesa->r200Screen->logTexGranularity[heap];
|
||||
int i, start, end;
|
||||
|
||||
rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap];
|
||||
|
||||
if ( !t->memBlock )
|
||||
return;
|
||||
|
||||
start = t->memBlock->ofs >> sz;
|
||||
end = (t->memBlock->ofs + t->memBlock->size-1) >> sz;
|
||||
|
||||
/* Update our local LRU */
|
||||
move_to_head( &rmesa->texture.objects[heap], t );
|
||||
|
||||
/* Update the global LRU */
|
||||
for ( i = start ; i <= end ; i++ ) {
|
||||
list[i].in_use = 1;
|
||||
list[i].age = rmesa->texture.age[heap];
|
||||
|
||||
/* remove_from_list(i) */
|
||||
list[(GLuint)list[i].next].prev = list[i].prev;
|
||||
list[(GLuint)list[i].prev].next = list[i].next;
|
||||
|
||||
/* insert_at_head(list, i) */
|
||||
list[i].prev = RADEON_NR_TEX_REGIONS;
|
||||
list[i].next = list[RADEON_NR_TEX_REGIONS].next;
|
||||
list[(GLuint)list[RADEON_NR_TEX_REGIONS].next].prev = i;
|
||||
list[RADEON_NR_TEX_REGIONS].next = i;
|
||||
}
|
||||
|
||||
if ( 0 ) {
|
||||
r200PrintGlobalLRU( rmesa, t->heap );
|
||||
r200PrintLocalLRU( rmesa, t->heap );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update our notion of what textures have been changed since we last
|
||||
* held the lock. This pertains to both our local textures and the
|
||||
* textures belonging to other clients. Keep track of other client's
|
||||
* textures by pushing a placeholder texture onto the LRU list -- these
|
||||
* are denoted by (tObj == NULL).
|
||||
*/
|
||||
static void r200TexturesGone( r200ContextPtr rmesa, int heap,
|
||||
int offset, int size, int in_use )
|
||||
{
|
||||
r200TexObjPtr t, tmp;
|
||||
|
||||
foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) {
|
||||
if ( !t->memBlock ||
|
||||
t->memBlock->ofs >= offset + size ||
|
||||
t->memBlock->ofs + t->memBlock->size <= offset )
|
||||
continue;
|
||||
|
||||
/* It overlaps - kick it out. Need to hold onto the currently
|
||||
* bound objects, however.
|
||||
*/
|
||||
r200SwapOutTexObj( rmesa, t );
|
||||
}
|
||||
|
||||
if ( in_use ) {
|
||||
t = (r200TexObjPtr) CALLOC( sizeof(*t) );
|
||||
if ( !t ) return;
|
||||
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset );
|
||||
if ( !t->memBlock ) {
|
||||
fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
|
||||
(int)size, (int)offset );
|
||||
mmDumpMemInfo( rmesa->texture.heap[heap] );
|
||||
return;
|
||||
}
|
||||
insert_at_head( &rmesa->texture.objects[heap], t );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update our client's shared texture state. If another client has
|
||||
* modified a region in which we have textures, then we need to figure
|
||||
* out which of our textures has been removed, and update our global
|
||||
* LRU.
|
||||
*/
|
||||
void r200AgeTextures( r200ContextPtr rmesa, int heap )
|
||||
{
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf(stderr, "%s %d\n", __FUNCTION__, heap);
|
||||
}
|
||||
|
||||
if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) {
|
||||
int sz = 1 << rmesa->r200Screen->logTexGranularity[heap];
|
||||
int nr = 0;
|
||||
int idx;
|
||||
|
||||
for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ;
|
||||
idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ;
|
||||
idx = sarea->texList[heap][idx].prev, nr++ )
|
||||
{
|
||||
/* If switching texturing schemes, then the SAREA might not
|
||||
* have been properly cleared, so we need to reset the
|
||||
* global texture LRU.
|
||||
*/
|
||||
if ( idx * sz > rmesa->r200Screen->texSize[heap] ) {
|
||||
nr = RADEON_NR_TEX_REGIONS;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) {
|
||||
r200TexturesGone( rmesa, heap, idx * sz, sz,
|
||||
sarea->texList[heap][idx].in_use );
|
||||
}
|
||||
}
|
||||
|
||||
if ( nr == RADEON_NR_TEX_REGIONS ) {
|
||||
r200TexturesGone( rmesa, heap, 0,
|
||||
rmesa->r200Screen->texSize[heap], 0 );
|
||||
r200ResetGlobalLRU( rmesa, heap );
|
||||
}
|
||||
|
||||
rmesa->texture.age[heap] = sarea->texAge[heap];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Texture image conversions
|
||||
*/
|
||||
|
||||
|
||||
static void r200UploadAGPClientSubImage( r200ContextPtr rmesa,
|
||||
r200TexObjPtr t,
|
||||
struct gl_texture_image *texImage,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y,
|
||||
GLint width, GLint height )
|
||||
{
|
||||
const struct gl_texture_format *texFormat = texImage->TexFormat;
|
||||
GLuint srcPitch, dstPitch;
|
||||
int blit_format;
|
||||
int srcOffset;
|
||||
|
||||
/*
|
||||
* XXX it appears that we always upload the full image, not a subimage.
|
||||
* I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever
|
||||
* changed, the src pitch will have to change.
|
||||
*/
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
blit_format = R200_CP_COLOR_FORMAT_CI8;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
case 2:
|
||||
blit_format = R200_CP_COLOR_FORMAT_RGB565;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
t->image[0][hwlevel].data = texImage->Data;
|
||||
srcOffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data );
|
||||
|
||||
assert( srcOffset != ~0 );
|
||||
|
||||
/* Don't currently need to cope with small pitches?
|
||||
*/
|
||||
width = texImage->Width;
|
||||
height = texImage->Height;
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
r200EmitBlit( rmesa, blit_format,
|
||||
srcPitch,
|
||||
srcOffset,
|
||||
dstPitch,
|
||||
t->bufAddr,
|
||||
x,
|
||||
y,
|
||||
t->image[0][hwlevel].x + x,
|
||||
t->image[0][hwlevel].y + y,
|
||||
width,
|
||||
height );
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_2D );
|
||||
}
|
||||
|
||||
static void r200UploadRectSubImage( r200ContextPtr rmesa,
|
||||
r200TexObjPtr t,
|
||||
struct gl_texture_image *texImage,
|
||||
GLint x, GLint y,
|
||||
GLint width, GLint height )
|
||||
{
|
||||
const struct gl_texture_format *texFormat = texImage->TexFormat;
|
||||
int blit_format, dstPitch, done;
|
||||
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
blit_format = R200_CP_COLOR_FORMAT_CI8;
|
||||
break;
|
||||
case 2:
|
||||
blit_format = R200_CP_COLOR_FORMAT_RGB565;
|
||||
break;
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
t->image[0][0].data = texImage->Data;
|
||||
|
||||
/* Currently don't need to cope with small pitches.
|
||||
*/
|
||||
width = texImage->Width;
|
||||
height = texImage->Height;
|
||||
dstPitch = t->pp_txpitch + 32;
|
||||
|
||||
if (rmesa->prefer_agp_client_texturing && texImage->IsClientData) {
|
||||
/* In this case, could also use agp texturing. This is
|
||||
* currently disabled, but has been tested & works.
|
||||
*/
|
||||
t->pp_txoffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data );
|
||||
t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32;
|
||||
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"Using agp texturing for rectangular client texture\n");
|
||||
|
||||
/* Release FB memory allocated for this image:
|
||||
*/
|
||||
if ( t->memBlock ) {
|
||||
mmFreeMem( t->memBlock );
|
||||
t->memBlock = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else if (texImage->IsClientData) {
|
||||
/* Data already in agp memory, with usable pitch.
|
||||
*/
|
||||
GLuint srcPitch;
|
||||
srcPitch = texImage->RowStride * texFormat->TexelBytes;
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
srcPitch,
|
||||
r200AgpOffsetFromVirtual( rmesa, texImage->Data ),
|
||||
dstPitch, t->bufAddr,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height );
|
||||
}
|
||||
else {
|
||||
/* Data not in agp memory, or bad pitch.
|
||||
*/
|
||||
for (done = 0; done < height ; ) {
|
||||
struct r200_dma_region region;
|
||||
int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch );
|
||||
int src_pitch;
|
||||
char *tex;
|
||||
|
||||
src_pitch = texImage->RowStride * texFormat->TexelBytes;
|
||||
|
||||
tex = (char *)texImage->Data + done * src_pitch;
|
||||
|
||||
memset(®ion, 0, sizeof(region));
|
||||
r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 64 );
|
||||
|
||||
/* Copy texdata to dma:
|
||||
*/
|
||||
if (0)
|
||||
fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n",
|
||||
__FUNCTION__, src_pitch, dstPitch);
|
||||
|
||||
if (src_pitch == dstPitch) {
|
||||
memcpy( region.address, tex, lines * src_pitch );
|
||||
}
|
||||
else {
|
||||
char *buf = region.address;
|
||||
int i;
|
||||
for (i = 0 ; i < lines ; i++) {
|
||||
memcpy( buf, tex, src_pitch );
|
||||
buf += dstPitch;
|
||||
tex += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
/* Blit to framebuffer
|
||||
*/
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
dstPitch, GET_START( ®ion ),
|
||||
dstPitch, t->bufAddr,
|
||||
0, 0,
|
||||
0, done,
|
||||
width, lines );
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_2D );
|
||||
|
||||
r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ );
|
||||
done += lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Upload the texture image associated with texture `t' at level `level'
|
||||
* at the address relative to `start'.
|
||||
*/
|
||||
static void r200UploadSubImage( r200ContextPtr rmesa,
|
||||
r200TexObjPtr t,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y, GLint width, GLint height,
|
||||
GLuint face )
|
||||
{
|
||||
struct gl_texture_image *texImage = NULL;
|
||||
const struct gl_texture_format *texFormat;
|
||||
GLint texelsPerDword = 0;
|
||||
GLuint format, pitch, offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drmRadeonTexture tex;
|
||||
drmRadeonTexImage tmp;
|
||||
int level = hwlevel + t->firstLevel;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s level %d %dx%d\n", __FUNCTION__,
|
||||
level, width, height);
|
||||
}
|
||||
|
||||
ASSERT(face < 6);
|
||||
|
||||
/* Ensure we have a valid texture to upload */
|
||||
if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
|
||||
_mesa_problem(NULL, "bad texture level in r200UploadSubimage");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (face) {
|
||||
case 0:
|
||||
texImage = t->tObj->Image[level];
|
||||
break;
|
||||
case 1:
|
||||
texImage = t->tObj->NegX[level];
|
||||
break;
|
||||
case 2:
|
||||
texImage = t->tObj->PosY[level];
|
||||
break;
|
||||
case 3:
|
||||
texImage = t->tObj->NegY[level];
|
||||
break;
|
||||
case 4:
|
||||
texImage = t->tObj->PosZ[level];
|
||||
break;
|
||||
case 5:
|
||||
texImage = t->tObj->NegZ[level];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !texImage ) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
|
||||
return;
|
||||
}
|
||||
if ( !texImage->Data ) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (t->tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
assert(level == 0);
|
||||
assert(hwlevel == 0);
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
|
||||
r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if (texImage->IsClientData) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in agp client storage\n",
|
||||
__FUNCTION__);
|
||||
r200UploadAGPClientSubImage( rmesa, t, texImage, hwlevel,
|
||||
x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in normal memory\n",
|
||||
__FUNCTION__);
|
||||
|
||||
|
||||
texFormat = texImage->TexFormat;
|
||||
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
texelsPerDword = 4;
|
||||
break;
|
||||
case 2:
|
||||
texelsPerDword = 2;
|
||||
break;
|
||||
case 4:
|
||||
texelsPerDword = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK;
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr;
|
||||
|
||||
if (texFormat->TexelBytes == 0)
|
||||
pitch = (t->image[face][0].width * 1) / 64;
|
||||
else
|
||||
pitch = (t->image[face][0].width * texFormat->TexelBytes) / 64;
|
||||
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) )
|
||||
{
|
||||
GLint imageX = 0;
|
||||
GLint imageY = 0;
|
||||
GLint blitX = t->image[face][hwlevel].x;
|
||||
GLint blitY = t->image[face][hwlevel].y;
|
||||
GLint blitWidth = t->image[face][hwlevel].width;
|
||||
GLint blitHeight = t->image[face][hwlevel].height;
|
||||
fprintf( stderr, " upload image: %d,%d at %d,%d\n",
|
||||
imageWidth, imageHeight, imageX, imageY );
|
||||
fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
|
||||
blitWidth, blitHeight, blitX, blitY );
|
||||
fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x "
|
||||
"level: %d/%d format: %x\n",
|
||||
(GLuint)offset, (GLuint)pitch, hwlevel, level, format );
|
||||
}
|
||||
|
||||
t->image[face][hwlevel].data = texImage->Data;
|
||||
|
||||
/* Init the DRM_RADEON_TEXTURE command / drmRadeonTexture struct.
|
||||
* NOTE: we're always use a 1KB-wide blit and I8 texture format.
|
||||
* We used to use 1, 2 and 4-byte texels and used to use the texture
|
||||
* width to dictate the blit width - but that won't work for compressed
|
||||
* textures. (Brian)
|
||||
*/
|
||||
tex.offset = offset;
|
||||
tex.pitch = BLIT_WIDTH_BYTES / 64;
|
||||
tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
if (texImage->TexFormat->TexelBytes) {
|
||||
tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */
|
||||
tex.height = imageHeight;
|
||||
}
|
||||
else {
|
||||
tex.width = imageWidth; /* compressed */
|
||||
tex.height = imageHeight;
|
||||
if (tex.height < 4)
|
||||
tex.height = 4;
|
||||
}
|
||||
tex.image = &tmp;
|
||||
|
||||
/* copy (x,y,width,height,data) */
|
||||
memcpy( &tmp, &t->image[face][hwlevel], sizeof(drmRadeonTexImage) );
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
do {
|
||||
ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drmRadeonTexture) );
|
||||
if (ret) {
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while ( ret && errno == EAGAIN );
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_R200_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n",
|
||||
offset, pitch, format );
|
||||
fprintf( stderr, " image width=%d height=%d\n",
|
||||
imageWidth, imageHeight );
|
||||
fprintf( stderr, " blit width=%d height=%d data=%p\n",
|
||||
t->image[face][hwlevel].width, t->image[face][hwlevel].height,
|
||||
t->image[face][hwlevel].data );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Upload the texture images associated with texture `t'. This might
|
||||
* require removing our own and/or other client's texture objects to
|
||||
* make room for these images.
|
||||
*/
|
||||
int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face )
|
||||
{
|
||||
const int numLevels = t->lastLevel - t->firstLevel + 1;
|
||||
int heap;
|
||||
r200TexObjPtr t0 = rmesa->state.texture.unit[0].texobj;
|
||||
r200TexObjPtr t1 = rmesa->state.texture.unit[1].texobj;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
||||
rmesa->glCtx, t->tObj, t->totalSize,
|
||||
t->firstLevel, t->lastLevel );
|
||||
}
|
||||
|
||||
if ( !t || t->totalSize == 0 )
|
||||
return 0;
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "\nSyncing\n\n");
|
||||
R200_FIREVERTICES( rmesa );
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
/* Choose the heap appropriately */
|
||||
heap = t->heap = RADEON_CARD_HEAP;
|
||||
|
||||
/* Do we need to eject LRU texture objects? */
|
||||
if ( !t->memBlock ) {
|
||||
/* Allocate a memory block on a 1k boundary (1<<10 == 1024) */
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap],
|
||||
t->totalSize, 10, 0 );
|
||||
|
||||
|
||||
/* Kick out textures until the requested texture fits */
|
||||
while ( !t->memBlock ) {
|
||||
if ( rmesa->texture.objects[heap].prev == t0 ||
|
||||
rmesa->texture.objects[heap].prev == t1 ) {
|
||||
fprintf( stderr,
|
||||
"r200UploadTexImages: ran into bound texture\n" );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
}
|
||||
if ( rmesa->texture.objects[heap].prev ==
|
||||
&rmesa->texture.objects[heap] ) {
|
||||
if ( rmesa->r200Screen->IsPCI ) {
|
||||
fprintf( stderr, "r200UploadTexImages: upload texture "
|
||||
"failure on local texture heaps, sz=%d\n",
|
||||
t->totalSize );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
} else {
|
||||
fprintf( stderr, "r200UploadTexImages: upload texture "
|
||||
"failure on both local and AGP texture heaps, "
|
||||
"sz=%d\n",
|
||||
t->totalSize );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
r200SwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev );
|
||||
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap],
|
||||
t->totalSize, 12, 0 );
|
||||
}
|
||||
|
||||
/* Set the base offset of the texture image */
|
||||
t->bufAddr = rmesa->r200Screen->texOffset[heap] + t->memBlock->ofs;
|
||||
t->pp_txoffset = t->bufAddr;
|
||||
|
||||
/* Mark this texobj as dirty on all units:
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
/* Let the world know we've used this memory recently */
|
||||
r200UpdateTexLRU( rmesa, t );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
/* Upload any images that are new */
|
||||
if (t->dirty_images[face]) {
|
||||
int hwlevel;
|
||||
for ( hwlevel = 0 ; hwlevel < numLevels ; hwlevel++ ) {
|
||||
if ( t->dirty_images[face] & (1 << (hwlevel+t->firstLevel)) ) {
|
||||
r200UploadSubImage( rmesa, t, hwlevel,
|
||||
0, 0,
|
||||
t->image[face][hwlevel].width,
|
||||
t->image[face][hwlevel].height, face );
|
||||
}
|
||||
}
|
||||
t->dirty_images[face] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "\nSyncing\n\n");
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1799
src/mesa/drivers/dri/r200/r200_texstate.c
Normal file
1799
src/mesa/drivers/dri/r200/r200_texstate.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user