Compare commits
76 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 |
@@ -1,7 +1,9 @@
|
||||
*.tag
|
||||
array_cache
|
||||
core
|
||||
core_subset
|
||||
math
|
||||
math_subset
|
||||
miniglx
|
||||
radeon_subset
|
||||
swrast
|
||||
|
||||
@@ -6,4 +6,5 @@ See http://www.doxygen.org/ for more info.
|
||||
Either run 'make' (Unix) or 'doxy.bat' (Windows) to run doxygen
|
||||
and generate souce code documentation.
|
||||
|
||||
Then, load doxy/core/index.html into your web browser.
|
||||
Then, load either doxy/core/index.html or doxy/core_subset/index.html into
|
||||
your web browser.
|
||||
|
||||
@@ -55,7 +55,7 @@ INPUT = ../src/
|
||||
FILE_PATTERNS = *.c *.h
|
||||
RECURSIVE = NO
|
||||
EXCLUDE = ../src/glapitemp.h ../src/glapioffsets.h
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS = subset_*
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
@@ -132,13 +132,13 @@ GENERATE_AUTOGEN_DEF = NO
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = ../include/
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
PREDEFINED = _HAVE_FULL_GL=1
|
||||
EXPAND_AS_DEFINED = _glthread_DECLARE_STATIC_MUTEX
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
@@ -148,8 +148,7 @@ TAGFILES = tnl_dd.tag=../tnl_dd \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
miniglx.tag=../miniglx
|
||||
tnl.tag=../tnl
|
||||
GENERATE_TAGFILE = core.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
226
doxygen/core_subset.doxy
Normal file
226
doxygen/core_subset.doxy
Normal file
@@ -0,0 +1,226 @@
|
||||
# Doxyfile 0.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = "Mesa Core"
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = YES
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS = subset
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_FORMAT =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ../src/
|
||||
FILE_PATTERNS = \
|
||||
accum.h \
|
||||
attrib.h \
|
||||
blend.[ch] \
|
||||
buffers.[ch] \
|
||||
dd.h \
|
||||
debug.h \
|
||||
depth.h \
|
||||
dlist.h \
|
||||
context.[ch] \
|
||||
config.h \
|
||||
colormac.h \
|
||||
colortab.h \
|
||||
enable.h \
|
||||
enums.h \
|
||||
eval.h \
|
||||
extensions.h \
|
||||
feedback.[ch] \
|
||||
fog.h \
|
||||
get.h \
|
||||
glheader.h \
|
||||
glthread.h \
|
||||
hash.[ch] \
|
||||
hint.h \
|
||||
histogram.h \
|
||||
image.[ch] \
|
||||
imports.[ch] \
|
||||
lines.[ch] \
|
||||
light.h \
|
||||
matrix.[ch] \
|
||||
macros.h \
|
||||
mmath.h \
|
||||
mtypes.h \
|
||||
pixel.h \
|
||||
points.[ch] \
|
||||
polygon.[ch] \
|
||||
rastpos.[ch] \
|
||||
simple_list.h \
|
||||
state.[ch] \
|
||||
stencil.[ch] \
|
||||
subset_*.c \
|
||||
texformat.h \
|
||||
teximage.h \
|
||||
texstate.h \
|
||||
texstore.h \
|
||||
texobj.[ch] \
|
||||
texutil_tmp.h \
|
||||
varray.h
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = core_subset
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT =
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT =
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT =
|
||||
MAN_EXTENSION =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = ../include/
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = \
|
||||
math_subset.tag=../math_subset \
|
||||
miniglx.tag=../miniglx
|
||||
GENERATE_TAGFILE = core_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME =
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH =
|
||||
EXT_DOC_PATHS =
|
||||
@@ -3,12 +3,10 @@
|
||||
</head>
|
||||
<body><center>
|
||||
<a href="../core/index.html">Mesa Core</a>
|
||||
<a href="../miniglx/index.html">MiniGLX</a>
|
||||
<a href="../array_cache/index.html">array_cache</a>
|
||||
<a href="../math/index.html">math</a>
|
||||
<a href="../swrast/index.html">swrast</a>
|
||||
<a href="../swrast_setup/index.html">swrast_setup</a>
|
||||
<a href="../tnl/index.html">tnl</a>
|
||||
<a href="../tnl_dd/index.html">tnl_dd</a>
|
||||
<a href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</center>
|
||||
</center>
|
||||
|
||||
9
doxygen/header_subset.html
Normal file
9
doxygen/header_subset.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<html><head><title>Mesa Source Code Documentation</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body><center>
|
||||
<a href="../core_subset/index.html">Mesa Core</a>
|
||||
<a href="../math_subset/index.html">math</a>
|
||||
<a href="../miniglx/index.html">MiniGLX</a>
|
||||
<a href="../radeon_subset/index.html">radeon_subset</a>
|
||||
</center>
|
||||
@@ -1,11 +1,12 @@
|
||||
default:
|
||||
default: subset
|
||||
|
||||
full:
|
||||
doxygen tnl_dd.doxy
|
||||
doxygen array_cache.doxy
|
||||
doxygen math.doxy
|
||||
doxygen swrast.doxy
|
||||
doxygen swrast_setup.doxy
|
||||
doxygen tnl.doxy
|
||||
doxygen miniglx.doxy
|
||||
doxygen core.doxy
|
||||
echo "Building again, to resolve tags"
|
||||
doxygen tnl_dd.doxy
|
||||
@@ -14,11 +15,30 @@ default:
|
||||
doxygen swrast.doxy
|
||||
doxygen swrast_setup.doxy
|
||||
doxygen tnl.doxy
|
||||
doxygen core.doxy
|
||||
|
||||
subset:
|
||||
doxygen core_subset.doxy
|
||||
doxygen math_subset.doxy
|
||||
doxygen miniglx.doxy
|
||||
echo "Building again, to resolve tags"
|
||||
doxygen core_subset.doxy
|
||||
doxygen math_subset.doxy
|
||||
doxygen miniglx.doxy
|
||||
doxygen radeon_subset.doxy
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf array_cache core math swrast swrast_setup tnl_dd tnl miniglx radeon_subset
|
||||
rm -rf \
|
||||
array_cache \
|
||||
core \
|
||||
core_subset \
|
||||
math \
|
||||
math_subset \
|
||||
swrast \
|
||||
swrast_setup \
|
||||
tnl_dd \
|
||||
tnl \
|
||||
miniglx \
|
||||
radeon_subset
|
||||
rm -rf *.tag
|
||||
|
||||
|
||||
177
doxygen/math_subset.doxy
Normal file
177
doxygen/math_subset.doxy
Normal file
@@ -0,0 +1,177 @@
|
||||
# Doxyfile 0.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = "Mesa math module"
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY = .
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_FORMAT =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ../src/math/
|
||||
FILE_PATTERNS = m_matrix.[ch]
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = math_subset
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT =
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT =
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT =
|
||||
MAN_EXTENSION =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core_subset.tag=../core_subset
|
||||
GENERATE_TAGFILE = math_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME =
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH =
|
||||
EXT_DOC_PATHS =
|
||||
@@ -80,7 +80,7 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = miniglx
|
||||
HTML_HEADER = header.html
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
@@ -143,14 +143,9 @@ SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core.tag=../core \
|
||||
tnl_dd.tag=../tnl_dd \
|
||||
array_cache.tag=../array_cache \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
array_cache.tag=array_cache
|
||||
TAGFILES = \
|
||||
core_subset.tag=../core_subset \
|
||||
math_subset.tag=../math_subset
|
||||
GENERATE_TAGFILE = miniglx.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
@@ -103,7 +103,7 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = radeon_subset
|
||||
HTML_HEADER = header.html
|
||||
HTML_HEADER = header_subset.html
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
@@ -166,15 +166,10 @@ SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES = core.tag=../core \
|
||||
tnl_dd.tag=../tnl_dd \
|
||||
array_cache.tag=../array_cache \
|
||||
math.tag=../math \
|
||||
swrast.tag=../swrast \
|
||||
swrast_setup.tag=../swrast_setup \
|
||||
tnl.tag=../tnl \
|
||||
miniglx.tag=../miniglx \
|
||||
array_cache.tag=array_cache
|
||||
TAGFILES = \
|
||||
core_subset.tag=../core_subset \
|
||||
math_subset.tag=../math_subset \
|
||||
miniglx.tag=../miniglx
|
||||
GENERATE_TAGFILE = radeon_subset.tag
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/* $Id: gl.h,v 1.72 2002/10/17 19:39:31 kschultz Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 4.1
|
||||
* Version: 5.0.1
|
||||
*
|
||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -2646,6 +2645,13 @@ GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid
|
||||
#endif /* GL_APPLE_ycbcr_422 */
|
||||
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_ATI_texture_env_combine3 1
|
||||
#define GL_MODULATE_ADD_ATI 0x8744
|
||||
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
|
||||
#define GL_MODULATE_SUBTRACT_ATI 0x8746
|
||||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Begin system-specific stuff
|
||||
|
||||
@@ -2423,6 +2423,11 @@ extern "C" {
|
||||
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
|
||||
#endif
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_MODULATE_ADD_ATI 0x8744
|
||||
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
|
||||
#define GL_MODULATE_SUBTRACT_ATI 0x8746
|
||||
#endif
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
@@ -5016,6 +5021,9 @@ GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum);
|
||||
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
||||
#endif
|
||||
|
||||
#ifndef GL_ATI_texture_env_combine3
|
||||
#define GL_ATI_texture_env_combine3 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -17,12 +17,14 @@ PROGS = prim \
|
||||
|
||||
# make executable from .c file:
|
||||
.c: $(LIB_DEP)
|
||||
gcc -I../include -g $< -L../lib -lglut -lGL -lm -o $@
|
||||
gcc -I../include -g $< -L../lib -lglut -lGL -lGLU -lm -o $@
|
||||
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
|
||||
clean:
|
||||
-rm *.o *~
|
||||
clean: clean_here
|
||||
|
||||
clean_here:
|
||||
rm -f *.o *~ $(PROGS)
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ static void Init(void)
|
||||
GLint i;
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearIndex(0.0);
|
||||
/* glClearIndex(0.0); */
|
||||
|
||||
if (!rgb) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
@@ -71,7 +71,7 @@ static void Init(void)
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonStipple(stippleBits);
|
||||
/* glPolygonStipple(stippleBits); */
|
||||
|
||||
antiAlias = GL_FALSE;
|
||||
stipple = GL_FALSE;
|
||||
@@ -135,11 +135,11 @@ static void Draw(void)
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexi(ci1);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
glVertex3f( 0.9, -0.9, -30.0);
|
||||
glVertex3f( 0.9, 0.9, -30.0);
|
||||
glVertex3f(-0.9, 0.0, -30.0);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexi(ci2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
glVertex3f(-0.9, -0.9, -40.0);
|
||||
glVertex3f(-0.9, 0.9, -40.0);
|
||||
glVertex3f( 0.9, 0.0, -25.0);
|
||||
|
||||
@@ -141,7 +141,7 @@ static void Draw(void)
|
||||
for (i = 0; i < 360; i += 5) {
|
||||
glRotatef(5.0, 0,0,1);
|
||||
|
||||
(rgb) ? glColor3f(1.0, 1.0, 0.0) : glIndexi(ci);
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(pntA);
|
||||
glVertex3fv(pntB);
|
||||
@@ -199,7 +199,7 @@ int main(int argc, char **argv)
|
||||
|
||||
glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
|
||||
|
||||
windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
|
||||
windType = GLUT_RGB;
|
||||
windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
|
||||
glutInitDisplayMode(windType);
|
||||
|
||||
|
||||
@@ -153,9 +153,9 @@ static void Draw(void)
|
||||
|
||||
/* glPointSize(size); */
|
||||
if (mode) {
|
||||
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED);
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
} else {
|
||||
(rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_RED);
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
}
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3fv(point);
|
||||
|
||||
@@ -126,18 +126,18 @@ static void Point(void)
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
for (i = 1; i < 8; i++) {
|
||||
GLint j = i * 2;
|
||||
SetColor(COLOR_BLACK+i);
|
||||
glVertex2i(-j, -j);
|
||||
glVertex2i(-j, 0);
|
||||
glVertex2i(-j, j);
|
||||
glVertex2i(0, j);
|
||||
glVertex2i(j, j);
|
||||
glVertex2i(j, 0);
|
||||
glVertex2i(j, -j);
|
||||
glVertex2i(0, -j);
|
||||
glVertex2f(-j, -j);
|
||||
glVertex2f(-j, 0);
|
||||
glVertex2f(-j, j);
|
||||
glVertex2f(0, j);
|
||||
glVertex2f(j, j);
|
||||
glVertex2f(j, 0);
|
||||
glVertex2f(j, -j);
|
||||
glVertex2f(0, -j);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -152,8 +152,8 @@ static void Lines(void)
|
||||
for (i = 1; i < 8; i++) {
|
||||
SetColor(COLOR_BLACK+i);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
glTranslatef(4, 0, 0);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ static void Lines(void)
|
||||
glPopMatrix();
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ static void LineStrip(void)
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -218,11 +218,11 @@ static void LineLoop(void)
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -231,16 +231,16 @@ static void Bitmap(void)
|
||||
|
||||
glBegin(GL_LINES);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/2, 0);
|
||||
glVertex2i(boxW/2, 0);
|
||||
glVertex2i(0, -boxH/2);
|
||||
glVertex2i(0, boxH/2);
|
||||
glVertex2f(-boxW/2, 0);
|
||||
glVertex2f(boxW/2, 0);
|
||||
glVertex2f(0, -boxH/2);
|
||||
glVertex2f(0, boxH/2);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(0, -3);
|
||||
glVertex2i(0, -3+OPENGL_HEIGHT);
|
||||
glVertex2f(0, -3);
|
||||
glVertex2f(0, -3+OPENGL_HEIGHT);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -3);
|
||||
glVertex2i(OPENGL_WIDTH, -3);
|
||||
glVertex2f(0, -3);
|
||||
glVertex2f(OPENGL_WIDTH, -3);
|
||||
glEnd();
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
@@ -257,23 +257,23 @@ static void Triangles(void)
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, -boxH/16);
|
||||
glVertex2f(-boxW/8, -boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, -boxH/16);
|
||||
glVertex2f(boxW/8, -boxH/16);
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, boxH/16);
|
||||
glVertex2f(-boxW/8, boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, boxH/16);
|
||||
glVertex2f(boxW/8, boxH/16);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -282,28 +282,28 @@ static void TriangleStrip(void)
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -boxH/4);
|
||||
glVertex2f(0, -boxH/4);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, boxH/4);
|
||||
glVertex2f(0, boxH/4);
|
||||
SetColor(COLOR_CYAN);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
SetColor(COLOR_YELLOW);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void TriangleFan(void)
|
||||
{
|
||||
GLint vx[8][2];
|
||||
GLfloat vx[8][2];
|
||||
GLint x0, y0, x1, y1, x2, y2, x3, y3;
|
||||
GLint i;
|
||||
|
||||
@@ -327,16 +327,16 @@ static void TriangleFan(void)
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SetColor(COLOR_WHITE-i);
|
||||
glVertex2iv(vx[i]);
|
||||
glVertex2fv(vx[i]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ static void Rect(void)
|
||||
|
||||
static void PolygonFunc(void)
|
||||
{
|
||||
GLint vx[8][2];
|
||||
GLfloat vx[8][2];
|
||||
GLint x0, y0, x1, y1, x2, y2, x3, y3;
|
||||
GLint i;
|
||||
|
||||
@@ -374,13 +374,13 @@ static void PolygonFunc(void)
|
||||
glBegin(GL_POLYGON);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SetColor(COLOR_WHITE-i);
|
||||
glVertex2iv(vx[i]);
|
||||
glVertex2fv(vx[i]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -389,28 +389,28 @@ static void Quads(void)
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, -boxH/16);
|
||||
glVertex2f(-boxW/8, -boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, -boxH/16);
|
||||
glVertex2f(boxW/8, -boxH/16);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/8, boxH/16);
|
||||
glVertex2f(-boxW/8, boxH/16);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(boxW/8, boxH/16);
|
||||
glVertex2f(boxW/8, boxH/16);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -419,29 +419,30 @@ static void QuadStrip(void)
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
SetColor(COLOR_GREEN);
|
||||
glVertex2i(-boxW/4, -boxH/4);
|
||||
glVertex2f(-boxW/4, -boxH/4);
|
||||
SetColor(COLOR_RED);
|
||||
glVertex2i(-boxW/4, boxH/4);
|
||||
glVertex2f(-boxW/4, boxH/4);
|
||||
SetColor(COLOR_BLUE);
|
||||
glVertex2i(0, -boxH/4);
|
||||
glVertex2f(0, -boxH/4);
|
||||
SetColor(COLOR_WHITE);
|
||||
glVertex2i(0, boxH/4);
|
||||
glVertex2f(0, boxH/4);
|
||||
SetColor(COLOR_CYAN);
|
||||
glVertex2i(boxW/4, -boxH/4);
|
||||
glVertex2f(boxW/4, -boxH/4);
|
||||
SetColor(COLOR_YELLOW);
|
||||
glVertex2i(boxW/4, boxH/4);
|
||||
glVertex2f(boxW/4, boxH/4);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(100, 100);
|
||||
glVertex2i(-100, 100);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2f(100, 100);
|
||||
glVertex2f(-100, 100);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void Draw(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
glViewport(0, 0, windW, windH);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
|
||||
@@ -255,7 +255,6 @@ static void Key(unsigned char key, int x, int y)
|
||||
|
||||
void Draw(void)
|
||||
{
|
||||
|
||||
MoveStars();
|
||||
ShowStars();
|
||||
if (nitro > 0) {
|
||||
|
||||
@@ -26,8 +26,8 @@ static void SetColor(int c)
|
||||
{
|
||||
if (glutGet(GLUT_WINDOW_RGBA))
|
||||
glColor3fv(RGBMap[c]);
|
||||
else
|
||||
glIndexf(c);
|
||||
/* else */
|
||||
/* glIndexf(c); */
|
||||
}
|
||||
|
||||
static void InitMap(void)
|
||||
|
||||
@@ -278,11 +278,11 @@ static void Draw(void)
|
||||
EndPrim();
|
||||
|
||||
if (showVerticies) {
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
|
||||
glColor3fv(RGBMap[COLOR_RED]);
|
||||
/* glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2); */
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
/* glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2); */
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
/* glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2); */
|
||||
}
|
||||
|
||||
@@ -314,11 +314,11 @@ static void Draw(void)
|
||||
|
||||
SetColor(COLOR_RED);
|
||||
BeginPrim();
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
|
||||
glColor3fv(RGBMap[COLOR_RED]);
|
||||
glVertex3fv(p0);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
|
||||
glColor3fv(RGBMap[COLOR_GREEN]);
|
||||
glVertex3fv(p1);
|
||||
(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
|
||||
glColor3fv(RGBMap[COLOR_BLUE]);
|
||||
glVertex3fv(p2);
|
||||
EndPrim();
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -I../include
|
||||
LIBS = -L../lib -lGL -lglut -lm
|
||||
LIBS = -L../lib -lGL -lGLU -lglut -lm
|
||||
|
||||
PROGS = miniglxtest miniglxsample manytex
|
||||
PROGS = miniglxtest miniglxsample manytex texline
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: manytex.c,v 1.4 2002/10/18 17:47:36 kschultz Exp $ */
|
||||
/* $Id: manytex.c,v 1.4.4.1 2003/03/22 08:46:22 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* test handling of many texture maps
|
||||
@@ -191,8 +191,8 @@ static void Init( void )
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, TextureID[i]);
|
||||
|
||||
if (i < LowPriorityCount)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
|
||||
/* if (i < LowPriorityCount) */
|
||||
/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); */
|
||||
|
||||
if (RandomSize) {
|
||||
#if 0
|
||||
|
||||
@@ -79,6 +79,8 @@ MakeWindow(Display * dpy, unsigned int width, unsigned int height)
|
||||
/* Bind the rendering context and window */
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: miniglxtest.c,v 1.1.4.7 2003/02/21 22:18:24 keithw Exp $ */
|
||||
/* $Id: miniglxtest.c,v 1.1.4.9 2003/03/24 18:46:57 keithw Exp $ */
|
||||
|
||||
/*
|
||||
* Test the mini GLX interface.
|
||||
@@ -122,6 +122,8 @@ static Window make_rgb_db_window( Display *dpy,
|
||||
|
||||
glXMakeCurrent( dpy, win, ctx );
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
@@ -161,7 +163,6 @@ int foo( )
|
||||
|
||||
XMapWindow( dpy, win );
|
||||
|
||||
#if !USE_MINI_GLX
|
||||
{
|
||||
XEvent e;
|
||||
while (1) {
|
||||
@@ -171,8 +172,6 @@ int foo( )
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
event_loop( dpy, win );
|
||||
|
||||
|
||||
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);
|
||||
|
||||
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
1152
src/mesa/drivers/dri/r200/r200_vtxfmt.c
Normal file
1152
src/mesa/drivers/dri/r200/r200_vtxfmt.c
Normal file
File diff suppressed because it is too large
Load Diff
128
src/mesa/drivers/dri/r200/r200_vtxfmt.h
Normal file
128
src/mesa/drivers/dri/r200/r200_vtxfmt.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_VTXFMT_H__
|
||||
#define __R200_VTXFMT_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
|
||||
|
||||
extern struct r200_vb vb;
|
||||
|
||||
|
||||
extern void r200VtxfmtUpdate( GLcontext *ctx );
|
||||
extern void r200VtxfmtInit( GLcontext *ctx );
|
||||
extern void r200VtxfmtInvalidate( GLcontext *ctx );
|
||||
extern void r200VtxfmtDestroy( GLcontext *ctx );
|
||||
extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt );
|
||||
|
||||
extern void r200VtxfmtMakeCurrent( GLcontext *ctx );
|
||||
extern void r200VtxfmtUnbindContext( GLcontext *ctx );
|
||||
|
||||
extern void r200_copy_to_current( GLcontext *ctx );
|
||||
|
||||
#define DFN( FUNC, CACHE) \
|
||||
do { \
|
||||
char *start = (char *)&FUNC; \
|
||||
char *end = (char *)&FUNC##_end; \
|
||||
insert_at_head( &CACHE, dfn ); \
|
||||
dfn->key[0] = key[0]; \
|
||||
dfn->key[1] = key[1]; \
|
||||
dfn->code = ALIGN_MALLOC( end - start, 16 ); \
|
||||
memcpy (dfn->code, start, end - start); \
|
||||
} \
|
||||
while ( 0 )
|
||||
|
||||
#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \
|
||||
do { \
|
||||
int *icode = (int *)(CODE+OFFSET); \
|
||||
assert (*icode == CHECKVAL); \
|
||||
*icode = (int)NEWVAL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Useful for figuring out the offsets:
|
||||
*/
|
||||
#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \
|
||||
do { \
|
||||
while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \
|
||||
/*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \
|
||||
/* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/ \
|
||||
*(int *)(CODE+OFFSET) = (int)(NEWVAL); \
|
||||
OFFSET += 4; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
*/
|
||||
void r200InitCodegen( struct dfn_generators *gen );
|
||||
void r200InitX86Codegen( struct dfn_generators *gen );
|
||||
void r200InitSSECodegen( struct dfn_generators *gen );
|
||||
|
||||
|
||||
|
||||
/* Defined in r200_vtxfmt_x86.c
|
||||
*/
|
||||
struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color4f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color3f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * );
|
||||
struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * );
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
797
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
Normal file
797
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
Normal file
@@ -0,0 +1,797 @@
|
||||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
#include "simple_list.h"
|
||||
#include "api_noop.h"
|
||||
#include "vtxfmt.h"
|
||||
|
||||
#include "r200_vtxfmt.h"
|
||||
|
||||
/* Fallback versions of all the entrypoints for situations where
|
||||
* codegen isn't available. This is still a lot faster than the
|
||||
* vb/pipeline implementation in Mesa.
|
||||
*/
|
||||
static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&x;
|
||||
*vb.dmaptr++ = *(int *)&y;
|
||||
*vb.dmaptr++ = *(int *)&z;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex3fv( const GLfloat *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&v[0];
|
||||
*vb.dmaptr++ = *(int *)&v[1];
|
||||
*vb.dmaptr++ = *(int *)&v[2];
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex2f( GLfloat x, GLfloat y )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&x;
|
||||
*vb.dmaptr++ = *(int *)&y;
|
||||
*vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex2fv( const GLfloat *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&v[0];
|
||||
*vb.dmaptr++ = *(int *)&v[1];
|
||||
*vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color for ubyte (packed) color formats:
|
||||
*/
|
||||
static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_Color3ubv_ub( const GLubyte *v )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
dest->red = v[0];
|
||||
dest->green = v[1];
|
||||
dest->blue = v[2];
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = a;
|
||||
}
|
||||
|
||||
static void r200_Color4ubv_ub( const GLubyte *v )
|
||||
{
|
||||
*(GLuint *)vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
|
||||
}
|
||||
|
||||
|
||||
static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void r200_Color3fv_ub( const GLfloat *v )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a );
|
||||
}
|
||||
|
||||
static void r200_Color4fv_ub( const GLfloat *v )
|
||||
{
|
||||
r200_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* Color for float color+alpha formats:
|
||||
*/
|
||||
static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_Color3ubv_4f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
dest[3] = UBYTE_TO_FLOAT(a);
|
||||
}
|
||||
|
||||
static void r200_Color4ubv_4f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
dest[3] = UBYTE_TO_FLOAT(v[3]);
|
||||
}
|
||||
|
||||
|
||||
static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_Color3fv_4f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = a;
|
||||
}
|
||||
|
||||
static void r200_Color4fv_4f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = v[3];
|
||||
}
|
||||
|
||||
|
||||
/* Color for float color formats:
|
||||
*/
|
||||
static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
}
|
||||
|
||||
static void r200_Color3ubv_3f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
}
|
||||
|
||||
static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
|
||||
}
|
||||
|
||||
static void r200_Color4ubv_3f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
|
||||
}
|
||||
|
||||
|
||||
static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
}
|
||||
|
||||
static void r200_Color3fv_3f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
}
|
||||
|
||||
static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
|
||||
}
|
||||
|
||||
static void r200_Color4fv_3f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
|
||||
}
|
||||
|
||||
|
||||
/* Secondary Color:
|
||||
*/
|
||||
static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
r200_color_t *dest = vb.specptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v )
|
||||
{
|
||||
r200_color_t *dest = vb.specptr;
|
||||
dest->red = v[0];
|
||||
dest->green = v[1];
|
||||
dest->blue = v[2];
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
r200_color_t *dest = vb.specptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v )
|
||||
{
|
||||
r200_color_t *dest = vb.specptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GLfloat *dest = vb.floatspecptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatspecptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GLfloat *dest = vb.floatspecptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatspecptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Normal
|
||||
*/
|
||||
static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
|
||||
{
|
||||
GLfloat *dest = vb.normalptr;
|
||||
dest[0] = n0;
|
||||
dest[1] = n1;
|
||||
dest[2] = n2;
|
||||
}
|
||||
|
||||
static void r200_Normal3fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.normalptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
/* TexCoord
|
||||
*/
|
||||
static void r200_TexCoord1f( GLfloat s )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_TexCoord1fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_TexCoord2f( GLfloat s, GLfloat t )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void r200_TexCoord2fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
}
|
||||
|
||||
|
||||
/* MultiTexcoord
|
||||
*/
|
||||
static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
}
|
||||
|
||||
static struct dynfn *lookup( struct dynfn *l, const int *key )
|
||||
{
|
||||
struct dynfn *f;
|
||||
|
||||
foreach( f, l ) {
|
||||
if (f->key[0] == key[0] && f->key[1] == key[1])
|
||||
return f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Can't use the loopback template for this:
|
||||
*/
|
||||
|
||||
#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
|
||||
static void choose_##FN ARGS1 \
|
||||
{ \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(vb.context); \
|
||||
int key[2]; \
|
||||
struct dynfn *dfn; \
|
||||
\
|
||||
key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
|
||||
key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
|
||||
\
|
||||
dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
|
||||
if (dfn == 0) \
|
||||
dfn = rmesa->vb.codegen.FN( vb.context, key ); \
|
||||
else if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
|
||||
\
|
||||
if (dfn) \
|
||||
vb.context->Exec->FN = (FNTYPE)(dfn->code); \
|
||||
else { \
|
||||
if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
|
||||
vb.context->Exec->FN = r200_##FN; \
|
||||
} \
|
||||
\
|
||||
vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
vb.context->Exec->FN ARGS2; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* For the _3f case, only allow one color function to be hooked in at
|
||||
* a time. Eventually, use a similar mechanism to allow selecting the
|
||||
* color component of the vertex format based on client behaviour.
|
||||
*
|
||||
* Note: Perform these actions even if there is a codegen or cached
|
||||
* codegen version of the chosen function.
|
||||
*/
|
||||
#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \
|
||||
static void choose_##FN ARGS1 \
|
||||
{ \
|
||||
GLcontext *ctx = vb.context; \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(vb.context); \
|
||||
int key[2]; \
|
||||
struct dynfn *dfn; \
|
||||
\
|
||||
key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
|
||||
key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
|
||||
\
|
||||
if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \
|
||||
ctx->Exec->FN = r200_##FN##_ub; \
|
||||
} \
|
||||
else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \
|
||||
\
|
||||
if (rmesa->vb.installed_color_3f_sz != NR) { \
|
||||
rmesa->vb.installed_color_3f_sz = NR; \
|
||||
if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
|
||||
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
|
||||
r200_copy_to_current( ctx ); \
|
||||
_mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
|
||||
ctx->Exec->FN ARGS2; \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
ctx->Exec->FN = r200_##FN##_3f; \
|
||||
} \
|
||||
else { \
|
||||
ctx->Exec->FN = r200_##FN##_4f; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
|
||||
if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
|
||||
\
|
||||
if (dfn) { \
|
||||
if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
|
||||
ctx->Exec->FN = (FNTYPE)dfn->code; \
|
||||
} \
|
||||
else if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
|
||||
\
|
||||
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
ctx->Exec->FN ARGS2; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Right now there are both _ub and _3f versions of the secondary color
|
||||
* functions. Currently, we only set-up the hardware to use the _ub versions.
|
||||
* The _3f versions are needed for the cases where secondary color isn't used
|
||||
* in the vertex format, but it still needs to be stored in the context
|
||||
* state vector.
|
||||
*/
|
||||
#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
|
||||
static void choose_##FN ARGS1 \
|
||||
{ \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(vb.context); \
|
||||
int key[2]; \
|
||||
struct dynfn *dfn; \
|
||||
\
|
||||
key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
|
||||
key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
|
||||
\
|
||||
dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
|
||||
if (dfn == 0) \
|
||||
dfn = rmesa->vb.codegen.FN( vb.context, key ); \
|
||||
else if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
|
||||
\
|
||||
if (dfn) \
|
||||
vb.context->Exec->FN = (FNTYPE)(dfn->code); \
|
||||
else { \
|
||||
if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
|
||||
vb.context->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \
|
||||
? r200_##FN##_ub : r200_##FN##_3f; \
|
||||
} \
|
||||
\
|
||||
vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
vb.context->Exec->FN ARGS2; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* VTXFMT_0
|
||||
*/
|
||||
#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0)
|
||||
#define MASK_NORM (MASK_XYZW|R200_VTX_N0)
|
||||
#define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
|
||||
#define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT))
|
||||
|
||||
/* VTXFMT_1
|
||||
*/
|
||||
#define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT)
|
||||
|
||||
|
||||
|
||||
typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
|
||||
typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
|
||||
typedef void (*p2f)( GLfloat, GLfloat );
|
||||
typedef void (*p1f)( GLfloat );
|
||||
typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
|
||||
typedef void (*pe1f)( GLenum, GLfloat );
|
||||
typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
|
||||
typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
|
||||
typedef void (*pfv)( const GLfloat * );
|
||||
typedef void (*pefv)( GLenum, const GLfloat * );
|
||||
typedef void (*pubv)( const GLubyte * );
|
||||
|
||||
|
||||
CHOOSE(Normal3f, p3f, MASK_NORM, 0,
|
||||
(GLfloat a,GLfloat b,GLfloat c), (a,b,c))
|
||||
CHOOSE(Normal3fv, pfv, MASK_NORM, 0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0,
|
||||
(GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
|
||||
CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0,
|
||||
(const GLubyte *v), (v))
|
||||
CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0,
|
||||
(GLubyte a,GLubyte b, GLubyte c), (a,b,c))
|
||||
CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0,
|
||||
(const GLubyte *v), (v))
|
||||
|
||||
CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0,
|
||||
(GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
|
||||
CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0,
|
||||
(GLfloat a,GLfloat b, GLfloat c), (a,b,c))
|
||||
CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
|
||||
CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0,
|
||||
(GLubyte a,GLubyte b, GLubyte c), (a,b,c))
|
||||
CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0,
|
||||
(const GLubyte *v), (v))
|
||||
CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0,
|
||||
(GLfloat a,GLfloat b, GLfloat c), (a,b,c))
|
||||
CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0,
|
||||
(GLfloat a,GLfloat b), (a,b))
|
||||
CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0,
|
||||
(GLfloat a), (a))
|
||||
CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0,
|
||||
(GLenum u,GLfloat a,GLfloat b), (u,a,b))
|
||||
CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0,
|
||||
(GLenum u,const GLfloat *v), (u,v))
|
||||
CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0,
|
||||
(GLenum u,GLfloat a), (u,a))
|
||||
CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0,
|
||||
(GLenum u,const GLfloat *v), (u,v))
|
||||
|
||||
CHOOSE(Vertex3f, p3f, ~0, ~0,
|
||||
(GLfloat a,GLfloat b,GLfloat c), (a,b,c))
|
||||
CHOOSE(Vertex3fv, pfv, ~0, ~0,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE(Vertex2f, p2f, ~0, ~0,
|
||||
(GLfloat a,GLfloat b), (a,b))
|
||||
CHOOSE(Vertex2fv, pfv, ~0, ~0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void r200VtxfmtInitChoosers( GLvertexformat *vfmt )
|
||||
{
|
||||
vfmt->Color3f = choose_Color3f;
|
||||
vfmt->Color3fv = choose_Color3fv;
|
||||
vfmt->Color3ub = choose_Color3ub;
|
||||
vfmt->Color3ubv = choose_Color3ubv;
|
||||
vfmt->Color4f = choose_Color4f;
|
||||
vfmt->Color4fv = choose_Color4fv;
|
||||
vfmt->Color4ub = choose_Color4ub;
|
||||
vfmt->Color4ubv = choose_Color4ubv;
|
||||
vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
|
||||
vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
|
||||
vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
|
||||
vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
|
||||
vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
|
||||
vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
|
||||
vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
|
||||
vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
|
||||
vfmt->Normal3f = choose_Normal3f;
|
||||
vfmt->Normal3fv = choose_Normal3fv;
|
||||
vfmt->TexCoord1f = choose_TexCoord1f;
|
||||
vfmt->TexCoord1fv = choose_TexCoord1fv;
|
||||
vfmt->TexCoord2f = choose_TexCoord2f;
|
||||
vfmt->TexCoord2fv = choose_TexCoord2fv;
|
||||
vfmt->Vertex2f = choose_Vertex2f;
|
||||
vfmt->Vertex2fv = choose_Vertex2fv;
|
||||
vfmt->Vertex3f = choose_Vertex3f;
|
||||
vfmt->Vertex3fv = choose_Vertex3fv;
|
||||
}
|
||||
|
||||
|
||||
static struct dynfn *codegen_noop( GLcontext *ctx, const int *key )
|
||||
{
|
||||
(void) ctx; (void) key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void r200InitCodegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Vertex3f = codegen_noop;
|
||||
gen->Vertex3fv = codegen_noop;
|
||||
gen->Color4ub = codegen_noop;
|
||||
gen->Color4ubv = codegen_noop;
|
||||
gen->Normal3f = codegen_noop;
|
||||
gen->Normal3fv = codegen_noop;
|
||||
gen->TexCoord2f = codegen_noop;
|
||||
gen->TexCoord2fv = codegen_noop;
|
||||
gen->MultiTexCoord2fARB = codegen_noop;
|
||||
gen->MultiTexCoord2fvARB = codegen_noop;
|
||||
gen->Vertex2f = codegen_noop;
|
||||
gen->Vertex2fv = codegen_noop;
|
||||
gen->Color3ub = codegen_noop;
|
||||
gen->Color3ubv = codegen_noop;
|
||||
gen->Color4f = codegen_noop;
|
||||
gen->Color4fv = codegen_noop;
|
||||
gen->Color3f = codegen_noop;
|
||||
gen->Color3fv = codegen_noop;
|
||||
gen->SecondaryColor3fEXT = codegen_noop;
|
||||
gen->SecondaryColor3fvEXT = codegen_noop;
|
||||
gen->SecondaryColor3ubEXT = codegen_noop;
|
||||
gen->SecondaryColor3ubvEXT = codegen_noop;
|
||||
gen->TexCoord1f = codegen_noop;
|
||||
gen->TexCoord1fv = codegen_noop;
|
||||
gen->MultiTexCoord1fARB = codegen_noop;
|
||||
gen->MultiTexCoord1fvARB = codegen_noop;
|
||||
|
||||
if (!getenv("R200_NO_CODEGEN")) {
|
||||
#if defined(USE_X86_ASM)
|
||||
r200InitX86Codegen( gen );
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSE_ASM)
|
||||
r200InitSSECodegen( gen );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user