mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 03:08:05 +02:00
r200 driver, brought over by Jon Smirl
This commit is contained in:
parent
a7ea785a10
commit
adbec39bbf
41 changed files with 22884 additions and 0 deletions
232
src/mesa/drivers/dri/r200/Doxyfile
Normal file
232
src/mesa/drivers/dri/r200/Doxyfile
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
# Doxyfile 1.3.2-Gideon
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = r200
|
||||
PROJECT_NUMBER = $VERSION$
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_LANGUAGE = English
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = 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
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = /home/temp/Mesa/src/drv/r200
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.C \
|
||||
*.H \
|
||||
*.tlh \
|
||||
*.diff \
|
||||
*.patch \
|
||||
*.moc \
|
||||
*.xpm
|
||||
RECURSIVE = yes
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
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
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
VERBATIM_HEADERS = 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 = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
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 = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
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
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = yes
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# 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 =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME = search.cgi
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
EXT_DOC_PATHS =
|
||||
136
src/mesa/drivers/dri/r200/Makefile.X11
Normal file
136
src/mesa/drivers/dri/r200/Makefile.X11
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# $Id: Makefile.X11,v 1.1 2003/08/06 17:59:57 keithw Exp $
|
||||
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 5.0
|
||||
# Copyright (C) 1995-2002 Brian Paul
|
||||
|
||||
TOP = ../../../../..
|
||||
|
||||
SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
|
||||
MINIGLX_INCLUDES = -I$(TOP)/src/miniglx
|
||||
|
||||
DEFINES += \
|
||||
-D_HAVE_SWRAST=1 \
|
||||
-D_HAVE_SWTNL=1 \
|
||||
-D_HAVE_SANITY=1 \
|
||||
-D_HAVE_CODEGEN=1 \
|
||||
-D_HAVE_LIGHTING=1 \
|
||||
-D_HAVE_TEXGEN=1 \
|
||||
-D_HAVE_USERCLIP=1 \
|
||||
-DGLX_DIRECT_RENDERING
|
||||
|
||||
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 \
|
||||
../common/utils.c \
|
||||
../common/texmem.c \
|
||||
../common/vblank.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 = $(TOP)/src/mesa/mesa.a
|
||||
|
||||
|
||||
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/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/$@ $@
|
||||
|
||||
|
||||
### Include directories
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main \
|
||||
-I$(TOP)/src/mesa/glapi \
|
||||
-I$(TOP)/src/mesa/math \
|
||||
-I$(TOP)/src/mesa/transform \
|
||||
-I$(TOP)/src/mesa/swrast \
|
||||
-I$(TOP)/src/mesa/swrast_setup
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
targets: r200_dri.so
|
||||
|
||||
r200_dri.so: $(SYMLINKS) $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
|
||||
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS)
|
||||
rm -f $(TOP)/lib/r200_dri.so && \
|
||||
install r200_dri.so $(TOP)/lib/r200_dri.so
|
||||
|
||||
# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
|
||||
# what's included by any source file.
|
||||
dep: $(C_SOURCES) $(ASM_SOURCES)
|
||||
makedepend -fdepend -Y $(SHARED_INCLUDES) \
|
||||
$(C_SOURCES) $(ASM_SOURCES)
|
||||
|
||||
|
||||
# Emacs tags
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` `find ../include`
|
||||
|
||||
|
||||
# Remove .o and backup files
|
||||
clean:
|
||||
-rm -f *.o *~ *.o *~ *.so
|
||||
|
||||
|
||||
include $(TOP)/Make-config
|
||||
|
||||
include depend
|
||||
337
src/mesa/drivers/dri/r200/r200_cmdbuf.c
Normal file
337
src/mesa/drivers/dri/r200/r200_cmdbuf.c
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/* $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));
|
||||
}
|
||||
|
||||
|
||||
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, "%s: Syncing\n", __FUNCTION__);
|
||||
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->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
|
||||
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;
|
||||
}
|
||||
}
|
||||
595
src/mesa/drivers/dri/r200/r200_context.c
Normal file
595
src/mesa/drivers/dri/r200/r200_context.c
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
/* $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 "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"
|
||||
|
||||
#define DRIVER_DATE "20030328"
|
||||
|
||||
#include "vblank.h"
|
||||
#include "utils.h"
|
||||
#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];
|
||||
unsigned offset;
|
||||
GLuint agp_mode = rmesa->r200Screen->IsPCI ? 0 :
|
||||
rmesa->r200Screen->AGPMode;
|
||||
|
||||
switch ( name ) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *)"Tungsten Graphics, Inc.";
|
||||
|
||||
case GL_RENDERER:
|
||||
offset = driGetRendererString( buffer, "R200", DRIVER_DATE,
|
||||
agp_mode );
|
||||
|
||||
sprintf( & buffer[ offset ], " %sTCL",
|
||||
!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
|
||||
? "" : "NO-" );
|
||||
|
||||
return (GLubyte *)buffer;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Extension strings exported by the R200 driver.
|
||||
*/
|
||||
static const char * const card_extensions[] =
|
||||
{
|
||||
"GL_ARB_multisample",
|
||||
"GL_ARB_multitexture",
|
||||
"GL_ARB_texture_border_clamp",
|
||||
"GL_ARB_texture_compression",
|
||||
"GL_ARB_texture_env_add",
|
||||
"GL_ARB_texture_env_combine",
|
||||
"GL_ARB_texture_env_dot3",
|
||||
"GL_ARB_texture_mirrored_repeat",
|
||||
"GL_EXT_blend_logic_op",
|
||||
"GL_EXT_blend_minmax",
|
||||
"GL_EXT_blend_subtract",
|
||||
"GL_EXT_secondary_color",
|
||||
"GL_EXT_stencil_wrap",
|
||||
"GL_EXT_texture_edge_clamp",
|
||||
"GL_EXT_texture_env_add",
|
||||
"GL_EXT_texture_env_combine",
|
||||
"GL_EXT_texture_env_dot3",
|
||||
"GL_EXT_texture_filter_anisotropic",
|
||||
"GL_EXT_texture_lod_bias",
|
||||
"GL_ATI_texture_env_combine3",
|
||||
"GL_ATI_texture_mirror_once",
|
||||
"GL_IBM_texture_mirrored_repeat",
|
||||
"GL_MESA_pack_invert",
|
||||
"GL_MESA_ycbcr_texture",
|
||||
"GL_NV_blend_square",
|
||||
"GL_NV_texture_rectangle",
|
||||
"GL_SGIS_generate_mipmap",
|
||||
"GL_SGIS_texture_border_clamp",
|
||||
"GL_SGIS_texture_edge_clamp",
|
||||
NULL
|
||||
};
|
||||
|
||||
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, */ /* FIXME: bugs with ut2003 */
|
||||
&_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 const struct dri_debug_control debug_control[] =
|
||||
{
|
||||
{ "fall", DEBUG_FALLBACKS },
|
||||
{ "tex", DEBUG_TEXTURE },
|
||||
{ "ioctl", DEBUG_IOCTL },
|
||||
{ "prim", DEBUG_PRIMS },
|
||||
{ "vert", DEBUG_VERTS },
|
||||
{ "state", DEBUG_STATE },
|
||||
{ "code", DEBUG_CODEGEN },
|
||||
{ "vfmt", DEBUG_VFMT },
|
||||
{ "vtxf", DEBUG_VFMT },
|
||||
{ "verb", DEBUG_VERBOSE },
|
||||
{ "dri", DEBUG_DRI },
|
||||
{ "dma", DEBUG_DMA },
|
||||
{ "san", DEBUG_SANITY },
|
||||
{ "sync", DEBUG_SYNC },
|
||||
{ "pix", DEBUG_PIXEL },
|
||||
{ "mem", DEBUG_MEMORY },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
get_ust_nop( int64_t * ust )
|
||||
{
|
||||
*ust = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create the device specific context.
|
||||
*/
|
||||
GLboolean r200CreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
|
||||
r200ContextPtr rmesa;
|
||||
GLcontext *ctx, *shareCtx;
|
||||
int i;
|
||||
|
||||
assert(glVisual);
|
||||
assert(driContextPriv);
|
||||
assert(screen);
|
||||
|
||||
/* 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 = screen;
|
||||
rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA +
|
||||
screen->sarea_priv_offset);
|
||||
|
||||
|
||||
rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
|
||||
|
||||
(void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
|
||||
make_empty_list( & rmesa->swapped );
|
||||
|
||||
rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
|
||||
for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
|
||||
rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
|
||||
screen->texSize[i],
|
||||
12,
|
||||
RADEON_NR_TEX_REGIONS,
|
||||
rmesa->sarea->texList[i],
|
||||
& rmesa->sarea->texAge[i],
|
||||
& rmesa->swapped,
|
||||
sizeof( r200TexObj ),
|
||||
(destroy_texture_object_t *) r200DestroyTexObj );
|
||||
}
|
||||
|
||||
rmesa->swtcl.RenderIndex = ~0;
|
||||
rmesa->lost_context = 1;
|
||||
|
||||
/* Set the maximum texture size small enough that we can guarentee that
|
||||
* all texture units can bind a maximal texture and have them both in
|
||||
* texturable memory at once.
|
||||
*/
|
||||
|
||||
ctx = rmesa->glCtx;
|
||||
ctx->Const.MaxTextureUnits = 2;
|
||||
|
||||
driCalculateMaxTextureLevels( rmesa->texture_heaps,
|
||||
rmesa->nr_heaps,
|
||||
& ctx->Const,
|
||||
4,
|
||||
11, /* max 2D texture size is 2048x2048 */
|
||||
#if ENABLE_HW_3D_TEXTURE
|
||||
8, /* max 3D texture size is 256^3 */
|
||||
#else
|
||||
0, /* 3D textures unsupported */
|
||||
#endif
|
||||
11, /* max cube texture size is 2048x2048 */
|
||||
11, /* max texture rectangle size is 2048x2048 */
|
||||
12,
|
||||
GL_FALSE );
|
||||
|
||||
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 );
|
||||
|
||||
driInitExtensions( ctx, card_extensions, GL_TRUE );
|
||||
if (rmesa->r200Screen->drmSupportsCubeMaps)
|
||||
_mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
|
||||
|
||||
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->vblank_flags = (rmesa->do_irqs)
|
||||
? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ;
|
||||
|
||||
rmesa->prefer_agp_client_texturing =
|
||||
(getenv("R200_AGP_CLIENT_TEXTURES") != 0);
|
||||
|
||||
#ifndef _SOLO
|
||||
rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" );
|
||||
if ( rmesa->get_ust == NULL ) {
|
||||
rmesa->get_ust = get_ust_nop;
|
||||
}
|
||||
|
||||
(*rmesa->get_ust)( & rmesa->swap_ust );
|
||||
#endif
|
||||
|
||||
#if DO_DEBUG
|
||||
R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ),
|
||||
debug_control );
|
||||
R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
|
||||
debug_control );
|
||||
#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 ) {
|
||||
GLboolean release_texture_heaps;
|
||||
|
||||
|
||||
release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
|
||||
_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;
|
||||
}
|
||||
|
||||
if ( release_texture_heaps ) {
|
||||
/* This share group is about to go away, free our private
|
||||
* texture object data.
|
||||
*/
|
||||
int i;
|
||||
|
||||
assert( is_empty_list( & rmesa->swapped ) );
|
||||
|
||||
for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
|
||||
driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
|
||||
rmesa->texture_heaps[ i ] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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, "%s: drawable has no context!", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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 newCtx =
|
||||
(r200ContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (R200_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newCtx->glCtx);
|
||||
|
||||
if ( newCtx->dri.drawable != driDrawPriv ) {
|
||||
newCtx->dri.drawable = driDrawPriv;
|
||||
r200UpdateWindow( newCtx->glCtx );
|
||||
r200UpdateViewportOffset( newCtx->glCtx );
|
||||
}
|
||||
|
||||
_mesa_make_current2( newCtx->glCtx,
|
||||
(GLframebuffer *) driDrawPriv->driverPrivate,
|
||||
(GLframebuffer *) driReadPriv->driverPrivate );
|
||||
|
||||
if ( !newCtx->glCtx->Viewport.Width ) {
|
||||
_mesa_set_viewport( newCtx->glCtx, 0, 0,
|
||||
driDrawPriv->w, driDrawPriv->h );
|
||||
}
|
||||
|
||||
if (newCtx->vb.enabled)
|
||||
r200VtxfmtMakeCurrent( newCtx->glCtx );
|
||||
|
||||
_mesa_update_state( newCtx->glCtx );
|
||||
r200ValidateState( newCtx->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;
|
||||
}
|
||||
926
src/mesa/drivers/dri/r200/r200_context.h
Normal file
926
src/mesa/drivers/dri/r200/r200_context.h
Normal file
|
|
@ -0,0 +1,926 @@
|
|||
/* $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 <inttypes.h>
|
||||
#include "dri_util.h"
|
||||
#include "radeon_common.h"
|
||||
#include "texmem.h"
|
||||
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.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
|
||||
#define R200_FALLBACK_BORDER_MODE 0x80
|
||||
|
||||
/* 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 {
|
||||
driTextureObject base;
|
||||
|
||||
GLuint bufAddr; /* Offset to start of locally
|
||||
shared texture block */
|
||||
|
||||
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. */
|
||||
|
||||
drmRadeonTexImage image[6][RADEON_MAX_TEXTURE_LEVELS];
|
||||
/* Six, for the 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 */
|
||||
|
||||
GLboolean border_fallback;
|
||||
};
|
||||
|
||||
|
||||
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 driver name prefix off the front of
|
||||
* everything - I think we know which driver we're in 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;
|
||||
};
|
||||
|
||||
/* 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 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_prim {
|
||||
GLuint start;
|
||||
GLuint end;
|
||||
GLuint prim;
|
||||
};
|
||||
|
||||
struct r200_vbinfo {
|
||||
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];
|
||||
|
||||
|
||||
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
|
||||
GLuint primflags;
|
||||
GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */
|
||||
GLboolean installed;
|
||||
GLboolean fell_back;
|
||||
GLboolean recheck;
|
||||
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
|
||||
*/
|
||||
unsigned nr_heaps;
|
||||
driTexHeap * texture_heaps[ R200_NR_TEX_HEAPS ];
|
||||
driTextureObject swapped;
|
||||
|
||||
|
||||
/* 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 / buffer swap
|
||||
*/
|
||||
GLuint vbl_seq;
|
||||
GLuint vblank_flags;
|
||||
|
||||
uint64_t swap_ust;
|
||||
uint64_t swap_missed_ust;
|
||||
|
||||
GLuint swap_count;
|
||||
GLuint swap_missed_count;
|
||||
|
||||
PFNGLXGETUSTPROC get_ust;
|
||||
|
||||
/* 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__ */
|
||||
925
src/mesa/drivers/dri/r200/r200_ioctl.c
Normal file
925
src/mesa/drivers/dri/r200/r200_ioctl.c
Normal file
|
|
@ -0,0 +1,925 @@
|
|||
/* $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 <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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 "vblank.h"
|
||||
|
||||
|
||||
#define R200_TIMEOUT 512
|
||||
#define R200_IDLE_RETRY 16
|
||||
|
||||
|
||||
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 (! driValidateTextureHeaps( rmesa->texture_heaps, rmesa->nr_heaps,
|
||||
& rmesa->swapped ) ) {
|
||||
fprintf( stderr, "%s: texture memory is inconsistent - expect "
|
||||
"mangled textures\n", __FUNCTION__ );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 = 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 );
|
||||
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;
|
||||
|
||||
assert( rmesa->dma.current.ptr <= rmesa->dma.current.end );
|
||||
}
|
||||
|
||||
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 CARD32 r200GetLastFrame(r200ContextPtr rmesa)
|
||||
{
|
||||
drmRadeonGetParam gp;
|
||||
int ret;
|
||||
CARD32 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 );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Copy the back color buffer to the front color buffer.
|
||||
*/
|
||||
void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
r200ContextPtr rmesa;
|
||||
GLint nbox, i, ret;
|
||||
GLboolean missed_target;
|
||||
int64_t ust;
|
||||
|
||||
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 );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
nbox = dPriv->numClipRects; /* must be in locked region */
|
||||
|
||||
for ( i = 0 ; i < nbox ; ) {
|
||||
GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
|
||||
XF86DRIClipRectPtr box = dPriv->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;
|
||||
|
||||
rmesa->swap_count++;
|
||||
(*rmesa->get_ust)( & ust );
|
||||
if ( missed_target ) {
|
||||
rmesa->swap_missed_count++;
|
||||
rmesa->swap_missed_ust = ust - rmesa->swap_ust;
|
||||
}
|
||||
|
||||
rmesa->swap_ust = ust;
|
||||
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
void r200PageFlip( const __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
r200ContextPtr rmesa;
|
||||
GLint ret;
|
||||
GLboolean missed_target;
|
||||
|
||||
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 (!dPriv->numClipRects) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
usleep( 10000 ); /* throttle invisible client 10ms */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to do this for the perf box placement:
|
||||
*/
|
||||
{
|
||||
XF86DRIClipRectPtr box = dPriv->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 );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
|
||||
if ( missed_target ) {
|
||||
rmesa->swap_missed_count++;
|
||||
(void) (*rmesa->get_ust)( & rmesa->swap_missed_ust );
|
||||
}
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
rmesa->swap_count++;
|
||||
(void) (*rmesa->get_ust)( & rmesa->swap_ust );
|
||||
|
||||
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 ) {
|
||||
if (R200_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, 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 );
|
||||
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 );
|
||||
} 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 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;
|
||||
}
|
||||
|
||||
191
src/mesa/drivers/dri/r200/r200_ioctl.h
Normal file
191
src/mesa/drivers/dri/r200/r200_ioctl.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/* $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 )
|
||||
{
|
||||
char * head;
|
||||
|
||||
if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
|
||||
r200FlushCmdBuf( rmesa, where );
|
||||
|
||||
head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
|
||||
rmesa->store.cmd_used += bytes;
|
||||
assert( rmesa->store.cmd_used <= R200_CMD_BUF_SZ );
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __R200_IOCTL_H__ */
|
||||
116
src/mesa/drivers/dri/r200/r200_lock.c
Normal file
116
src/mesa/drivers/dri/r200/r200_lock.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* $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;
|
||||
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->nr_heaps ; i++ ) {
|
||||
DRI_AGE_TEXTURES( rmesa->texture_heaps[ i ] );
|
||||
}
|
||||
}
|
||||
112
src/mesa/drivers/dri/r200/r200_lock.h
Normal file
112
src/mesa/drivers/dri/r200/r200_lock.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/* $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
|
||||
48
src/mesa/drivers/dri/r200/r200_maos.h
Normal file
48
src/mesa/drivers/dri/r200/r200_maos.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* $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
|
||||
478
src/mesa/drivers/dri/r200/r200_maos_arrays.c
Normal file
478
src/mesa/drivers/dri/r200/r200_maos_arrays.c
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
/* $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 "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;
|
||||
}
|
||||
|
||||
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
|
||||
340
src/mesa/drivers/dri/r200/r200_maos_verts.c
Normal file
340
src/mesa/drivers/dri/r200/r200_maos_verts.c
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* $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
|
||||
1444
src/mesa/drivers/dri/r200/r200_reg.h
Normal file
1444
src/mesa/drivers/dri/r200/r200_reg.h
Normal file
File diff suppressed because it is too large
Load diff
1325
src/mesa/drivers/dri/r200/r200_sanity.c
Normal file
1325
src/mesa/drivers/dri/r200/r200_sanity.c
Normal file
File diff suppressed because it is too large
Load diff
8
src/mesa/drivers/dri/r200/r200_sanity.h
Normal file
8
src/mesa/drivers/dri/r200/r200_sanity.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef R200_SANITY_H
|
||||
#define R200_SANITY_H
|
||||
|
||||
extern int r200SanityCmdBuffer( r200ContextPtr rmesa,
|
||||
int nbox,
|
||||
XF86DRIClipRectRec *boxes );
|
||||
|
||||
#endif
|
||||
462
src/mesa/drivers/dri/r200/r200_screen.c
Normal file
462
src/mesa/drivers/dri/r200/r200_screen.c
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
|
||||
#include "r200_screen.h"
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "vblank.h"
|
||||
|
||||
#ifndef _SOLO
|
||||
#include "glxextensions.h"
|
||||
#endif
|
||||
|
||||
#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 /* Radeon 7500 - not an R200 at all */
|
||||
#endif
|
||||
|
||||
static r200ScreenPtr __r200Screen;
|
||||
|
||||
static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
|
||||
|
||||
/* Create the device specific screen private data struct.
|
||||
*/
|
||||
static r200ScreenPtr
|
||||
r200CreateScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
r200ScreenPtr screen;
|
||||
RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
|
||||
|
||||
if ( ! driCheckDriDdxDrmVersions( sPriv, "R200", 4, 0, 4, 0, 1, 5 ) )
|
||||
return NULL;
|
||||
|
||||
/* Allocate the private area */
|
||||
screen = (r200ScreenPtr) CALLOC( sizeof(*screen) );
|
||||
if ( !screen ) {
|
||||
__driUtilMessage("%s: Could not allocate memory for screen structure",
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch ( dri_priv->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( screen );
|
||||
return NULL;
|
||||
default:
|
||||
screen->chipset = R200_CHIPSET_R200;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* This is first since which regions we map depends on whether or
|
||||
* not we are using a PCI card.
|
||||
*/
|
||||
screen->IsPCI = dri_priv->IsPCI;
|
||||
|
||||
{
|
||||
int ret;
|
||||
drmRadeonGetParam gp;
|
||||
|
||||
gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET;
|
||||
gp.value = &screen->agp_buffer_offset;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( screen );
|
||||
fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->agp_texture_offset =
|
||||
screen->agp_buffer_offset + 2*1024*1024;
|
||||
|
||||
|
||||
if (sPriv->drmMinor >= 6) {
|
||||
gp.param = RADEON_PARAM_AGP_BASE;
|
||||
gp.value = &screen->agp_base;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( screen );
|
||||
fprintf(stderr, "drmR200GetParam (RADEON_PARAM_AGP_BASE): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
gp.param = RADEON_PARAM_IRQ_NR;
|
||||
gp.value = &screen->irq;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE( screen );
|
||||
fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if kernel module is new enough to support cube maps */
|
||||
screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
|
||||
}
|
||||
}
|
||||
|
||||
screen->mmio.handle = dri_priv->registerHandle;
|
||||
screen->mmio.size = dri_priv->registerSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
screen->mmio.handle,
|
||||
screen->mmio.size,
|
||||
&screen->mmio.map ) ) {
|
||||
FREE( screen );
|
||||
__driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->status.handle = dri_priv->statusHandle;
|
||||
screen->status.size = dri_priv->statusSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
screen->status.handle,
|
||||
screen->status.size,
|
||||
&screen->status.map ) ) {
|
||||
drmUnmap( screen->mmio.map, screen->mmio.size );
|
||||
FREE( screen );
|
||||
__driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
|
||||
return NULL;
|
||||
}
|
||||
screen->scratch = (__volatile__ CARD32 *)
|
||||
((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
||||
|
||||
screen->buffers = drmMapBufs( sPriv->fd );
|
||||
if ( !screen->buffers ) {
|
||||
drmUnmap( screen->status.map, screen->status.size );
|
||||
drmUnmap( screen->mmio.map, screen->mmio.size );
|
||||
FREE( screen );
|
||||
__driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !screen->IsPCI ) {
|
||||
screen->agpTextures.handle = dri_priv->agpTexHandle;
|
||||
screen->agpTextures.size = dri_priv->agpTexMapSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
screen->agpTextures.handle,
|
||||
screen->agpTextures.size,
|
||||
(drmAddressPtr)&screen->agpTextures.map ) ) {
|
||||
drmUnmapBufs( screen->buffers );
|
||||
drmUnmap( screen->status.map, screen->status.size );
|
||||
drmUnmap( screen->mmio.map, screen->mmio.size );
|
||||
FREE( screen );
|
||||
__driUtilMessage("%s: IsPCI failed\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
screen->cpp = dri_priv->bpp / 8;
|
||||
screen->AGPMode = dri_priv->AGPMode;
|
||||
|
||||
screen->frontOffset = dri_priv->frontOffset;
|
||||
screen->frontPitch = dri_priv->frontPitch;
|
||||
screen->backOffset = dri_priv->backOffset;
|
||||
screen->backPitch = dri_priv->backPitch;
|
||||
screen->depthOffset = dri_priv->depthOffset;
|
||||
screen->depthPitch = dri_priv->depthPitch;
|
||||
|
||||
screen->texOffset[RADEON_CARD_HEAP] = dri_priv->textureOffset;
|
||||
screen->texSize[RADEON_CARD_HEAP] = dri_priv->textureSize;
|
||||
screen->logTexGranularity[RADEON_CARD_HEAP] =
|
||||
dri_priv->log2TexGran;
|
||||
|
||||
if ( screen->IsPCI ) {
|
||||
screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
|
||||
screen->texOffset[RADEON_AGP_HEAP] = 0;
|
||||
screen->texSize[RADEON_AGP_HEAP] = 0;
|
||||
screen->logTexGranularity[RADEON_AGP_HEAP] = 0;
|
||||
} else {
|
||||
screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
|
||||
screen->texOffset[RADEON_AGP_HEAP] =
|
||||
dri_priv->agpTexOffset + R200_AGP_TEX_OFFSET;
|
||||
screen->texSize[RADEON_AGP_HEAP] = dri_priv->agpTexMapSize;
|
||||
screen->logTexGranularity[RADEON_AGP_HEAP] =
|
||||
dri_priv->log2AGPTexGran;
|
||||
}
|
||||
|
||||
screen->driScreen = sPriv;
|
||||
screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
|
||||
return screen;
|
||||
}
|
||||
|
||||
/* Destroy the device specific screen private data struct.
|
||||
*/
|
||||
static void
|
||||
r200DestroyScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
r200ScreenPtr screen = (r200ScreenPtr)sPriv->private;
|
||||
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
if ( !screen->IsPCI ) {
|
||||
drmUnmap( screen->agpTextures.map,
|
||||
screen->agpTextures.size );
|
||||
}
|
||||
drmUnmapBufs( screen->buffers );
|
||||
drmUnmap( screen->status.map, screen->status.size );
|
||||
drmUnmap( screen->mmio.map, screen->mmio.size );
|
||||
|
||||
FREE( screen );
|
||||
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 = {
|
||||
.InitDriver = r200InitDriver,
|
||||
.DestroyScreen = r200DestroyScreen,
|
||||
.CreateContext = r200CreateContext,
|
||||
.DestroyContext = r200DestroyContext,
|
||||
.CreateBuffer = r200CreateBuffer,
|
||||
.DestroyBuffer = r200DestroyBuffer,
|
||||
.SwapBuffers = r200SwapBuffers,
|
||||
.MakeCurrent = r200MakeCurrent,
|
||||
.UnbindContext = r200UnbindContext,
|
||||
.OpenFullScreen = r200OpenCloseFullScreen,
|
||||
.CloseFullScreen = r200OpenCloseFullScreen,
|
||||
.GetSwapInfo = getSwapInfo,
|
||||
.GetMSC = driGetMSC32,
|
||||
.WaitForMSC = driWaitForMSC32,
|
||||
.WaitForSBC = NULL,
|
||||
.SwapBuffersMSC = NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
* Return: pointer to a __DRIscreenPrivate.
|
||||
*
|
||||
*/
|
||||
#ifndef _SOLO
|
||||
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;
|
||||
}
|
||||
#else
|
||||
void *__driCreateScreen(struct DRIDriverRec *driver,
|
||||
struct DRIDriverContextRec *driverContext)
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
psp = __driUtilCreateScreen(driver, driverContext, &r200API);
|
||||
return (void *) psp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef _SOLO
|
||||
/* 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 )
|
||||
{
|
||||
PFNGLXENABLEEXTENSIONPROC glx_enable_extension;
|
||||
typedef void *(*registerFunc)(const char *funcName, void *funcAddr);
|
||||
registerFunc regFunc;
|
||||
|
||||
|
||||
if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
|
||||
glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC)
|
||||
glXGetProcAddress( "__glXEnableExtension" );
|
||||
|
||||
if ( glx_enable_extension != NULL ) {
|
||||
glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE );
|
||||
glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE );
|
||||
glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE );
|
||||
glx_enable_extension( "GLX_MESA_swap_frame_usage", GL_FALSE );
|
||||
|
||||
|
||||
/* Get pointers to libGL's __glXRegisterGLXFunction
|
||||
* and __glXRegisterGLXExtensionString, if they exist.
|
||||
*/
|
||||
regFunc = (registerFunc) glXGetProcAddress( "__glXRegisterGLXFunction" );
|
||||
|
||||
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? */
|
||||
|
||||
glx_enable_extension( "GLX_NV_vertex_array_range", GL_TRUE );
|
||||
glx_enable_extension( "GLX_MESA_agp_offset", GL_TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get information about previous buffer swaps.
|
||||
*/
|
||||
static int
|
||||
getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
|
||||
{
|
||||
r200ContextPtr rmesa;
|
||||
|
||||
if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
|
||||
|| (dPriv->driContextPriv->driverPrivate == NULL)
|
||||
|| (sInfo == NULL) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
sInfo->swap_count = rmesa->swap_count;
|
||||
sInfo->swap_ust = rmesa->swap_ust;
|
||||
sInfo->swap_missed_count = rmesa->swap_missed_count;
|
||||
|
||||
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
|
||||
? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
|
||||
: 0.0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
99
src/mesa/drivers/dri/r200/r200_screen.h
Normal file
99
src/mesa/drivers/dri/r200/r200_screen.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/* $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 "xf86drm.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__ CARD32 *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__ */
|
||||
433
src/mesa/drivers/dri/r200/r200_span.c
Normal file
433
src/mesa/drivers/dri/r200/r200_span.c
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/* $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 "colormac.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 Radeon family 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 %s", __FUNCTION__);
|
||||
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;
|
||||
}
|
||||
45
src/mesa/drivers/dri/r200/r200_span.h
Normal file
45
src/mesa/drivers/dri/r200/r200_span.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* $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
|
||||
2175
src/mesa/drivers/dri/r200/r200_state.c
Normal file
2175
src/mesa/drivers/dri/r200/r200_state.c
Normal file
File diff suppressed because it is too large
Load diff
2168
src/mesa/drivers/dri/r200/r200_state.c~
Normal file
2168
src/mesa/drivers/dri/r200/r200_state.c~
Normal file
File diff suppressed because it is too large
Load diff
70
src/mesa/drivers/dri/r200/r200_state.h
Normal file
70
src/mesa/drivers/dri/r200/r200_state.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* $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
|
||||
691
src/mesa/drivers/dri/r200/r200_state_init.c
Normal file
691
src/mesa/drivers/dri/r200/r200_state_init.c
Normal file
|
|
@ -0,0 +1,691 @@
|
|||
/* $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 "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 < ctx->Const.MaxTextureUnits ; i++ ) {
|
||||
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;
|
||||
}
|
||||
1291
src/mesa/drivers/dri/r200/r200_swtcl.c
Normal file
1291
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
|
||||
549
src/mesa/drivers/dri/r200/r200_tcl.c
Normal file
549
src/mesa/drivers/dri/r200/r200_tcl.c
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
/* $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 "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);rmesa = rmesa
|
||||
#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, ~0 /* 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 (ctx->RenderMode == GL_RENDER) {
|
||||
/* Make all this event-driven:
|
||||
*/
|
||||
if (ctx->Light.Enabled) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
|
||||
if (1 || 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/mesa/drivers/dri/r200/r200_tcl.h
Normal file
67
src/mesa/drivers/dri/r200/r200_tcl.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* $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
|
||||
1002
src/mesa/drivers/dri/r200/r200_tex.c
Normal file
1002
src/mesa/drivers/dri/r200/r200_tex.c
Normal file
File diff suppressed because it is too large
Load diff
51
src/mesa/drivers/dri/r200/r200_tex.h
Normal file
51
src/mesa/drivers/dri/r200/r200_tex.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* $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 r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t );
|
||||
|
||||
extern void r200InitTextureFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif /* __R200_TEX_H__ */
|
||||
505
src/mesa/drivers/dri/r200/r200_texmem.c
Normal file
505
src/mesa/drivers/dri/r200/r200_texmem.c
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
/* $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 <errno.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
#include "colormac.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() */
|
||||
|
||||
|
||||
/**
|
||||
* Destroy any device-dependent state associated with the texture. This may
|
||||
* include NULLing out hardware state that points to the texture.
|
||||
*/
|
||||
void
|
||||
r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t )
|
||||
{
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->base.tObj );
|
||||
}
|
||||
|
||||
if ( rmesa != NULL ) {
|
||||
unsigned i;
|
||||
|
||||
|
||||
for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) {
|
||||
if ( t == rmesa->state.texture.unit[i].texobj ) {
|
||||
rmesa->state.texture.unit[i].texobj = NULL;
|
||||
remove_from_list( &rmesa->hw.tex[i] );
|
||||
make_empty_list( &rmesa->hw.tex[i] );
|
||||
remove_from_list( &rmesa->hw.cube[i] );
|
||||
make_empty_list( &rmesa->hw.cube[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* 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:
|
||||
*/
|
||||
/* FIXME This may not be correct as driSwapOutTextureObject sets
|
||||
* FIXME dirty_images. It may be fine, though.
|
||||
*/
|
||||
if ( t->base.memBlock ) {
|
||||
driSwapOutTextureObject( (driTextureObject *) t );
|
||||
}
|
||||
}
|
||||
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 \a t at the specified
|
||||
* level at the address relative to \a start.
|
||||
*/
|
||||
static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y, GLint width, GLint height,
|
||||
GLuint face )
|
||||
{
|
||||
struct gl_texture_image *texImage = NULL;
|
||||
GLuint offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drmRadeonTexture tex;
|
||||
drmRadeonTexImage tmp;
|
||||
const int level = hwlevel + t->base.firstLevel;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
||||
__FUNCTION__, t, t->base.tObj, level, width, height, face );
|
||||
}
|
||||
|
||||
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 %s", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (face) {
|
||||
case 0:
|
||||
texImage = t->base.tObj->Image[level];
|
||||
break;
|
||||
case 1:
|
||||
texImage = t->base.tObj->NegX[level];
|
||||
break;
|
||||
case 2:
|
||||
texImage = t->base.tObj->PosY[level];
|
||||
break;
|
||||
case 3:
|
||||
texImage = t->base.tObj->NegY[level];
|
||||
break;
|
||||
case 4:
|
||||
texImage = t->base.tObj->PosZ[level];
|
||||
break;
|
||||
case 5:
|
||||
texImage = t->base.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->base.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__);
|
||||
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr;
|
||||
|
||||
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 level: %d/%d\n",
|
||||
(GLuint)offset, hwlevel, level );
|
||||
}
|
||||
|
||||
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_RADEON_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x\n",
|
||||
offset );
|
||||
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 \a t. This might
|
||||
* require the allocation of texture memory.
|
||||
*
|
||||
* \param rmesa Context pointer
|
||||
* \param t Texture to be uploaded
|
||||
* \param face Cube map face to be uploaded. Zero for non-cube maps.
|
||||
*/
|
||||
|
||||
int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face )
|
||||
{
|
||||
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
||||
rmesa->glCtx, t->base.tObj, t->base.totalSize,
|
||||
t->base.firstLevel, t->base.lastLevel );
|
||||
}
|
||||
|
||||
if ( !t || t->base.totalSize == 0 )
|
||||
return 0;
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
if ( t->base.memBlock == NULL ) {
|
||||
int heap;
|
||||
|
||||
heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps,
|
||||
(driTextureObject *) t );
|
||||
if ( heap == -1 ) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the base offset of the texture image */
|
||||
t->bufAddr = rmesa->r200Screen->texOffset[heap]
|
||||
+ t->base.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.
|
||||
*/
|
||||
driUpdateTextureLRU( (driTextureObject *) t );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
/* Upload any images that are new */
|
||||
if (t->base.dirty_images[face]) {
|
||||
int i;
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
if ( (t->base.dirty_images[face] & (1 << (i+t->base.firstLevel))) != 0 ) {
|
||||
uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width,
|
||||
t->image[face][i].height, face );
|
||||
}
|
||||
}
|
||||
t->base.dirty_images[face] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
|
||||
r200Finish( rmesa->glCtx );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1824
src/mesa/drivers/dri/r200/r200_texstate.c
Normal file
1824
src/mesa/drivers/dri/r200/r200_texstate.c
Normal file
File diff suppressed because it is too large
Load diff
1125
src/mesa/drivers/dri/r200/r200_vtxfmt.c
Normal file
1125
src/mesa/drivers/dri/r200/r200_vtxfmt.c
Normal file
File diff suppressed because it is too large
Load diff
127
src/mesa/drivers/dri/r200/r200_vtxfmt.h
Normal file
127
src/mesa/drivers/dri/r200/r200_vtxfmt.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/* $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 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
|
||||
901
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
Normal file
901
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
Normal file
|
|
@ -0,0 +1,901 @@
|
|||
/* $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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
*rmesa->vb.dmaptr++ = *(int *)&x;
|
||||
*rmesa->vb.dmaptr++ = *(int *)&y;
|
||||
*rmesa->vb.dmaptr++ = *(int *)&z;
|
||||
|
||||
for (i = 3; i < rmesa->vb.vertex_size; i++)
|
||||
*rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
|
||||
|
||||
if (--rmesa->vb.counter == 0)
|
||||
rmesa->vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex3fv( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
*rmesa->vb.dmaptr++ = *(int *)&v[0];
|
||||
*rmesa->vb.dmaptr++ = *(int *)&v[1];
|
||||
*rmesa->vb.dmaptr++ = *(int *)&v[2];
|
||||
|
||||
for (i = 3; i < rmesa->vb.vertex_size; i++)
|
||||
*rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
|
||||
|
||||
if (--rmesa->vb.counter == 0)
|
||||
rmesa->vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex2f( GLfloat x, GLfloat y )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
*rmesa->vb.dmaptr++ = *(int *)&x;
|
||||
*rmesa->vb.dmaptr++ = *(int *)&y;
|
||||
*rmesa->vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < rmesa->vb.vertex_size; i++)
|
||||
*rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
|
||||
|
||||
if (--rmesa->vb.counter == 0)
|
||||
rmesa->vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void r200_Vertex2fv( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
*rmesa->vb.dmaptr++ = *(int *)&v[0];
|
||||
*rmesa->vb.dmaptr++ = *(int *)&v[1];
|
||||
*rmesa->vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < rmesa->vb.vertex_size; i++)
|
||||
*rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
|
||||
|
||||
if (--rmesa->vb.counter == 0)
|
||||
rmesa->vb.notify();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color for ubyte (packed) color formats:
|
||||
*/
|
||||
static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_Color3ubv_ub( const GLubyte *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = a;
|
||||
}
|
||||
|
||||
static void r200_Color4ubv_ub( const GLubyte *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
*(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
|
||||
}
|
||||
|
||||
|
||||
static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_Color3fv_4f( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = a;
|
||||
}
|
||||
|
||||
static void r200_Color4fv_4f( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
|
||||
}
|
||||
|
||||
static void r200_Color4ubv_3f( const GLubyte *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
|
||||
}
|
||||
|
||||
|
||||
static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
}
|
||||
|
||||
static void r200_Color3fv_3f( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
|
||||
}
|
||||
|
||||
static void r200_Color4fv_3f( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
|
||||
}
|
||||
|
||||
|
||||
/* Secondary Color:
|
||||
*/
|
||||
static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->vb.specptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
r200_color_t *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.floatspecptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->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 )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.normalptr;
|
||||
dest[0] = n0;
|
||||
dest[1] = n1;
|
||||
dest[2] = n2;
|
||||
}
|
||||
|
||||
static void r200_Normal3fv( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.normalptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
/* TexCoord
|
||||
*/
|
||||
static void r200_TexCoord1f( GLfloat s )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_TexCoord1fv( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_TexCoord2f( GLfloat s, GLfloat t )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void r200_TexCoord2fv( const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
}
|
||||
|
||||
|
||||
/* MultiTexcoord
|
||||
*
|
||||
* Technically speaking, these functions should subtract GL_TEXTURE0 from
|
||||
* \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0,
|
||||
* which has the low-order 5 bits 0. For all possible valid values of
|
||||
* \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target
|
||||
* with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so
|
||||
* the subtraction has been omitted.
|
||||
*/
|
||||
|
||||
static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
GLfloat *dest = rmesa->vb.texcoordptr[target & 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 \
|
||||
{ \
|
||||
GET_CURRENT_CONTEXT(ctx); \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
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( ctx, key ); \
|
||||
else if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
|
||||
\
|
||||
if (dfn) \
|
||||
ctx->Exec->FN = (FNTYPE)(dfn->code); \
|
||||
else { \
|
||||
if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
|
||||
ctx->Exec->FN = r200_##FN; \
|
||||
} \
|
||||
\
|
||||
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
ctx->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 \
|
||||
{ \
|
||||
GET_CURRENT_CONTEXT(ctx); \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
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 \
|
||||
{ \
|
||||
GET_CURRENT_CONTEXT(ctx); \
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
|
||||
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( ctx, key ); \
|
||||
else if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
|
||||
\
|
||||
if (dfn) \
|
||||
ctx->Exec->FN = (FNTYPE)(dfn->code); \
|
||||
else { \
|
||||
if (R200_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
|
||||
ctx->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \
|
||||
? r200_##FN##_ub : r200_##FN##_3f; \
|
||||
} \
|
||||
\
|
||||
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
ctx->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
|
||||
}
|
||||
}
|
||||
231
src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
Normal file
231
src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "simple_list.h"
|
||||
#include "r200_vtxfmt.h"
|
||||
|
||||
#if defined(USE_SSE_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
|
||||
#define EXTERN( FUNC ) \
|
||||
extern const char *FUNC; \
|
||||
extern const char *FUNC##_end
|
||||
|
||||
EXTERN( _sse_Attribute2fv );
|
||||
EXTERN( _sse_Attribute2f );
|
||||
EXTERN( _sse_Attribute3fv );
|
||||
EXTERN( _sse_Attribute3f );
|
||||
EXTERN( _sse_MultiTexCoord2fv );
|
||||
EXTERN( _sse_MultiTexCoord2f );
|
||||
EXTERN( _sse_MultiTexCoord2fv_2 );
|
||||
EXTERN( _sse_MultiTexCoord2f_2 );
|
||||
|
||||
/* Build specialized versions of the immediate calls on the fly for
|
||||
* the current state.
|
||||
*/
|
||||
|
||||
static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key,
|
||||
const char * name, void * dest)
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _sse_Attribute2fv, (*cache) );
|
||||
FIXUP(dfn->code, 10, 0x0, (int)dest);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _sse_Attribute2f, (*cache) );
|
||||
FIXUP(dfn->code, 8, 0x0, (int)dest);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key,
|
||||
const char * name, void * dest)
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _sse_Attribute3fv, (*cache) );
|
||||
FIXUP(dfn->code, 13, 0x0, (int)dest);
|
||||
FIXUP(dfn->code, 18, 0x8, 8+(int)dest);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _sse_Attribute3f, (*cache) );
|
||||
FIXUP(dfn->code, 12, 0x0, (int)dest);
|
||||
FIXUP(dfn->code, 17, 0x8, 8+(int)dest);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
|
||||
__FUNCTION__, rmesa->vb.normalptr );
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
|
||||
__FUNCTION__, rmesa->vb.normalptr );
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key )
|
||||
{
|
||||
if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
|
||||
__FUNCTION__, rmesa->vb.floatcolorptr );
|
||||
}
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key )
|
||||
{
|
||||
if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key,
|
||||
__FUNCTION__, rmesa->vb.floatcolorptr );
|
||||
}
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
|
||||
__FUNCTION__, rmesa->vb.texcoordptr[0] );
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
|
||||
__FUNCTION__, rmesa->vb.texcoordptr[0] );
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
|
||||
|
||||
if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
|
||||
DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
|
||||
} else {
|
||||
DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
|
||||
|
||||
if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
|
||||
DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
|
||||
} else {
|
||||
DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
void r200InitSSECodegen( struct dfn_generators *gen )
|
||||
{
|
||||
if ( cpu_has_xmm ) {
|
||||
gen->Normal3fv = (void *) r200_makeSSENormal3fv;
|
||||
gen->Normal3f = (void *) r200_makeSSENormal3f;
|
||||
gen->Color3fv = (void *) r200_makeSSEColor3fv;
|
||||
gen->Color3f = (void *) r200_makeSSEColor3f;
|
||||
gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv;
|
||||
gen->TexCoord2f = (void *) r200_makeSSETexCoord2f;
|
||||
gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv;
|
||||
gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void r200InitSSECodegen( struct dfn_generators *gen )
|
||||
{
|
||||
(void) gen;
|
||||
}
|
||||
|
||||
#endif
|
||||
438
src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
Normal file
438
src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "simple_list.h"
|
||||
#include "r200_vtxfmt.h"
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
|
||||
#define EXTERN( FUNC ) \
|
||||
extern const char *FUNC; \
|
||||
extern const char *FUNC##_end
|
||||
|
||||
EXTERN ( _x86_Attribute2fv );
|
||||
EXTERN ( _x86_Attribute2f );
|
||||
EXTERN ( _x86_Attribute3fv );
|
||||
EXTERN ( _x86_Attribute3f );
|
||||
EXTERN ( _x86_Vertex3fv_6 );
|
||||
EXTERN ( _x86_Vertex3fv_8 );
|
||||
EXTERN ( _x86_Vertex3fv );
|
||||
EXTERN ( _x86_Vertex3f_4 );
|
||||
EXTERN ( _x86_Vertex3f_6 );
|
||||
EXTERN ( _x86_Vertex3f );
|
||||
EXTERN ( _x86_Color4ubv_ub );
|
||||
EXTERN ( _x86_Color4ubv_4f );
|
||||
EXTERN ( _x86_Color4ub_ub );
|
||||
EXTERN ( _x86_MultiTexCoord2fv );
|
||||
EXTERN ( _x86_MultiTexCoord2fv_2 );
|
||||
EXTERN ( _x86_MultiTexCoord2f );
|
||||
EXTERN ( _x86_MultiTexCoord2f_2 );
|
||||
|
||||
|
||||
/* Build specialized versions of the immediate calls on the fly for
|
||||
* the current state. Generic x86 versions.
|
||||
*/
|
||||
|
||||
struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,
|
||||
key[0], key[1], rmesa->vb.vertex_size );
|
||||
|
||||
switch (rmesa->vb.vertex_size) {
|
||||
case 4: {
|
||||
|
||||
DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
|
||||
DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]);
|
||||
FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]);
|
||||
FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3);
|
||||
FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,
|
||||
key[0], key[1], rmesa->vb.vertex_size );
|
||||
|
||||
switch (rmesa->vb.vertex_size) {
|
||||
case 6: {
|
||||
|
||||
DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
|
||||
FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]);
|
||||
FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 8: {
|
||||
|
||||
DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
|
||||
FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]);
|
||||
FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]);
|
||||
FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]);
|
||||
FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
default: {
|
||||
|
||||
DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3);
|
||||
FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]);
|
||||
FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr);
|
||||
FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *
|
||||
r200_makeX86Attribute2fv( struct dynfn * cache, const int *key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _x86_Attribute2fv, (*cache) );
|
||||
FIXUP(dfn->code, 11, 0x0, (int)dest);
|
||||
FIXUP(dfn->code, 16, 0x4, 4+(int)dest);
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *
|
||||
r200_makeX86Attribute2f( struct dynfn * cache, const int *key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _x86_Attribute2f, (*cache) );
|
||||
FIXUP(dfn->code, 1, 0x0, (int)dest);
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
static struct dynfn *
|
||||
r200_makeX86Attribute3fv( struct dynfn * cache, const int *key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _x86_Attribute3fv, (*cache) );
|
||||
FIXUP(dfn->code, 14, 0x0, (int)dest);
|
||||
FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
|
||||
FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
static struct dynfn *
|
||||
r200_makeX86Attribute3f( struct dynfn * cache, const int *key,
|
||||
const char * name, void * dest )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", name, key[0] );
|
||||
|
||||
DFN ( _x86_Attribute3f, (*cache) );
|
||||
FIXUP(dfn->code, 14, 0x0, (int)dest);
|
||||
FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
|
||||
FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
|
||||
__FUNCTION__, rmesa->vb.normalptr );
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
|
||||
__FUNCTION__, rmesa->vb.normalptr );
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
|
||||
|
||||
if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) {
|
||||
DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv);
|
||||
FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr);
|
||||
return dfn;
|
||||
}
|
||||
else {
|
||||
|
||||
DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv);
|
||||
FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
|
||||
FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr);
|
||||
FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4);
|
||||
FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8);
|
||||
FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key )
|
||||
{
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
|
||||
|
||||
if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) {
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub );
|
||||
FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr);
|
||||
FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1);
|
||||
FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2);
|
||||
FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3);
|
||||
return dfn;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
|
||||
__FUNCTION__, rmesa->vb.floatcolorptr );
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key )
|
||||
{
|
||||
if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key,
|
||||
__FUNCTION__, rmesa->vb.floatcolorptr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
|
||||
__FUNCTION__, rmesa->vb.texcoordptr[0] );
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
|
||||
__FUNCTION__, rmesa->vb.texcoordptr[0] );
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] );
|
||||
|
||||
if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
|
||||
DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
|
||||
FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
|
||||
} else {
|
||||
DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx,
|
||||
const int *key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] );
|
||||
|
||||
if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
|
||||
DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
|
||||
FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
|
||||
}
|
||||
else {
|
||||
/* Note: this might get generated multiple times, even though the
|
||||
* actual emitted code is the same.
|
||||
*/
|
||||
DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
void r200InitX86Codegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Vertex3f = r200_makeX86Vertex3f;
|
||||
gen->Vertex3fv = r200_makeX86Vertex3fv;
|
||||
gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */
|
||||
gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */
|
||||
gen->Normal3f = r200_makeX86Normal3f;
|
||||
gen->Normal3fv = r200_makeX86Normal3fv;
|
||||
gen->TexCoord2f = r200_makeX86TexCoord2f;
|
||||
gen->TexCoord2fv = r200_makeX86TexCoord2fv;
|
||||
gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB;
|
||||
gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB;
|
||||
gen->Color3f = r200_makeX86Color3f;
|
||||
gen->Color3fv = r200_makeX86Color3fv;
|
||||
|
||||
/* Not done:
|
||||
*/
|
||||
/* gen->Vertex2f = r200_makeX86Vertex2f; */
|
||||
/* gen->Vertex2fv = r200_makeX86Vertex2fv; */
|
||||
/* gen->Color3ub = r200_makeX86Color3ub; */
|
||||
/* gen->Color3ubv = r200_makeX86Color3ubv; */
|
||||
/* gen->Color4f = r200_makeX86Color4f; */
|
||||
/* gen->Color4fv = r200_makeX86Color4fv; */
|
||||
/* gen->TexCoord1f = r200_makeX86TexCoord1f; */
|
||||
/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */
|
||||
/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */
|
||||
/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
void r200InitX86Codegen( struct dfn_generators *gen )
|
||||
{
|
||||
(void) gen;
|
||||
}
|
||||
|
||||
#endif
|
||||
410
src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
Normal file
410
src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#define GLOBL( x ) \
|
||||
.globl x; \
|
||||
x:
|
||||
|
||||
.data
|
||||
.align 4
|
||||
GLOBL( _x86_Normal3fv)
|
||||
movl 4(%esp), %eax /* load 'v' off stack */
|
||||
movl (%eax), %ecx /* load v[0] */
|
||||
movl 4(%eax), %edx /* load v[1] */
|
||||
movl 8(%eax), %eax /* load v[2] */
|
||||
movl %ecx, 0 /* store v[0] to current vertex */
|
||||
movl %edx, 4 /* store v[1] to current vertex */
|
||||
movl %eax, 8 /* store v[2] to current vertex */
|
||||
ret
|
||||
GLOBL ( _x86_Normal3fv_end )
|
||||
|
||||
/*
|
||||
vertex 3f vertex size 4
|
||||
*/
|
||||
|
||||
GLOBL ( _x86_Vertex3f_4 )
|
||||
movl (0), %ecx
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %edx
|
||||
movl %eax, (%ecx)
|
||||
movl %edx, 4(%ecx)
|
||||
movl 12(%esp), %eax
|
||||
movl (0), %edx
|
||||
movl %eax, 8(%ecx)
|
||||
movl %edx, 12(%ecx)
|
||||
movl (0), %eax
|
||||
addl $16, %ecx
|
||||
dec %eax
|
||||
movl %ecx, (0)
|
||||
movl %eax, (0)
|
||||
je .1
|
||||
ret
|
||||
.1: jmp *0
|
||||
|
||||
GLOBL ( _x86_Vertex3f_4_end )
|
||||
|
||||
/*
|
||||
vertex 3f vertex size 6
|
||||
*/
|
||||
GLOBL ( _x86_Vertex3f_6 )
|
||||
push %edi
|
||||
movl (0), %edi
|
||||
movl 8(%esp), %eax
|
||||
movl 12(%esp), %edx
|
||||
movl 16(%esp), %ecx
|
||||
movl %eax, (%edi)
|
||||
movl %edx, 4(%edi)
|
||||
movl %ecx, 8(%edi)
|
||||
movl (0), %eax
|
||||
movl (0), %edx
|
||||
movl (0), %ecx
|
||||
movl %eax, 12(%edi)
|
||||
movl %edx, 16(%edi)
|
||||
movl %ecx, 20(%edi)
|
||||
addl $24, %edi
|
||||
movl (0), %eax
|
||||
movl %edi, (0)
|
||||
dec %eax
|
||||
pop %edi
|
||||
movl %eax, (0)
|
||||
je .2
|
||||
ret
|
||||
.2: jmp *0
|
||||
GLOBL ( _x86_Vertex3f_6_end )
|
||||
/*
|
||||
vertex 3f generic size
|
||||
*/
|
||||
GLOBL ( _x86_Vertex3f )
|
||||
push %edi
|
||||
push %esi
|
||||
movl $0, %esi
|
||||
movl (0), %edi
|
||||
movl 12(%esp), %eax
|
||||
movl 16(%esp), %edx
|
||||
movl 20(%esp), %ecx
|
||||
movl %eax, (%edi)
|
||||
movl %edx, 4(%edi)
|
||||
movl %ecx, 8(%edi)
|
||||
addl $12, %edi
|
||||
movl $0, %ecx
|
||||
repz
|
||||
movsl %ds:(%esi), %es:(%edi)
|
||||
movl (0), %eax
|
||||
movl %edi, (0)
|
||||
dec %eax
|
||||
movl %eax, (0)
|
||||
pop %esi
|
||||
pop %edi
|
||||
je .3
|
||||
ret
|
||||
.3: jmp *0
|
||||
|
||||
GLOBL ( _x86_Vertex3f_end )
|
||||
|
||||
/*
|
||||
Vertex 3fv vertex size 6
|
||||
*/
|
||||
GLOBL ( _x86_Vertex3fv_6 )
|
||||
movl (0), %eax
|
||||
movl 4(%esp), %ecx
|
||||
movl (%ecx), %edx
|
||||
movl %edx, (%eax)
|
||||
movl 4(%ecx), %edx
|
||||
movl 8(%ecx), %ecx
|
||||
movl %edx, 4(%eax)
|
||||
movl %ecx, 8(%eax)
|
||||
movl (28), %edx
|
||||
movl (32), %ecx
|
||||
movl %edx, 12(%eax)
|
||||
movl %ecx, 16(%eax)
|
||||
movl (36), %edx
|
||||
movl %edx, 20(%eax)
|
||||
addl $24, %eax
|
||||
movl %eax, 0
|
||||
movl 4, %eax
|
||||
dec %eax
|
||||
movl %eax, 4
|
||||
je .4
|
||||
ret
|
||||
.4: jmp *8
|
||||
|
||||
GLOBL ( _x86_Vertex3fv_6_end )
|
||||
|
||||
/*
|
||||
Vertex 3fv vertex size 8
|
||||
*/
|
||||
GLOBL ( _x86_Vertex3fv_8 )
|
||||
movl (0), %eax
|
||||
movl 4(%esp), %ecx
|
||||
movl (%ecx), %edx
|
||||
movl %edx ,(%eax)
|
||||
movl 4(%ecx) ,%edx
|
||||
movl 8(%ecx) ,%ecx
|
||||
movl %edx, 4(%eax)
|
||||
movl %ecx, 8(%eax)
|
||||
movl (28), %edx
|
||||
movl (32), %ecx
|
||||
movl %edx, 12(%eax)
|
||||
movl %ecx, 16(%eax)
|
||||
movl (28), %edx
|
||||
movl (32), %ecx
|
||||
movl %edx, 20(%eax)
|
||||
movl %ecx, 24(%eax)
|
||||
movl (36), %edx
|
||||
movl %edx, 28(%eax)
|
||||
addl $32, %eax
|
||||
movl %eax, (0)
|
||||
movl 4, %eax
|
||||
dec %eax
|
||||
movl %eax, (4)
|
||||
je .5
|
||||
ret
|
||||
.5: jmp *8
|
||||
|
||||
GLOBL ( _x86_Vertex3fv_8_end )
|
||||
|
||||
/*
|
||||
Vertex 3fv generic vertex size
|
||||
*/
|
||||
GLOBL ( _x86_Vertex3fv )
|
||||
movl 4(%esp), %edx
|
||||
push %edi
|
||||
push %esi
|
||||
movl (0x1010101), %edi
|
||||
movl (%edx), %eax
|
||||
movl 4(%edx), %ecx
|
||||
movl 8(%edx), %esi
|
||||
movl %eax, (%edi)
|
||||
movl %ecx, 4(%edi)
|
||||
movl %esi, 8(%edi)
|
||||
addl $12, %edi
|
||||
movl $6, %ecx
|
||||
movl $0x58, %esi
|
||||
repz
|
||||
movsl %ds:(%esi), %es:(%edi)
|
||||
movl %edi, (0x1010101)
|
||||
movl (0x2020202), %eax
|
||||
pop %esi
|
||||
pop %edi
|
||||
dec %eax
|
||||
movl %eax, (0x2020202)
|
||||
je .6
|
||||
ret
|
||||
.6: jmp *0
|
||||
GLOBL ( _x86_Vertex3fv_end )
|
||||
|
||||
/*
|
||||
Normal 3f
|
||||
*/
|
||||
GLOBL ( _x86_Normal3f )
|
||||
movl $0x12345678, %edx
|
||||
movl 4(%esp), %eax
|
||||
movl %eax, (%edx)
|
||||
movl 8(%esp), %eax
|
||||
movl %eax, 4(%edx)
|
||||
movl 12(%esp), %eax
|
||||
movl %eax, 8(%edx)
|
||||
ret
|
||||
GLOBL ( _x86_Normal3f_end )
|
||||
|
||||
/*
|
||||
Color 4ubv_ub
|
||||
*/
|
||||
GLOBL ( _x86_Color4ubv_ub )
|
||||
movl 4(%esp), %eax
|
||||
movl $0x12345678, %edx
|
||||
movl (%eax), %eax
|
||||
movl %eax, (%edx)
|
||||
ret
|
||||
GLOBL ( _x86_Color4ubv_ub_end )
|
||||
|
||||
/*
|
||||
Color 4ubv 4f
|
||||
*/
|
||||
GLOBL ( _x86_Color4ubv_4f )
|
||||
push %ebx
|
||||
movl $0, %edx
|
||||
xor %eax, %eax
|
||||
xor %ecx, %ecx
|
||||
movl 8(%esp), %ebx
|
||||
movl (%ebx), %ebx
|
||||
mov %bl, %al
|
||||
mov %bh, %cl
|
||||
movl (%edx,%eax,4),%eax
|
||||
movl (%edx,%ecx,4),%ecx
|
||||
movl %eax, (0xdeadbeaf)
|
||||
movl %ecx, (0xdeadbeaf)
|
||||
xor %eax, %eax
|
||||
xor %ecx, %ecx
|
||||
shr $16, %ebx
|
||||
mov %bl, %al
|
||||
mov %bh, %cl
|
||||
movl (%edx,%eax,4), %eax
|
||||
movl (%edx,%ecx,4), %ecx
|
||||
movl %eax, (0xdeadbeaf)
|
||||
movl %ecx, (0xdeadbeaf)
|
||||
pop %ebx
|
||||
ret
|
||||
GLOBL ( _x86_Color4ubv_4f_end )
|
||||
|
||||
/*
|
||||
|
||||
Color4ub_ub
|
||||
*/
|
||||
GLOBL( _x86_Color4ub_ub )
|
||||
push %ebx
|
||||
movl 8(%esp), %eax
|
||||
movl 12(%esp), %edx
|
||||
movl 16(%esp), %ecx
|
||||
movl 20(%esp), %ebx
|
||||
mov %al, (0)
|
||||
mov %dl, (0)
|
||||
mov %cl, (0)
|
||||
mov %bl, (0)
|
||||
pop %ebx
|
||||
ret
|
||||
GLOBL( _x86_Color4ub_ub_end )
|
||||
|
||||
/*
|
||||
Color3fv_3f
|
||||
*/
|
||||
GLOBL( _x86_Color3fv_3f )
|
||||
movl 4(%esp), %eax
|
||||
movl $0, %edx
|
||||
movl (%eax), %ecx
|
||||
movl %ecx, (%edx)
|
||||
movl 4(%eax), %ecx
|
||||
movl %ecx, 4(%edx)
|
||||
movl 8(%eax), %ecx
|
||||
movl %ecx, 8(%edx)
|
||||
ret
|
||||
GLOBL( _x86_Color3fv_3f_end )
|
||||
|
||||
/*
|
||||
Color3f_3f
|
||||
*/
|
||||
GLOBL( _x86_Color3f_3f )
|
||||
movl $0x12345678, %edx
|
||||
movl 4(%esp), %eax
|
||||
movl %eax, (%edx)
|
||||
movl 8(%esp,1), %eax
|
||||
movl %eax, 4(%edx)
|
||||
movl 12(%esp), %eax
|
||||
movl %eax, 8(%edx)
|
||||
ret
|
||||
GLOBL( _x86_Color3f_3f_end )
|
||||
|
||||
/*
|
||||
TexCoord2fv
|
||||
*/
|
||||
|
||||
GLOBL( _x86_TexCoord2fv )
|
||||
movl 4(%esp), %eax
|
||||
movl $0x12345678, %edx
|
||||
movl (%eax), %ecx
|
||||
movl 4(%eax), %eax
|
||||
movl %ecx, (%edx)
|
||||
movl %eax, 4(%edx)
|
||||
ret
|
||||
|
||||
GLOBL( _x86_TexCoord2fv_end )
|
||||
/*
|
||||
TexCoord2f
|
||||
*/
|
||||
GLOBL( _x86_TexCoord2f )
|
||||
movl $0x12345678, %edx
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %ecx
|
||||
movl %eax, (%edx)
|
||||
movl %ecx, 4(%edx)
|
||||
ret
|
||||
GLOBL( _x86_TexCoord2f_end )
|
||||
|
||||
/*
|
||||
MultiTexCoord2fvARB st0/st1
|
||||
*/
|
||||
GLOBL( _x86_MultiTexCoord2fvARB )
|
||||
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %ecx
|
||||
sub $0x84c0, %eax
|
||||
and $1, %eax
|
||||
movl (%ecx), %edx
|
||||
shl $3, %eax
|
||||
movl 4(%ecx), %ecx
|
||||
movl %edx, 0xdeadbeef(%eax)
|
||||
movl %ecx, 0xdeadbeef(%eax)
|
||||
ret
|
||||
GLOBL( _x86_MultiTexCoord2fvARB_end )
|
||||
/*
|
||||
MultiTexCoord2fvARB
|
||||
*/
|
||||
|
||||
GLOBL( _x86_MultiTexCoord2fvARB_2 )
|
||||
movl 4(%esp,1), %eax
|
||||
movl 8(%esp,1), %ecx
|
||||
sub $0x84c0, %eax
|
||||
and $0x1, %eax
|
||||
movl 0(,%eax,4), %edx
|
||||
movl (%ecx), %eax
|
||||
movl %eax, (%edx)
|
||||
movl 4(%ecx), %eax
|
||||
movl %eax, 4(%edx)
|
||||
ret
|
||||
|
||||
GLOBL( _x86_MultiTexCoord2fvARB_2_end )
|
||||
|
||||
/*
|
||||
MultiTexCoord2fARB st0/st1
|
||||
*/
|
||||
GLOBL( _x86_MultiTexCoord2fARB )
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %edx
|
||||
sub $0x84c0, %eax
|
||||
movl 12(%esp), %ecx
|
||||
and $1, %eax
|
||||
shl $3, %eax
|
||||
movl %edx, 0xdeadbeef(%eax)
|
||||
movl %ecx, 0xdeadbeef(%eax)
|
||||
ret
|
||||
GLOBL( _x86_MultiTexCoord2fARB_end )
|
||||
|
||||
/*
|
||||
MultiTexCoord2fARB
|
||||
*/
|
||||
GLOBL( _x86_MultiTexCoord2fARB_2 )
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %edx
|
||||
sub $0x84c0, %eax
|
||||
movl 12(%esp,1), %ecx
|
||||
and $1,%eax
|
||||
movl 0(,%eax,4), %eax
|
||||
movl %edx, (%eax)
|
||||
movl %ecx, 4(%eax)
|
||||
ret
|
||||
GLOBL( _x86_MultiTexCoord2fARB_2_end )
|
||||
Loading…
Add table
Reference in a new issue