Compare commits
86 Commits
unichrome-
...
blended_fo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
380ba2daec | ||
|
|
e99f390ff6 | ||
|
|
065f725672 | ||
|
|
6b185aaedf | ||
|
|
55ee1daaf9 | ||
|
|
638faa92fc | ||
|
|
85edffd5ff | ||
|
|
932dee87e3 | ||
|
|
bdbdab837e | ||
|
|
6650264802 | ||
|
|
31c25f2edc | ||
|
|
e024cae14b | ||
|
|
b6ab7a1bf1 | ||
|
|
f72e4424d9 | ||
|
|
e3748eb19b | ||
|
|
87889aeab4 | ||
|
|
3276c192b7 | ||
|
|
dd1a817c50 | ||
|
|
a5039af357 | ||
|
|
8e73b14228 | ||
|
|
81ca616e7e | ||
|
|
6563c16e38 | ||
|
|
25faa2d56e | ||
|
|
63473a8e76 | ||
|
|
2fc9351ee7 | ||
|
|
63fd67e561 | ||
|
|
f50a1964d1 | ||
|
|
d6be8dd651 | ||
|
|
9a04b25c60 | ||
|
|
3c80f5c56b | ||
|
|
7a231da442 | ||
|
|
1067ce0cea | ||
|
|
467d64a177 | ||
|
|
404d925b58 | ||
|
|
e443d1ec47 | ||
|
|
92d47e79f1 | ||
|
|
11374bdb86 | ||
|
|
24b5e49141 | ||
|
|
179cc373f1 | ||
|
|
c664f0c515 | ||
|
|
8be4747fd6 | ||
|
|
4a04f002db | ||
|
|
8f1ba083ba | ||
|
|
58cc2e9124 | ||
|
|
18551e75ea | ||
|
|
6fcc6c4965 | ||
|
|
bcd1a9ed68 | ||
|
|
2269445f6d | ||
|
|
b53030a94c | ||
|
|
a656dc251e | ||
|
|
51050efe0e | ||
|
|
7d8c1fb03a | ||
|
|
74bf43051c | ||
|
|
5be14fd59a | ||
|
|
490e764d7a | ||
|
|
ef494c06b6 | ||
|
|
54ef88109b | ||
|
|
e158292ee3 | ||
|
|
e972497310 | ||
|
|
f102f7ae3d | ||
|
|
cb0cc796d2 | ||
|
|
3b486d795d | ||
|
|
13ae06cf36 | ||
|
|
7b05b70c2a | ||
|
|
4c3f041862 | ||
|
|
5bdb4652f9 | ||
|
|
6a50fc43cb | ||
|
|
c6cca6a3b8 | ||
|
|
29c88396db | ||
|
|
d9fcfa2797 | ||
|
|
0983c9dd99 | ||
|
|
c3eaa17b37 | ||
|
|
99edafd4e8 | ||
|
|
83fcf49647 | ||
|
|
3cbc2bd833 | ||
|
|
1b2a655521 | ||
|
|
46a35b2284 | ||
|
|
1c86c7ad9c | ||
|
|
3deaf21745 | ||
|
|
9876730f7a | ||
|
|
15da29b5e7 | ||
|
|
7db50bb3a8 | ||
|
|
922bfd70ff | ||
|
|
80dd3c7917 | ||
|
|
8bdaa927eb | ||
|
|
990dec7ea0 |
28
Makefile
28
Makefile
@@ -33,7 +33,11 @@ realclean:
|
||||
|
||||
install:
|
||||
@echo "Installing"
|
||||
$(TOP)/bin/installmesa
|
||||
$(TOP)/bin/installmesa
|
||||
|
||||
# DirectFBGL module installation
|
||||
linux-directfb-install:
|
||||
cd src/mesa/drivers/directfb && $(MAKE) install
|
||||
|
||||
# If there's no current configuration file
|
||||
$(TOP)/configs/current:
|
||||
@@ -78,6 +82,7 @@ linux \
|
||||
linux-alpha \
|
||||
linux-alpha-static \
|
||||
linux-debug \
|
||||
linux-directfb \
|
||||
linux-dri \
|
||||
linux-dri-x86 \
|
||||
linux-dri-x86-64 \
|
||||
@@ -122,9 +127,9 @@ ultrix-gcc:
|
||||
|
||||
# Rules for making release tarballs
|
||||
|
||||
DIRECTORY = Mesa-6.2
|
||||
LIB_NAME = MesaLib-6.2
|
||||
DEMO_NAME = MesaDemos-6.2
|
||||
DIRECTORY = Mesa-6.3
|
||||
LIB_NAME = MesaLib-6.3
|
||||
DEMO_NAME = MesaDemos-6.3
|
||||
|
||||
LIB_FILES = \
|
||||
$(DIRECTORY)/Makefile* \
|
||||
@@ -201,6 +206,8 @@ LIB_FILES = \
|
||||
$(DIRECTORY)/src/mesa/drivers/beos/Makefile \
|
||||
$(DIRECTORY)/src/mesa/drivers/common/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/drivers/common/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/drivers/directfb/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/drivers/directfb/Makefile \
|
||||
$(DIRECTORY)/src/mesa/drivers/dos/*.[chS] \
|
||||
$(DIRECTORY)/src/mesa/drivers/dri/common/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/drivers/fbdev/glfbdev.c \
|
||||
@@ -270,7 +277,7 @@ LIB_FILES = \
|
||||
$(DIRECTORY)/vms/xlib_share.opt
|
||||
|
||||
|
||||
DEMO_FILES = \
|
||||
GLUT_FILES = \
|
||||
$(DIRECTORY)/include/GL/glut.h \
|
||||
$(DIRECTORY)/include/GL/glutf90.h \
|
||||
$(DIRECTORY)/src/glut/glx/Makefile* \
|
||||
@@ -287,7 +294,10 @@ DEMO_FILES = \
|
||||
$(DIRECTORY)/src/glut/dos/Makefile.DJ \
|
||||
$(DIRECTORY)/src/glut/dos/PC_HW/*.[chS] \
|
||||
$(DIRECTORY)/src/glut/ggi/*.[ch] \
|
||||
$(DIRECTORY)/src/glut/ggi/Makefile \
|
||||
$(DIRECTORY)/src/glut/ggi/Makefile
|
||||
|
||||
|
||||
DEMO_FILES = \
|
||||
$(DIRECTORY)/progs/beos/*.cpp \
|
||||
$(DIRECTORY)/progs/beos/Makefile \
|
||||
$(DIRECTORY)/progs/images/*.rgb \
|
||||
@@ -344,7 +354,7 @@ lib_gz:
|
||||
|
||||
demo_gz:
|
||||
cd .. ; \
|
||||
tar -cvf $(DEMO_NAME).tar $(DEMO_FILES) ; \
|
||||
tar -cvf $(DEMO_NAME).tar $(DEMO_FILES) $(GLUT_FILES) ; \
|
||||
gzip $(DEMO_NAME).tar ; \
|
||||
mv $(DEMO_NAME).tar.gz $(DIRECTORY)
|
||||
|
||||
@@ -357,7 +367,7 @@ lib_bz2:
|
||||
|
||||
demo_bz2:
|
||||
cd .. ; \
|
||||
tar -cvf $(DEMO_NAME).tar $(DEMO_FILES) ; \
|
||||
tar -cvf $(DEMO_NAME).tar $(DEMO_FILES) $(GLUT_FILES) ; \
|
||||
bzip2 $(DEMO_NAME).tar ; \
|
||||
mv $(DEMO_NAME).tar.bz2 $(DIRECTORY)
|
||||
|
||||
@@ -371,7 +381,7 @@ lib_zip:
|
||||
demo_zip:
|
||||
-rm $(DEMO_NAME).zip ; \
|
||||
cd .. ; \
|
||||
zip -r $(DEMO_NAME).zip $(DEMO_FILES) ; \
|
||||
zip -r $(DEMO_NAME).zip $(DEMO_FILES) $(GLUT_FILES) ; \
|
||||
mv $(DEMO_NAME).zip $(DIRECTORY)
|
||||
|
||||
md5:
|
||||
|
||||
29
configs/linux-directfb
Normal file
29
configs/linux-directfb
Normal file
@@ -0,0 +1,29 @@
|
||||
# Configuration for DirectFB
|
||||
|
||||
include $(TOP)/configs/default
|
||||
|
||||
CONFIG_NAME = linux-directfb
|
||||
|
||||
# Compiler and flags
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
||||
CFLAGS = -Wall -O3 -ffast-math -fPIC -std=c99 -D_GNU_SOURCE -D_POSIX_SOURCE -D_SVID_SOURCE \
|
||||
-D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE -DPTHREADS
|
||||
|
||||
CXXFLAGS = -Wall -O3 -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
|
||||
|
||||
HAVE_X86 = $(shell uname -m | grep 'i[3-6]86' >/dev/null && echo yes)
|
||||
ifeq ($(HAVE_X86), yes)
|
||||
CFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM
|
||||
CXXFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM
|
||||
ASM_SOURCES = $(X86_SOURCES) $(X86_API)
|
||||
endif
|
||||
|
||||
# Directories
|
||||
SRC_DIRS = mesa glu
|
||||
DRIVER_DIRS = directfb
|
||||
PROGRAM_DIRS = # disabled
|
||||
|
||||
# Library/program dependencies
|
||||
GL_LIB_DEPS = -lm -lpthread
|
||||
@@ -49,6 +49,5 @@ WINDOW_SYSTEM=dri
|
||||
|
||||
# ffb and gamma are missing because they have not been converted to use the new
|
||||
# interface.
|
||||
DRI_DIRS = dri_client i810 i830 i915 mach64 mga r128 r200 radeon tdfx \
|
||||
unichrome savage sis
|
||||
|
||||
DRI_DIRS = dri_client i810 i830 i915 mach64 mga r128 r200 radeon s3v \
|
||||
savage sis tdfx trident unichrome
|
||||
|
||||
28
docs/README.directfb
Normal file
28
docs/README.directfb
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
Mesa DirectFB Information
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
To build Mesa with DirectFB (DirectFBGL) support you need:
|
||||
- DirectFB at least 0.9.21 (http://directfb.org)
|
||||
- pkg-config at least 0.9 (http://pkgconfig.sf.net)
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
Run
|
||||
|
||||
make linux-directfb
|
||||
|
||||
to build Mesa and DirectFBGL module,
|
||||
|
||||
make install
|
||||
|
||||
to install OpenGL libraries and
|
||||
|
||||
make linux-directfb-install
|
||||
|
||||
to install DirectFBGL module in the proper location.
|
||||
|
||||
@@ -25,6 +25,19 @@ GL_ARB_draw_buffers - allows a fragment program to write to a number of
|
||||
GL_OES_read_format - allows one to query the fastest glReadPixels format
|
||||
and datatype.
|
||||
|
||||
GL_ARB_pixel_buffer_object - buffer objects for pixel read/write functions.
|
||||
|
||||
DirectFB driver, contributed by Claudio Ciccani. See docs/README.directfb
|
||||
for details.
|
||||
|
||||
|
||||
|
||||
Vertex/Fragment Program PRINT Instruction
|
||||
-----------------------------------------
|
||||
|
||||
The GL_NV_vertex_program and GL_NV_fragment_program languages have been
|
||||
extended with a PRINT instruction.
|
||||
|
||||
|
||||
|
||||
To Do before release
|
||||
@@ -53,4 +66,4 @@ D3D needs updating
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
$Id: RELNOTES-6.3,v 3.6 2004/12/09 23:21:36 brianp Exp $
|
||||
$Id: RELNOTES-6.3,v 3.7 2005/01/03 15:55:51 brianp Exp $
|
||||
|
||||
@@ -1317,11 +1317,12 @@ Mesa Version History
|
||||
6.3 Month day, 2004
|
||||
New:
|
||||
- GL_ARB_draw_buffers extension
|
||||
- GL_ARB_pixel_buffer_object extension
|
||||
- GL_OES_read_format extension (Ian Romanick)
|
||||
- full support for GL_EXT_pixel_buffer_object (convolution filters,
|
||||
polygon stipple, colormaps, etc)
|
||||
- DirectFB driver (Claudio Ciccani)
|
||||
Changes:
|
||||
- added -stereo option for glxgears demo (Jacek Rosik)
|
||||
Bug fixes:
|
||||
fixes from 6.2.1, plus:
|
||||
-
|
||||
- some functions didn't support PBO functionality
|
||||
- glGetTexImage didn't convert color index images to RGBA as required
|
||||
|
||||
|
||||
89
include/GL/directfbgl.h
Normal file
89
include/GL/directfbgl.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
(c) Copyright 2001 convergence integrated media GmbH.
|
||||
All rights reserved.
|
||||
|
||||
Written by Denis Oliver Kropp <dok@convergence.de> and
|
||||
Andreas Hundt <andi@convergence.de>.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DIRECTFBGL_H__
|
||||
#define __DIRECTFBGL_H__
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
int buffer_size;
|
||||
int depth_size;
|
||||
int stencil_size;
|
||||
int aux_buffers;
|
||||
|
||||
int red_size;
|
||||
int green_size;
|
||||
int blue_size;
|
||||
int alpha_size;
|
||||
|
||||
int accum_red_size;
|
||||
int accum_green_size;
|
||||
int accum_blue_size;
|
||||
int accum_alpha_size;
|
||||
|
||||
DFBBoolean double_buffer;
|
||||
DFBBoolean stereo;
|
||||
} DFBGLAttributes;
|
||||
|
||||
|
||||
DEFINE_INTERFACE( IDirectFBGL,
|
||||
|
||||
/** Context handling **/
|
||||
|
||||
/*
|
||||
* Acquire the hardware lock.
|
||||
*/
|
||||
DFBResult (*Lock) (
|
||||
IDirectFBGL *thiz
|
||||
);
|
||||
|
||||
/*
|
||||
* Release the lock.
|
||||
*/
|
||||
DFBResult (*Unlock) (
|
||||
IDirectFBGL *thiz
|
||||
);
|
||||
|
||||
/*
|
||||
* Query the OpenGL attributes.
|
||||
*/
|
||||
DFBResult (*GetAttributes) (
|
||||
IDirectFBGL *thiz,
|
||||
DFBGLAttributes *attributes
|
||||
);
|
||||
)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.2
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -495,6 +495,17 @@ extern Bool glXDrawableAttribARB(Display *dpy, GLXDrawable draw, const int *attr
|
||||
#endif /* GLX_ARB_render_texture */
|
||||
|
||||
|
||||
/*
|
||||
* Remove this when glxext.h is updated.
|
||||
*/
|
||||
#ifndef GLX_NV_float_buffer
|
||||
#define GLX_NV_float_buffer 1
|
||||
|
||||
#define GLX_FLOAT_COMPONENTS_NV 0x20B0
|
||||
|
||||
#endif /* GLX_NV_float_buffer */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -41,22 +41,23 @@
|
||||
|
||||
|
||||
/* Some ugly global vars */
|
||||
static GLXFBConfigSGIX gFBconfig = 0;
|
||||
static Display *gDpy = NULL;
|
||||
static int gScreen = 0;
|
||||
static GLXPbufferSGIX gPBuffer = 0;
|
||||
static FBCONFIG gFBconfig = 0;
|
||||
static PBUFFER gPBuffer = 0;
|
||||
static int gWidth, gHeight;
|
||||
static GLXContext glCtx;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Create the pbuffer and return a GLXPbufferSGIX handle.
|
||||
* Create the pbuffer and return a GLXPbuffer handle.
|
||||
*
|
||||
* We loop over a list of fbconfigs trying to create
|
||||
* a pixel buffer. We return the first pixel buffer which we successfully
|
||||
* create.
|
||||
*/
|
||||
static GLXPbufferSGIX
|
||||
static PBUFFER
|
||||
MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
{
|
||||
#define NUM_FB_CONFIGS 4
|
||||
@@ -69,8 +70,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
int fbAttribs[NUM_FB_CONFIGS][100] = {
|
||||
{
|
||||
/* Single buffered, with depth buffer */
|
||||
GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
|
||||
GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
@@ -81,8 +82,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
},
|
||||
{
|
||||
/* Double buffered, with depth buffer */
|
||||
GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
|
||||
GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
@@ -93,8 +94,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
},
|
||||
{
|
||||
/* Single bufferd, without depth buffer */
|
||||
GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
|
||||
GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
@@ -105,8 +106,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
},
|
||||
{
|
||||
/* Double bufferd, without depth buffer */
|
||||
GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
|
||||
GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
@@ -116,13 +117,10 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
None
|
||||
}
|
||||
};
|
||||
int pbAttribs[] = {
|
||||
GLX_LARGEST_PBUFFER_SGIX, True,
|
||||
GLX_PRESERVED_CONTENTS_SGIX, False,
|
||||
None
|
||||
};
|
||||
GLXFBConfigSGIX *fbConfigs;
|
||||
GLXPbufferSGIX pBuffer = None;
|
||||
Bool largest = True;
|
||||
Bool preserve = False;
|
||||
FBCONFIG *fbConfigs;
|
||||
PBUFFER pBuffer = None;
|
||||
int nConfigs;
|
||||
int i;
|
||||
int attempt;
|
||||
@@ -130,23 +128,23 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
for (attempt=0; attempt<NUM_FB_CONFIGS; attempt++) {
|
||||
|
||||
/* Get list of possible frame buffer configurations */
|
||||
fbConfigs = glXChooseFBConfigSGIX(dpy, screen, fbAttribs[attempt], &nConfigs);
|
||||
fbConfigs = ChooseFBConfig(dpy, screen, fbAttribs[attempt], &nConfigs);
|
||||
if (nConfigs==0 || !fbConfigs) {
|
||||
printf("Error: glxChooseFBConfigSGIX failed\n");
|
||||
printf("Error: glXChooseFBConfig failed\n");
|
||||
XCloseDisplay(dpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#if 0 /*DEBUG*/
|
||||
for (i=0;i<nConfigs;i++) {
|
||||
printf("Config %d\n", i);
|
||||
PrintFBConfigInfo(dpy, fbConfigs[i], 0);
|
||||
PrintFBConfigInfo(dpy, screen, fbConfigs[i], 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create the pbuffer using first fbConfig in the list that works. */
|
||||
for (i=0;i<nConfigs;i++) {
|
||||
pBuffer = CreatePbuffer(dpy, fbConfigs[i], width, height, pbAttribs);
|
||||
pBuffer = CreatePbuffer(dpy, screen, fbConfigs[i], width, height, preserve, largest);
|
||||
if (pBuffer) {
|
||||
gFBconfig = fbConfigs[i];
|
||||
gWidth = width;
|
||||
@@ -178,9 +176,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
|
||||
static int
|
||||
Setup(int width, int height)
|
||||
{
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
int pbSupport;
|
||||
XVisualInfo *visInfo;
|
||||
GLXContext glCtx;
|
||||
|
||||
/* Open the X display */
|
||||
gDpy = XOpenDisplay(NULL);
|
||||
@@ -193,7 +190,14 @@ Setup(int width, int height)
|
||||
gScreen = DefaultScreen(gDpy);
|
||||
|
||||
/* Test that pbuffers are available */
|
||||
if (!QueryPbuffers(gDpy, gScreen)) {
|
||||
pbSupport = QueryPbuffers(gDpy, gScreen);
|
||||
if (pbSupport == 1) {
|
||||
printf("Using GLX 1.3 Pbuffers\n");
|
||||
}
|
||||
else if (pbSupport == 2) {
|
||||
printf("Using SGIX Pbuffers\n");
|
||||
}
|
||||
else {
|
||||
printf("Error: pbuffers not available on this screen\n");
|
||||
XCloseDisplay(gDpy);
|
||||
return 0;
|
||||
@@ -208,7 +212,7 @@ Setup(int width, int height)
|
||||
}
|
||||
|
||||
/* Get corresponding XVisualInfo */
|
||||
visInfo = glXGetVisualFromFBConfigSGIX(gDpy, gFBconfig);
|
||||
visInfo = GetVisualFromFBConfig(gDpy, gScreen, gFBconfig);
|
||||
if (!visInfo) {
|
||||
printf("Error: can't get XVisualInfo from FBconfig\n");
|
||||
XCloseDisplay(gDpy);
|
||||
@@ -240,11 +244,6 @@ Setup(int width, int height)
|
||||
}
|
||||
|
||||
return 1; /* Success!! */
|
||||
#else
|
||||
printf("Error: GLX_SGIX_fbconfig and/or GLX_SGIX_pbuffer extensions not"
|
||||
" available at compile-time.\n");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +359,6 @@ Render(void)
|
||||
int NumBoxes = 100;
|
||||
int i;
|
||||
|
||||
InitGL();
|
||||
glClearColor(0.2, 0.2, 0.9, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
@@ -470,9 +468,10 @@ main(int argc, char *argv[])
|
||||
if (!Setup(width, height)) {
|
||||
return 1;
|
||||
}
|
||||
InitGL();
|
||||
Render();
|
||||
WriteFile(fileName);
|
||||
glXDestroyGLXPbufferSGIX( gDpy, gPBuffer );
|
||||
DestroyPbuffer(gDpy, gScreen, gPBuffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,18 +20,18 @@
|
||||
static void
|
||||
PrintConfigs(Display *dpy, int screen, Bool horizFormat)
|
||||
{
|
||||
GLXFBConfigSGIX *fbConfigs;
|
||||
FBCONFIG *fbConfigs;
|
||||
int nConfigs;
|
||||
int i;
|
||||
/* Note: you may want to tweek the attribute list to select a different
|
||||
* set of fbconfigs.
|
||||
*/
|
||||
int fbAttribs[] = {
|
||||
GLX_RENDER_TYPE_SGIX, 0,
|
||||
GLX_DRAWABLE_TYPE_SGIX, 0,
|
||||
GLX_RENDER_TYPE, 0,
|
||||
GLX_DRAWABLE_TYPE, 0,
|
||||
#if 0
|
||||
GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
|
||||
GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
@@ -43,17 +43,9 @@ PrintConfigs(Display *dpy, int screen, Bool horizFormat)
|
||||
|
||||
|
||||
/* Get list of possible frame buffer configurations */
|
||||
#if 0
|
||||
/* SGIX method */
|
||||
fbConfigs = glXChooseFBConfigSGIX(dpy, screen, fbAttribs, &nConfigs);
|
||||
#else
|
||||
/* GLX 1.3 method */
|
||||
(void) fbAttribs;
|
||||
fbConfigs = glXGetFBConfigs(dpy, screen, &nConfigs);
|
||||
#endif
|
||||
|
||||
if (nConfigs==0 || !fbConfigs) {
|
||||
printf("Error: glxChooseFBConfigSGIX failed\n");
|
||||
fbConfigs = ChooseFBConfig(dpy, screen, fbAttribs, &nConfigs);
|
||||
if (!nConfigs || !fbConfigs) {
|
||||
printf("Error: glxChooseFBConfig failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -61,12 +53,12 @@ PrintConfigs(Display *dpy, int screen, Bool horizFormat)
|
||||
|
||||
if (horizFormat) {
|
||||
printf(" ID VisualType Depth Lvl RGB CI DB Stereo R G B A");
|
||||
printf(" Z S AR AG AB AA MSbufs MSnum Pbuffer\n");
|
||||
printf(" Z S AR AG AB AA MSbufs MSnum Pbuffer Float\n");
|
||||
}
|
||||
|
||||
/* Print config info */
|
||||
for (i=0;i<nConfigs;i++) {
|
||||
PrintFBConfigInfo(dpy, fbConfigs[i], horizFormat);
|
||||
PrintFBConfigInfo(dpy, screen, fbConfigs[i], horizFormat);
|
||||
}
|
||||
|
||||
/* free the list */
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
* OpenGL pbuffers utility functions.
|
||||
*
|
||||
* Brian Paul
|
||||
* April 1997
|
||||
* Original code: April 1997
|
||||
* Updated on 5 October 2002
|
||||
* Updated again on 3 January 2005 to use GLX 1.3 functions in preference
|
||||
* to the GLX_SGIX_fbconfig/pbuffer extensions.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,51 +15,140 @@
|
||||
#include "pbutil.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Test if we pixel buffers are available for a particular X screen.
|
||||
* Input: dpy - the X display
|
||||
* screen - screen number
|
||||
* Return: 0 = pixel buffers not available.
|
||||
* 1 = pixel buffers are available.
|
||||
* 1 = pixel buffers are available via GLX 1.3.
|
||||
* 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
|
||||
*/
|
||||
int
|
||||
QueryPbuffers(Display *dpy, int screen)
|
||||
{
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
char *extensions;
|
||||
|
||||
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
|
||||
if (!strstr(extensions,"GLX_SGIX_fbconfig")) {
|
||||
return 0;
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
{
|
||||
/* GLX 1.3 supports pbuffers */
|
||||
int glxVersionMajor, glxVersionMinor;
|
||||
if (!glXQueryVersion(dpy, &glxVersionMajor, &glxVersionMinor)) {
|
||||
/* GLX not available! */
|
||||
return 0;
|
||||
}
|
||||
if (glxVersionMajor * 100 + glxVersionMinor >= 103) {
|
||||
return 1;
|
||||
}
|
||||
/* fall-through */
|
||||
}
|
||||
if (!strstr(extensions,"GLX_SGIX_pbuffer")) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
/* Try the SGIX extensions */
|
||||
{
|
||||
char *extensions;
|
||||
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
|
||||
if (!extensions ||
|
||||
!strstr(extensions,"GLX_SGIX_fbconfig") ||
|
||||
!strstr(extensions,"GLX_SGIX_pbuffer")) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef GLX_SGIX_fbconfig
|
||||
FBCONFIG *
|
||||
ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
|
||||
{
|
||||
int pbSupport = QueryPbuffers(dpy, screen);
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
if (pbSupport == 1) {
|
||||
return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
|
||||
}
|
||||
#endif
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
if (pbSupport == 2) {
|
||||
return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
XVisualInfo *
|
||||
GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
|
||||
{
|
||||
int pbSupport = QueryPbuffers(dpy, screen);
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
if (pbSupport == 1) {
|
||||
return glXGetVisualFromFBConfig(dpy, config);
|
||||
}
|
||||
#endif
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
if (pbSupport == 2) {
|
||||
return glXGetVisualFromFBConfigSGIX(dpy, config);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Either use glXGetFBConfigAttrib() or glXGetFBConfigAttribSGIX()
|
||||
* to query an fbconfig attribute.
|
||||
*/
|
||||
static int
|
||||
GetFBConfigAttrib(Display *dpy,
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
const GLXFBConfig config,
|
||||
#elif defined(GLX_SGIX_fbconfig)
|
||||
const GLXFBConfigSGIX config,
|
||||
#endif
|
||||
int attrib
|
||||
)
|
||||
{
|
||||
int value;
|
||||
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
int glxVersionMajor, glxVersionMinor;
|
||||
if (glXQueryVersion(dpy, &glxVersionMajor, &glxVersionMinor)
|
||||
&& glxVersionMajor * 100 + glxVersionMinor >= 103) {
|
||||
/* ok */
|
||||
if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
|
||||
value = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/* fall-through */
|
||||
#endif
|
||||
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
|
||||
value = 0;
|
||||
}
|
||||
return value;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Print parameters for a GLXFBConfig to stdout.
|
||||
* Input: dpy - the X display
|
||||
* screen - the X screen number
|
||||
* fbConfig - the fbconfig handle
|
||||
* horizFormat - if true, print in horizontal format
|
||||
*/
|
||||
void
|
||||
PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat)
|
||||
PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat)
|
||||
{
|
||||
int pbAttribs[] = {GLX_LARGEST_PBUFFER_SGIX, True,
|
||||
GLX_PRESERVED_CONTENTS_SGIX, False,
|
||||
None};
|
||||
GLXPbufferSGIX pBuffer;
|
||||
PBUFFER pBuffer;
|
||||
int width=2, height=2;
|
||||
int bufferSize, level, doubleBuffer, stereo, auxBuffers;
|
||||
int redSize, greenSize, blueSize, alphaSize;
|
||||
@@ -67,44 +158,49 @@ PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat)
|
||||
int drawableType, renderType, xRenderable, xVisual, id;
|
||||
int maxWidth, maxHeight, maxPixels;
|
||||
int optWidth, optHeight;
|
||||
int floatComponents;
|
||||
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_BUFFER_SIZE, &bufferSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_LEVEL, &level);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DOUBLEBUFFER, &doubleBuffer);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_STEREO, &stereo);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_AUX_BUFFERS, &auxBuffers);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_RED_SIZE, &redSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_GREEN_SIZE, &greenSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_BLUE_SIZE, &blueSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ALPHA_SIZE, &alphaSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DEPTH_SIZE, &depthSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_STENCIL_SIZE, &stencilSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_RED_SIZE, &accumRedSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_GREEN_SIZE, &accumGreenSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_BLUE_SIZE, &accumBlueSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_ALPHA_SIZE, &accumAlphaSize);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_SAMPLE_BUFFERS_SGIS, &sampleBuffers);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_SAMPLES_SGIS, &samples);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DRAWABLE_TYPE_SGIX, &drawableType);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_RENDER_TYPE_SGIX, &renderType);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_X_RENDERABLE_SGIX, &xRenderable);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_X_VISUAL_TYPE_EXT, &xVisual);
|
||||
/* do queries using the GLX 1.3 tokens (same as the SGIX tokens) */
|
||||
bufferSize = GetFBConfigAttrib(dpy, config, GLX_BUFFER_SIZE);
|
||||
level = GetFBConfigAttrib(dpy, config, GLX_LEVEL);
|
||||
doubleBuffer = GetFBConfigAttrib(dpy, config, GLX_DOUBLEBUFFER);
|
||||
stereo = GetFBConfigAttrib(dpy, config, GLX_STEREO);
|
||||
auxBuffers = GetFBConfigAttrib(dpy, config, GLX_AUX_BUFFERS);
|
||||
redSize = GetFBConfigAttrib(dpy, config, GLX_RED_SIZE);
|
||||
greenSize = GetFBConfigAttrib(dpy, config, GLX_GREEN_SIZE);
|
||||
blueSize = GetFBConfigAttrib(dpy, config, GLX_BLUE_SIZE);
|
||||
alphaSize = GetFBConfigAttrib(dpy, config, GLX_ALPHA_SIZE);
|
||||
depthSize = GetFBConfigAttrib(dpy, config, GLX_DEPTH_SIZE);
|
||||
stencilSize = GetFBConfigAttrib(dpy, config, GLX_STENCIL_SIZE);
|
||||
accumRedSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_RED_SIZE);
|
||||
accumGreenSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_GREEN_SIZE);
|
||||
accumBlueSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_BLUE_SIZE);
|
||||
accumAlphaSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_ALPHA_SIZE);
|
||||
sampleBuffers = GetFBConfigAttrib(dpy, config, GLX_SAMPLE_BUFFERS);
|
||||
samples = GetFBConfigAttrib(dpy, config, GLX_SAMPLES);
|
||||
drawableType = GetFBConfigAttrib(dpy, config, GLX_DRAWABLE_TYPE);
|
||||
renderType = GetFBConfigAttrib(dpy, config, GLX_RENDER_TYPE);
|
||||
xRenderable = GetFBConfigAttrib(dpy, config, GLX_X_RENDERABLE);
|
||||
xVisual = GetFBConfigAttrib(dpy, config, GLX_X_VISUAL_TYPE);
|
||||
if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX))
|
||||
xVisual = -1;
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_FBCONFIG_ID_SGIX, &id);
|
||||
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_WIDTH_SGIX,
|
||||
&maxWidth);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_HEIGHT_SGIX,
|
||||
&maxHeight);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_PIXELS_SGIX,
|
||||
&maxPixels);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX,
|
||||
&optWidth);
|
||||
glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX,
|
||||
&optHeight);
|
||||
id = GetFBConfigAttrib(dpy, config, GLX_FBCONFIG_ID);
|
||||
maxWidth = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_WIDTH);
|
||||
maxHeight = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_HEIGHT);
|
||||
maxPixels = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_PIXELS);
|
||||
#if defined(GLX_SGIX_pbuffer)
|
||||
optWidth = GetFBConfigAttrib(dpy, config, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX);
|
||||
optHeight = GetFBConfigAttrib(dpy, config, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX);
|
||||
#else
|
||||
optWidth = optHeight = 0;
|
||||
#endif
|
||||
#if defined(GLX_NV_float_buffer)
|
||||
floatComponents = GetFBConfigAttrib(dpy, config, GLX_FLOAT_COMPONENTS_NV);
|
||||
#endif
|
||||
|
||||
pBuffer = CreatePbuffer(dpy, fbConfig, width, height, pbAttribs);
|
||||
/* See if we can create a pbuffer with this config */
|
||||
pBuffer = CreatePbuffer(dpy, screen, config, width, height, False, False);
|
||||
|
||||
if (horizFormat) {
|
||||
printf("0x%03x ", id);
|
||||
@@ -125,7 +221,8 @@ PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat)
|
||||
printf("%2d %2d %2d %2d", accumRedSize, accumGreenSize, accumBlueSize,
|
||||
accumAlphaSize);
|
||||
printf(" %2d %2d", sampleBuffers, samples);
|
||||
printf(" %s", pBuffer ? "y" : "n");
|
||||
printf(" %s %c", pBuffer ? "y" : "n",
|
||||
"ny"[floatComponents]);
|
||||
printf("\n");
|
||||
}
|
||||
else {
|
||||
@@ -148,27 +245,28 @@ PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat)
|
||||
printf(" Sample Buffers: %d\n", sampleBuffers);
|
||||
printf(" Samples/Pixel: %d\n", samples);
|
||||
printf(" Drawable Types: ");
|
||||
if (drawableType & GLX_WINDOW_BIT_SGIX) printf("Window ");
|
||||
if (drawableType & GLX_PIXMAP_BIT_SGIX) printf("Pixmap ");
|
||||
if (drawableType & GLX_PBUFFER_BIT_SGIX) printf("PBuffer");
|
||||
if (drawableType & GLX_WINDOW_BIT) printf("Window ");
|
||||
if (drawableType & GLX_PIXMAP_BIT) printf("Pixmap ");
|
||||
if (drawableType & GLX_PBUFFER_BIT) printf("PBuffer");
|
||||
printf("\n");
|
||||
printf(" Render Types: ");
|
||||
if (renderType & GLX_RGBA_BIT_SGIX) printf("RGBA ");
|
||||
if (renderType & GLX_COLOR_INDEX_BIT_SGIX) printf("CI ");
|
||||
printf("\n");
|
||||
printf(" X Renderable: %s\n", xRenderable ? "yes" : "no");
|
||||
/*
|
||||
printf(" Max width: %d\n", maxWidth);
|
||||
printf(" Max height: %d\n", maxHeight);
|
||||
printf(" Max pixels: %d\n", maxPixels);
|
||||
printf(" Optimum width: %d\n", optWidth);
|
||||
printf(" Optimum height: %d\n", optHeight);
|
||||
*/
|
||||
|
||||
printf(" Pbuffer: %s\n", pBuffer ? "yes" : "no");
|
||||
printf(" Max Pbuffer width: %d\n", maxWidth);
|
||||
printf(" Max Pbuffer height: %d\n", maxHeight);
|
||||
printf(" Max Pbuffer pixels: %d\n", maxPixels);
|
||||
printf(" Optimum Pbuffer width: %d\n", optWidth);
|
||||
printf(" Optimum Pbuffer height: %d\n", optHeight);
|
||||
|
||||
printf(" Float Components: %s\n", floatComponents ? "yes" : "no");
|
||||
}
|
||||
|
||||
if (pBuffer) {
|
||||
glXDestroyGLXPbufferSGIX(dpy, pBuffer);
|
||||
DestroyPbuffer(dpy, screen, pBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,42 +274,73 @@ PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat)
|
||||
|
||||
/* This is only used by CreatePbuffer() */
|
||||
static int XErrorFlag = 0;
|
||||
static int HandleXError( Display *dpy, XErrorEvent *event )
|
||||
static int HandleXError(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
XErrorFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Create a Pbuffer. Use an X error handler to deal with potential
|
||||
* BadAlloc errors.
|
||||
*
|
||||
* Input: dpy - the X display
|
||||
* fbConfig - an FBConfig as returned by glXChooseFBConfigSGIX().
|
||||
* width, height - size of pixel buffer to request, in pixels.
|
||||
* pbAttribs - list of pixel buffer attributes as used by
|
||||
* glXCreateGLXPbufferSGIX().
|
||||
* Return: a pixel buffer or None.
|
||||
* pbAttribs - list of optional pixel buffer attributes
|
||||
* Return: a Pbuffer or None.
|
||||
*/
|
||||
GLXPbufferSGIX
|
||||
CreatePbuffer( Display *dpy, GLXFBConfigSGIX fbConfig,
|
||||
int width, int height, int *pbAttribs )
|
||||
PBUFFER
|
||||
CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
|
||||
int width, int height, Bool largest, Bool preserve)
|
||||
{
|
||||
int (*oldHandler)( Display *, XErrorEvent * );
|
||||
GLXPbufferSGIX pBuffer = None;
|
||||
int (*oldHandler)(Display *, XErrorEvent *);
|
||||
PBUFFER pBuffer = None;
|
||||
int pbSupport = QueryPbuffers(dpy, screen);
|
||||
|
||||
/* Catch X protocol errors with our own error handler */
|
||||
oldHandler = XSetErrorHandler( HandleXError );
|
||||
|
||||
oldHandler = XSetErrorHandler(HandleXError);
|
||||
XErrorFlag = 0;
|
||||
pBuffer = glXCreateGLXPbufferSGIX(dpy, fbConfig, width, height, pbAttribs);
|
||||
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
if (pbSupport == 1) {
|
||||
/* GLX 1.3 */
|
||||
int attribs[100], i = 0;
|
||||
attribs[i++] = GLX_PBUFFER_WIDTH;
|
||||
attribs[i++] = width;
|
||||
attribs[i++] = GLX_PBUFFER_HEIGHT;
|
||||
attribs[i++] = height;
|
||||
attribs[i++] = GLX_PRESERVED_CONTENTS;
|
||||
attribs[i++] = preserve;
|
||||
attribs[i++] = GLX_LARGEST_PBUFFER;
|
||||
attribs[i++] = largest;
|
||||
attribs[i++] = 0;
|
||||
pBuffer = glXCreatePbuffer(dpy, config, attribs);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
if (pbSupport == 2) {
|
||||
int attribs[100], i = 0;
|
||||
attribs[i++] = GLX_PRESERVED_CONTENTS;
|
||||
attribs[i++] = preserve;
|
||||
attribs[i++] = GLX_LARGEST_PBUFFER;
|
||||
attribs[i++] = largest;
|
||||
attribs[i++] = 0;
|
||||
pBuffer = glXCreateGLXPbufferSGIX(dpy, config, width, height, attribs);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pBuffer = None;
|
||||
}
|
||||
|
||||
/* Restore original X error handler */
|
||||
(void) XSetErrorHandler( oldHandler );
|
||||
(void) XSetErrorHandler(oldHandler);
|
||||
|
||||
/* Return pbuffer (may be None) */
|
||||
if (!XErrorFlag && pBuffer!=None) {
|
||||
if (!XErrorFlag && pBuffer != None) {
|
||||
/*printf("config %d worked!\n", i);*/
|
||||
return pBuffer;
|
||||
}
|
||||
@@ -221,7 +350,20 @@ CreatePbuffer( Display *dpy, GLXFBConfigSGIX fbConfig,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /*GLX_SGIX_fbconfig*/
|
||||
|
||||
|
||||
void
|
||||
DestroyPbuffer(Display *dpy, int screen, PBUFFER pbuffer)
|
||||
{
|
||||
int pbSupport = QueryPbuffers(dpy, screen);
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
if (pbSupport == 1) {
|
||||
glXDestroyPbuffer(dpy, pbuffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
if (pbSupport == 2) {
|
||||
glXDestroyGLXPbufferSGIX(dpy, pbuffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* OpenGL pbuffers utility functions.
|
||||
*
|
||||
@@ -15,23 +14,41 @@
|
||||
#include <GL/glx.h>
|
||||
|
||||
|
||||
#if defined(GLX_VERSION_1_3)
|
||||
#define PBUFFER GLXPbuffer
|
||||
#define FBCONFIG GLXFBConfig
|
||||
#elif defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||
#define PBUFFER GLXPbufferSGIX
|
||||
#define FBCONFIG GLXFBConfigSGIX
|
||||
#else
|
||||
#define PBUFFER int
|
||||
#define FBCONFIG int
|
||||
#endif
|
||||
|
||||
|
||||
extern int
|
||||
QueryPbuffers(Display *dpy, int screen);
|
||||
|
||||
|
||||
#ifdef GLX_SGIX_fbconfig
|
||||
extern void
|
||||
PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat);
|
||||
|
||||
|
||||
extern FBCONFIG *
|
||||
ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs);
|
||||
|
||||
|
||||
extern XVisualInfo *
|
||||
GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config);
|
||||
|
||||
|
||||
extern PBUFFER
|
||||
CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
|
||||
int width, int height, Bool preserve, Bool largest);
|
||||
|
||||
|
||||
extern void
|
||||
PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat);
|
||||
|
||||
|
||||
extern GLXPbufferSGIX
|
||||
CreatePbuffer( Display *dpy, GLXFBConfigSGIX fbConfig,
|
||||
int width, int height, int *pbAttribs );
|
||||
|
||||
|
||||
#endif /*GLX_SGIX_fbconfig*/
|
||||
DestroyPbuffer(Display *dpy, int screen, PBUFFER pbuffer);
|
||||
|
||||
|
||||
#endif /*PBUTIL_H*/
|
||||
|
||||
@@ -1263,23 +1263,23 @@ CARD8 __glXSetupForCommand(Display *dpy)
|
||||
return priv->majorOpcode;
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the drawing command transport buffer.
|
||||
*/
|
||||
/**
|
||||
* Flush the drawing command transport buffer.
|
||||
*
|
||||
* \param ctx Context whose transport buffer is to be flushed.
|
||||
* \param pc Pointer to first unused buffer location.
|
||||
*
|
||||
* \todo
|
||||
* Modify this function to use \c ctx->pc instead of the explicit
|
||||
* \c pc parameter.
|
||||
*/
|
||||
GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
|
||||
{
|
||||
Display *dpy;
|
||||
Display * const dpy = ctx->currentDpy;
|
||||
xGLXRenderReq *req;
|
||||
GLint size;
|
||||
const GLint size = pc - ctx->buf;
|
||||
|
||||
if (!(dpy = ctx->currentDpy)) {
|
||||
/* Using the dummy context */
|
||||
ctx->pc = ctx->buf;
|
||||
return ctx->pc;
|
||||
}
|
||||
|
||||
size = pc - ctx->buf;
|
||||
if (size) {
|
||||
if ( (dpy != NULL) && (size > 0) ) {
|
||||
/* Send the entire buffer as an X request */
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXRender,req);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,8 @@ default:
|
||||
$(MAKE) osmesa-only ; \
|
||||
elif [ "$(DRIVER_DIRS)" = "beos" ]; then \
|
||||
$(MAKE) beos ; \
|
||||
elif [ "$(DRIVER_DIRS)" = "directfb" ]; then \
|
||||
$(MAKE) directfb; \
|
||||
else \
|
||||
$(MAKE) stand-alone ; \
|
||||
fi
|
||||
@@ -69,6 +71,30 @@ drivers-dri:
|
||||
cd drivers/dri ; $(MAKE)
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Stand-alone Mesa libGL, no built-in drivers (DirectFB)
|
||||
|
||||
LIBGL_CORE_SOURCES = \
|
||||
$(CORE_SOURCES) \
|
||||
$(ASM_SOURCES)
|
||||
|
||||
LIBGL_CORE_OBJECTS = \
|
||||
$(CORE_OBJECTS) \
|
||||
$(ASM_SOURCES:.S=.o)
|
||||
|
||||
# Make libGL from core object files
|
||||
libgl-core: $(LIBGL_CORE_OBJECTS)
|
||||
@ CC=$(CC) CXX=$(CXX) $(TOP)/bin/mklib -o $(GL_LIB) \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(LIB_DIR) $(MKLIB_OPTIONS) $(LIBGL_CORE_OBJECTS) $(GL_LIB_DEPS)
|
||||
|
||||
# DirectFB driver target
|
||||
directfb: depend subdirs libgl-core
|
||||
cd drivers/directfb; $(MAKE)
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# Stand-alone Mesa libGL and libOSMesa
|
||||
|
||||
|
||||
53
src/mesa/drivers/directfb/Makefile
Normal file
53
src/mesa/drivers/directfb/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
# src/mesa/drivers/directfb/Makefile
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
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/tnl \
|
||||
-I$(TOP)/src/mesa/shader \
|
||||
-I$(TOP)/src/mesa/swrast \
|
||||
-I$(TOP)/src/mesa/swrast_setup
|
||||
|
||||
DFB_CFLAGS = $(shell pkg-config --cflags directfb)
|
||||
DFB_MODULEDIR = $(shell pkg-config --variable=moduledir directfb-internal)
|
||||
|
||||
DIRECTFBGL_MESA_SOURCES = ../common/driverfuncs.c idirectfbgl_mesa.c
|
||||
|
||||
DIRECTFBGL_MESA_OBJECTS = $(DIRECTFBGL_MESA_SOURCES:.c=.o)
|
||||
|
||||
DIRECTFBGL_MESA = libidirectfbgl_mesa.so
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DFB_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: directfbgl_mesa
|
||||
|
||||
# Mesa DirectFBGL module
|
||||
directfbgl_mesa: $(DIRECTFBGL_MESA_OBJECTS)
|
||||
$(CC) -shared $(CFLAGS) $(DIRECTFBGL_MESA_OBJECTS) -o $(DIRECTFBGL_MESA) \
|
||||
-Wl,-soname -Wl,$(DIRECTFBGL_MESA) -L$(TOP)/lib -lGL -lm
|
||||
|
||||
|
||||
install:
|
||||
@if test -d $(DFB_MODULEDIR); then \
|
||||
echo "Installing DirectFBGL module."; \
|
||||
else \
|
||||
echo "*** Failed to determine DirectFB module's directory."; \
|
||||
echo "*** Installation aborted."; \
|
||||
exit 1; \
|
||||
fi;
|
||||
install -m 0755 $(DIRECTFBGL_MESA) $(DFB_MODULEDIR)/interfaces/IDirectFBGL/
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so
|
||||
|
||||
642
src/mesa/drivers/directfb/idirectfbgl_mesa.c
Normal file
642
src/mesa/drivers/directfb/idirectfbgl_mesa.c
Normal file
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Claudio Ciccani <klan@users.sf.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Based on glfbdev.c, written by Brian Paul.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
#include <direct/messages.h>
|
||||
#include <direct/interface.h>
|
||||
#include <direct/mem.h>
|
||||
|
||||
#ifdef CLAMP
|
||||
# undef CLAMP
|
||||
#endif
|
||||
|
||||
#include "GL/directfbgl.h"
|
||||
#include "glheader.h"
|
||||
#include "buffers.h"
|
||||
#include "context.h"
|
||||
#include "extensions.h"
|
||||
#include "imports.h"
|
||||
#include "texformat.h"
|
||||
#include "teximage.h"
|
||||
#include "texstore.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
|
||||
|
||||
static DFBResult
|
||||
Probe( void *data );
|
||||
|
||||
static DFBResult
|
||||
Construct( IDirectFBGL *thiz,
|
||||
IDirectFBSurface *surface );
|
||||
|
||||
#include <direct/interface_implementation.h>
|
||||
|
||||
DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL, Mesa )
|
||||
|
||||
/*
|
||||
* private data struct of IDirectFBGL
|
||||
*/
|
||||
typedef struct {
|
||||
int ref; /* reference counter */
|
||||
|
||||
bool locked;
|
||||
|
||||
IDirectFBSurface *surface;
|
||||
DFBSurfacePixelFormat format;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
struct {
|
||||
__u8 *start;
|
||||
__u8 *end;
|
||||
int pitch;
|
||||
} video;
|
||||
|
||||
GLvisual visual;
|
||||
GLframebuffer framebuffer;
|
||||
GLcontext context;
|
||||
} IDirectFBGL_data;
|
||||
|
||||
|
||||
static bool dfb_mesa_setup_visual ( GLvisual *visual,
|
||||
DFBSurfacePixelFormat format );
|
||||
static bool dfb_mesa_create_context ( GLcontext *context,
|
||||
GLframebuffer *framebuffer,
|
||||
GLvisual *visual,
|
||||
DFBSurfacePixelFormat format,
|
||||
void *data );
|
||||
static void dfb_mesa_destroy_context( GLcontext *context,
|
||||
GLframebuffer *framebuffer );
|
||||
|
||||
|
||||
static void
|
||||
IDirectFBGL_Destruct( IDirectFBGL *thiz )
|
||||
{
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv;
|
||||
|
||||
dfb_mesa_destroy_context( &data->context, &data->framebuffer );
|
||||
|
||||
data->surface->Release( data->surface );
|
||||
|
||||
DIRECT_DEALLOCATE_INTERFACE( thiz );
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
IDirectFBGL_AddRef( IDirectFBGL *thiz )
|
||||
{
|
||||
DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
|
||||
|
||||
data->ref++;
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
IDirectFBGL_Release( IDirectFBGL *thiz )
|
||||
{
|
||||
DIRECT_INTERFACE_GET_DATA( IDirectFBGL )
|
||||
|
||||
if (--data->ref == 0) {
|
||||
IDirectFBGL_Destruct( thiz );
|
||||
}
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
IDirectFBGL_Lock( IDirectFBGL *thiz )
|
||||
{
|
||||
IDirectFBSurface *surface;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
DFBResult err;
|
||||
|
||||
DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
|
||||
|
||||
if (data->locked)
|
||||
return DFB_LOCKED;
|
||||
|
||||
surface = data->surface;
|
||||
surface->GetSize( surface, &width, &height );
|
||||
|
||||
err = surface->Lock( surface, DSLF_READ | DSLF_WRITE,
|
||||
(void**) &data->video.start, &data->video.pitch );
|
||||
if (err != DFB_OK) {
|
||||
D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
|
||||
return err;
|
||||
}
|
||||
data->video.end = data->video.start + (height-1) * data->video.pitch;
|
||||
|
||||
if (data->width != width || data->height != height) {
|
||||
data->width = width;
|
||||
data->height = height;
|
||||
_mesa_ResizeBuffersMESA();
|
||||
}
|
||||
|
||||
data->locked = true;
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
IDirectFBGL_Unlock( IDirectFBGL *thiz )
|
||||
{
|
||||
DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
|
||||
|
||||
if (!data->locked)
|
||||
return DFB_OK;
|
||||
|
||||
data->surface->Unlock( data->surface );
|
||||
data->video.start = NULL;
|
||||
data->video.end = NULL;
|
||||
|
||||
data->locked = false;
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
IDirectFBGL_GetAttributes( IDirectFBGL *thiz,
|
||||
DFBGLAttributes *attributes )
|
||||
{
|
||||
GLvisual *visual;
|
||||
|
||||
DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
|
||||
|
||||
if (!attributes)
|
||||
return DFB_INVARG;
|
||||
|
||||
visual = &data->visual;
|
||||
|
||||
attributes->buffer_size = visual->rgbBits ? : visual->indexBits;
|
||||
attributes->depth_size = visual->depthBits;
|
||||
attributes->stencil_size = visual->stencilBits;
|
||||
attributes->aux_buffers = visual->numAuxBuffers;
|
||||
attributes->red_size = visual->redBits;
|
||||
attributes->green_size = visual->greenBits;
|
||||
attributes->blue_size = visual->blueBits;
|
||||
attributes->alpha_size = visual->alphaBits;
|
||||
attributes->accum_red_size = visual->accumRedBits;
|
||||
attributes->accum_green_size = visual->accumGreenBits;
|
||||
attributes->accum_blue_size = visual->accumBlueBits;
|
||||
attributes->accum_alpha_size = visual->accumAlphaBits;
|
||||
attributes->double_buffer = (visual->doubleBufferMode != 0);
|
||||
attributes->stereo = (visual->stereoMode != 0);
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
|
||||
/* exported symbols */
|
||||
|
||||
static DFBResult
|
||||
Probe( void *data )
|
||||
{
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
static DFBResult
|
||||
Construct( IDirectFBGL *thiz,
|
||||
IDirectFBSurface *surface )
|
||||
{
|
||||
/* Allocate interface data. */
|
||||
DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL );
|
||||
|
||||
/* Initialize interface data. */
|
||||
data->ref = 1;
|
||||
data->surface = surface;
|
||||
|
||||
surface->AddRef( surface );
|
||||
surface->GetPixelFormat( surface, &data->format );
|
||||
surface->GetSize( surface, &data->width, &data->height );
|
||||
|
||||
/* Configure visual. */
|
||||
if (!dfb_mesa_setup_visual( &data->visual, data->format )) {
|
||||
D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
|
||||
surface->Release( surface );
|
||||
return DFB_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Create context. */
|
||||
if (!dfb_mesa_create_context( &data->context, &data->framebuffer,
|
||||
&data->visual, data->format, (void*) data )) {
|
||||
D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
|
||||
surface->Release( surface );
|
||||
return DFB_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Assign interface pointers. */
|
||||
thiz->AddRef = IDirectFBGL_AddRef;
|
||||
thiz->Release = IDirectFBGL_Release;
|
||||
thiz->Lock = IDirectFBGL_Lock;
|
||||
thiz->Unlock = IDirectFBGL_Unlock;
|
||||
thiz->GetAttributes = IDirectFBGL_GetAttributes;
|
||||
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
|
||||
/* internal functions */
|
||||
|
||||
static const GLubyte*
|
||||
get_string( GLcontext *ctx, GLenum pname )
|
||||
{
|
||||
switch (pname) {
|
||||
case GL_VENDOR:
|
||||
return "Claudio Ciccani";
|
||||
case GL_VERSION:
|
||||
return "1.0";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_state( GLcontext *ctx, GLuint new_state )
|
||||
{
|
||||
_swrast_InvalidateState( ctx, new_state );
|
||||
_swsetup_InvalidateState( ctx, new_state );
|
||||
_ac_InvalidateState( ctx, new_state );
|
||||
_tnl_InvalidateState( ctx, new_state );
|
||||
}
|
||||
|
||||
static void
|
||||
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
|
||||
{
|
||||
GLcontext *ctx = _mesa_get_current_context();
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
|
||||
*width = (GLuint) data->width;
|
||||
*height = (GLuint) data->height;
|
||||
}
|
||||
|
||||
static void
|
||||
set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
|
||||
{
|
||||
_mesa_ResizeBuffersMESA();
|
||||
}
|
||||
|
||||
/* required but not used */
|
||||
static void
|
||||
set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* RGB332 */
|
||||
#define NAME(PREFIX) PREFIX##_RGB332
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLubyte *P = data->video.end - (Y) * data->video.pitch + (X)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0xe0) ); \
|
||||
G = ((*P & 0x1c) << 3); \
|
||||
B = ((*P & 0x03) << 6); \
|
||||
A = CHAN_MAX
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* ARGB1555 */
|
||||
#define NAME(PREFIX) PREFIX##_ARGB1555
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( (((A) & 0x80) << 8) | (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0x7c00) >> 7); \
|
||||
G = ((*P & 0x03e0) >> 2); \
|
||||
B = ((*P & 0x001f) << 3); \
|
||||
A = ((*P & 0x8000) ? 0xff : 0)
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* RGB16 */
|
||||
#define NAME(PREFIX) PREFIX##_RGB16
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0xf800) >> 8); \
|
||||
G = ((*P & 0x07e0) >> 3); \
|
||||
B = ((*P & 0x001f) << 3); \
|
||||
A = CHAN_MAX
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* RGB24 */
|
||||
#define NAME(PREFIX) PREFIX##_RGB24
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3
|
||||
#define INC_PIXEL_PTR(P) P += 3
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
P[0] = B; P[1] = G; P[2] = R
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
P[0] = B; P[1] = G; P[2] = R
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* RGB32 */
|
||||
#define NAME(PREFIX) PREFIX##_RGB32
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0x00ff0000) >> 16); \
|
||||
G = ((*P & 0x0000ff00) >> 8); \
|
||||
B = ((*P & 0x000000ff) ); \
|
||||
A = CHAN_MAX
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* ARGB */
|
||||
#define NAME(PREFIX) PREFIX##_ARGB
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( 0xff000000 | ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( ((A) << 24) | ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0x00ff0000) >> 16); \
|
||||
G = ((*P & 0x0000ff00) >> 8); \
|
||||
B = ((*P & 0x000000ff) ); \
|
||||
A = ((*P & 0xff000000) >> 24)
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
/* AiRGB */
|
||||
#define NAME(PREFIX) PREFIX##_AiRGB
|
||||
#define SPAN_VARS \
|
||||
IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
|
||||
#define INIT_PIXEL_PTR(P, X, Y) \
|
||||
GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
|
||||
#define INC_PIXEL_PTR(P) P += 1
|
||||
#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
|
||||
*P = ( ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
|
||||
*P = ( ((0xff - (A)) << 24) | ((R) << 16) | ((G) << 8) | (B) )
|
||||
#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
|
||||
R = ((*P & 0x00ff0000) >> 16); \
|
||||
G = ((*P & 0x0000ff00) >> 8); \
|
||||
B = ((*P & 0x000000ff) ); \
|
||||
A = (0xff - ((*P & 0xff000000) >> 24))
|
||||
|
||||
#include "swrast/s_spantemp.h"
|
||||
|
||||
|
||||
static bool
|
||||
dfb_mesa_setup_visual( GLvisual *visual,
|
||||
DFBSurfacePixelFormat format )
|
||||
{
|
||||
GLboolean rgbFlag = GL_TRUE;
|
||||
GLboolean dbFlag = GL_FALSE;
|
||||
GLboolean stereoFlag = GL_FALSE;
|
||||
GLint redBits = 0;
|
||||
GLint blueBits = 0;
|
||||
GLint greenBits = 0;
|
||||
GLint alphaBits = 0;
|
||||
GLint indexBits = 0;
|
||||
GLint depthBits = 0;
|
||||
GLint stencilBits = 0;
|
||||
GLint accumRedBits = 0;
|
||||
GLint accumGreenBits = 0;
|
||||
GLint accumBlueBits = 0;
|
||||
GLint accumAlphaBits = 0;
|
||||
GLint numSamples = 0;
|
||||
|
||||
/* FIXME: LUT8 support. */
|
||||
switch (format) {
|
||||
case DSPF_RGB332:
|
||||
redBits = 3;
|
||||
greenBits = 3;
|
||||
blueBits = 2;
|
||||
break;
|
||||
case DSPF_ARGB1555:
|
||||
redBits = 5;
|
||||
greenBits = 5;
|
||||
blueBits = 5;
|
||||
alphaBits = 1;
|
||||
break;
|
||||
case DSPF_RGB16:
|
||||
redBits = 5;
|
||||
greenBits = 6;
|
||||
blueBits = 5;
|
||||
break;
|
||||
case DSPF_ARGB:
|
||||
case DSPF_AiRGB:
|
||||
alphaBits = 8;
|
||||
case DSPF_RGB24:
|
||||
case DSPF_RGB32:
|
||||
redBits = 8;
|
||||
greenBits = 8;
|
||||
blueBits = 8;
|
||||
break;
|
||||
default:
|
||||
D_WARN( "unsupported pixelformat" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rgbFlag) {
|
||||
accumRedBits = redBits;
|
||||
accumGreenBits = greenBits;
|
||||
accumBlueBits = blueBits;
|
||||
accumAlphaBits = alphaBits;
|
||||
depthBits = redBits + greenBits + blueBits;
|
||||
stencilBits = alphaBits;
|
||||
} else
|
||||
depthBits = 8;
|
||||
|
||||
return _mesa_initialize_visual( visual,
|
||||
rgbFlag, dbFlag, stereoFlag,
|
||||
redBits, greenBits, blueBits, alphaBits,
|
||||
indexBits, depthBits, stencilBits,
|
||||
accumRedBits, accumGreenBits,
|
||||
accumBlueBits, accumAlphaBits,
|
||||
numSamples );
|
||||
}
|
||||
|
||||
static bool
|
||||
dfb_mesa_create_context( GLcontext *context,
|
||||
GLframebuffer *framebuffer,
|
||||
GLvisual *visual,
|
||||
DFBSurfacePixelFormat format,
|
||||
void *data )
|
||||
{
|
||||
struct dd_function_table functions;
|
||||
struct swrast_device_driver *swdd;
|
||||
|
||||
_mesa_initialize_framebuffer( framebuffer, visual,
|
||||
visual->haveDepthBuffer,
|
||||
visual->haveStencilBuffer,
|
||||
visual->haveAccumBuffer,
|
||||
visual->accumAlphaBits > 0 );
|
||||
|
||||
_mesa_init_driver_functions( &functions );
|
||||
functions.GetString = get_string;
|
||||
functions.UpdateState = update_state;
|
||||
functions.GetBufferSize = get_buffer_size;
|
||||
functions.Viewport = set_viewport;
|
||||
|
||||
if (!_mesa_initialize_context( context, visual, NULL,
|
||||
&functions, data )) {
|
||||
D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
|
||||
_mesa_free_framebuffer_data( framebuffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
_swrast_CreateContext( context );
|
||||
_ac_CreateContext( context );
|
||||
_tnl_CreateContext( context );
|
||||
_swsetup_CreateContext( context );
|
||||
_swsetup_Wakeup( context );
|
||||
|
||||
swdd = _swrast_GetDeviceDriverReference( context );
|
||||
swdd->SetBuffer = set_buffer;
|
||||
switch (format) {
|
||||
case DSPF_RGB332:
|
||||
swdd->WriteRGBASpan = write_rgba_span_RGB332;
|
||||
swdd->WriteRGBSpan = write_rgb_span_RGB332;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_RGB332;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_RGB332;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB332;
|
||||
swdd->ReadRGBASpan = read_rgba_span_RGB332;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_RGB332;
|
||||
break;
|
||||
case DSPF_ARGB1555:
|
||||
swdd->WriteRGBASpan = write_rgba_span_ARGB1555;
|
||||
swdd->WriteRGBSpan = write_rgb_span_ARGB1555;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_ARGB1555;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_ARGB1555;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_ARGB1555;
|
||||
swdd->ReadRGBASpan = read_rgba_span_ARGB1555;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_ARGB1555;
|
||||
break;
|
||||
case DSPF_RGB16:
|
||||
swdd->WriteRGBASpan = write_rgba_span_RGB16;
|
||||
swdd->WriteRGBSpan = write_rgb_span_RGB16;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_RGB16;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_RGB16;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB16;
|
||||
swdd->ReadRGBASpan = read_rgba_span_RGB16;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_RGB16;
|
||||
break;
|
||||
case DSPF_RGB24:
|
||||
swdd->WriteRGBASpan = write_rgba_span_RGB24;
|
||||
swdd->WriteRGBSpan = write_rgb_span_RGB24;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_RGB24;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_RGB24;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB24;
|
||||
swdd->ReadRGBASpan = read_rgba_span_RGB24;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_RGB24;
|
||||
break;
|
||||
case DSPF_RGB32:
|
||||
swdd->WriteRGBASpan = write_rgba_span_RGB32;
|
||||
swdd->WriteRGBSpan = write_rgb_span_RGB32;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_RGB32;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_RGB32;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB32;
|
||||
swdd->ReadRGBASpan = read_rgba_span_RGB32;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_RGB32;
|
||||
break;
|
||||
case DSPF_ARGB:
|
||||
swdd->WriteRGBASpan = write_rgba_span_ARGB;
|
||||
swdd->WriteRGBSpan = write_rgb_span_ARGB;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_ARGB;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_ARGB;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_ARGB;
|
||||
swdd->ReadRGBASpan = read_rgba_span_ARGB;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_ARGB;
|
||||
break;
|
||||
case DSPF_AiRGB:
|
||||
swdd->WriteRGBASpan = write_rgba_span_AiRGB;
|
||||
swdd->WriteRGBSpan = write_rgb_span_AiRGB;
|
||||
swdd->WriteMonoRGBASpan = write_monorgba_span_AiRGB;
|
||||
swdd->WriteRGBAPixels = write_rgba_pixels_AiRGB;
|
||||
swdd->WriteMonoRGBAPixels = write_monorgba_pixels_AiRGB;
|
||||
swdd->ReadRGBASpan = read_rgba_span_AiRGB;
|
||||
swdd->ReadRGBAPixels = read_rgba_pixels_AiRGB;
|
||||
break;
|
||||
default:
|
||||
D_BUG( "unexpected pixelformat" );
|
||||
return false;
|
||||
}
|
||||
|
||||
TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
|
||||
_mesa_enable_sw_extensions( context );
|
||||
|
||||
_mesa_make_current( context, framebuffer );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
dfb_mesa_destroy_context( GLcontext *context,
|
||||
GLframebuffer *framebuffer )
|
||||
{
|
||||
_mesa_make_current( NULL, NULL );
|
||||
_mesa_free_framebuffer_data( framebuffer );
|
||||
_mesa_notifyDestroy( context );
|
||||
_mesa_free_context_data( context );
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ WINOBJ=
|
||||
WINLIB=-L$(MESA)/src/glx/mini
|
||||
MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
|
||||
INCLUDES = $(MINIGLX_INCLUDES) \
|
||||
-I$(DRM_SOURCE_PATH)/shared \
|
||||
-I$(DRM_SOURCE_PATH)/shared-core \
|
||||
-I$(DRM_SOURCE_PATH)/libdrm \
|
||||
$(SHARED_INCLUDES)
|
||||
|
||||
@@ -36,8 +36,7 @@ SHARED_INCLUDES = \
|
||||
-I. \
|
||||
-I$(TOP)/src/mesa/drivers/dri/common \
|
||||
-Iserver \
|
||||
-I$(DRM_SOURCE_PATH)/shared \
|
||||
-I$(DRM_SOURCE_PATH)/linux \
|
||||
-I$(DRM_SOURCE_PATH)/shared-core \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/include/GL/internal \
|
||||
-I$(TOP)/src/mesa \
|
||||
@@ -95,7 +94,7 @@ tags:
|
||||
|
||||
# Remove .o and backup files
|
||||
clean:
|
||||
-rm -f *.o */*.o *~ *.o *~ *.so server/*.o $(SYMLINKS)
|
||||
-rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS)
|
||||
-rm -f depend depend.bak
|
||||
|
||||
include depend
|
||||
|
||||
@@ -210,6 +210,12 @@ DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \
|
||||
DRI_CONF_DESC_END \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_FLOAT_DEPTH(def) \
|
||||
DRI_CONF_OPT_BEGIN(float_depth,bool,def) \
|
||||
DRI_CONF_DESC(en,"Floating point depth buffer") \
|
||||
DRI_CONF_DESC(de,"Fließkomma z-Puffer") \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
/** \brief Performance-related options */
|
||||
#define DRI_CONF_SECTION_PERFORMANCE \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
|
||||
@@ -145,7 +145,7 @@ intelTryReadPixels( GLcontext *ctx,
|
||||
GLvoid *pixels )
|
||||
{
|
||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
||||
GLint size;
|
||||
GLint size = 0;
|
||||
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
||||
|
||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# src/mesa/drivers/dri/r300/Makefile
|
||||
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
@@ -31,6 +32,10 @@ DRIVER_SOURCES = \
|
||||
r300_cmdbuf.c \
|
||||
r300_state.c \
|
||||
r300_render.c \
|
||||
r300_lib.c \
|
||||
r300_texmem.c \
|
||||
r300_tex.c \
|
||||
r300_texstate.c \
|
||||
\
|
||||
r200_context.c \
|
||||
r200_ioctl.c \
|
||||
@@ -50,6 +55,7 @@ DRIVER_SOURCES = \
|
||||
r200_vtxfmt_sse.c \
|
||||
r200_vtxfmt_x86.c
|
||||
|
||||
|
||||
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
|
||||
|
||||
X86_SOURCES = r200_vtxtmp_x86.S
|
||||
|
||||
94
src/mesa/drivers/dri/r300/pixel_shader.h
Normal file
94
src/mesa/drivers/dri/r300/pixel_shader.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef __PIXEL_SHADER_H__
|
||||
#define __PIXEL_SHADER_H__
|
||||
|
||||
#include "r300_reg.h"
|
||||
|
||||
|
||||
/* INSTR 0 */
|
||||
|
||||
#define PFS_OP_MAD 0
|
||||
#define PFS_OP_DP3 1
|
||||
#define PFS_OP_DP4 2
|
||||
#define PFS_OP_MIN 4
|
||||
#define PFS_OP_MAX 5
|
||||
#define PFS_OP_CMP 8
|
||||
#define PFS_OP_FRC 9
|
||||
#define PFS_OP_OUTC_REPL_ALPHA 10
|
||||
|
||||
/* "or" these with arg0 value to negate or take absolute value of an argument */
|
||||
#define PFS_ARG_NEG (1<<5)
|
||||
#define PFS_ARG_ABS (1<<6)
|
||||
|
||||
#define MAKE_PFS_INSTR0(op, arg0, arg1, arg2, flags) \
|
||||
( ((op)<<23) \
|
||||
| ((arg0)<<R300_FPI0_ARG0C_SHIFT) \
|
||||
| ((arg1)<<R300_FPI0_ARG1C_SHIFT) \
|
||||
| ((arg2)<<R300_FPI0_ARG2C_SHIFT) \
|
||||
| (flags) \
|
||||
)
|
||||
|
||||
#define PFS_FLAG_X 1
|
||||
#define PFS_FLAG_Y 2
|
||||
#define PFS_FLAG_XY 3
|
||||
#define PFS_FLAG_Z 4
|
||||
#define PFS_FLAG_XZ 5
|
||||
#define PFS_FLAG_YZ 6
|
||||
#define PFS_FLAG_ALL 7
|
||||
#define PFS_FLAG_NONE 0
|
||||
|
||||
#define EASY_PFS_INSTR0(op, arg0, arg1, arg2) \
|
||||
MAKE_PFS_INSTR0(PFS_OP_##op, \
|
||||
R300_FPI0_ARGC_##arg0, \
|
||||
R300_FPI0_ARGC_##arg1, \
|
||||
R300_FPI0_ARGC_##arg2, \
|
||||
0)
|
||||
|
||||
/* INSTR 1 */
|
||||
|
||||
#define PFS_FLAG_CONST (1<<5)
|
||||
|
||||
#define MAKE_PFS_INSTR1(dstc, src0, src1, src2, reg, output) \
|
||||
((src0) | ((src1) << R300_FPI1_SRC1C_SHIFT) \
|
||||
| ((src2)<<R300_FPI1_SRC2C_SHIFT) \
|
||||
| ((dstc) << R300_FPI1_DSTC_SHIFT) \
|
||||
| ((reg) << 23) | ((output)<<26))
|
||||
|
||||
#define EASY_PFS_INSTR1(dstc, src0, src1, src2, reg, output) \
|
||||
MAKE_PFS_INSTR1(dstc, src0, src1, src2, PFS_FLAG_##reg, PFS_FLAG_##output)
|
||||
|
||||
/* INSTR 2 */
|
||||
|
||||
/* you can "or" PFS_ARG_NEG with these values to negate them */
|
||||
|
||||
#define MAKE_PFS_INSTR2(op, arg0, arg1, arg2, flags) \
|
||||
(((op) << 23) | \
|
||||
((arg0)<<R300_FPI2_ARG0A_SHIFT) | \
|
||||
((arg1)<<R300_FPI2_ARG1A_SHIFT) | \
|
||||
((arg2)<<R300_FPI2_ARG2A_SHIFT) | \
|
||||
(flags))
|
||||
|
||||
#define EASY_PFS_INSTR2(op, arg0, arg1, arg2) \
|
||||
MAKE_PFS_INSTR2(R300_FPI2_OUTA_##op, \
|
||||
R300_FPI2_ARGA_##arg0, \
|
||||
R300_FPI2_ARGA_##arg1, \
|
||||
R300_FPI2_ARGA_##arg2, \
|
||||
0)
|
||||
|
||||
|
||||
/* INSTR 3 */
|
||||
|
||||
#define PFS_FLAG_NONE 0
|
||||
#define PFS_FLAG_REG 1
|
||||
#define PFS_FLAG_OUTPUT 2
|
||||
#define PFS_FLAG_BOTH 3
|
||||
|
||||
#define MAKE_PFS_INSTR3(dstc, src0, src1, src2, flags) \
|
||||
((src0) | ((src1) << R300_FPI1_SRC1C_SHIFT) \
|
||||
| ((src2)<<R300_FPI1_SRC2C_SHIFT) \
|
||||
| ((dstc) << R300_FPI1_DSTC_SHIFT) \
|
||||
| ((flags) << 23))
|
||||
|
||||
#define EASY_PFS_INSTR3(dstc, src0, src1, src2, flag) \
|
||||
MAKE_PFS_INSTR3(dstc, src0, src1, src2, PFS_FLAG_##flag)
|
||||
|
||||
#endif
|
||||
@@ -46,8 +46,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "r300_emit.h"
|
||||
|
||||
|
||||
// Set this to 1 for extremely verbose debugging of command buffers
|
||||
@@ -212,6 +214,7 @@ void r300EmitState(r300ContextPtr r300)
|
||||
r300->hw.all_dirty = GL_FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static __inline__ uint32_t cmducs(int reg, int count)
|
||||
{
|
||||
@@ -236,6 +239,7 @@ static __inline__ uint32_t cmdvpu(int addr, int count)
|
||||
|
||||
return cmd.u;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CHECK( NM, COUNT ) \
|
||||
static int check_##NM( r300ContextPtr r300, \
|
||||
@@ -273,9 +277,12 @@ CHECK( vpu, vpucount(atom->cmd) ? (1 + vpucount(atom->cmd)*4) : 0 )
|
||||
*/
|
||||
void r300InitCmdBuf(r300ContextPtr r300)
|
||||
{
|
||||
int size;
|
||||
int size, i, mtu;
|
||||
|
||||
r300->hw.max_state_size = 0;
|
||||
|
||||
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
|
||||
fprintf(stderr, "Using %d maximum texture units..\n", mtu);
|
||||
|
||||
/* Initialize state atoms */
|
||||
ALLOC_STATE( vpt, always, R300_VPT_CMDSIZE, "vpt", 0 );
|
||||
@@ -284,8 +291,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
r300->hw.unk2080.cmd[0] = cmducs(0x2080, 1);
|
||||
ALLOC_STATE( ovf, always, R300_OVF_CMDSIZE, "ovf", 0 );
|
||||
r300->hw.ovf.cmd[R300_OVF_CMD_0] = cmducs(R300_VAP_OUTPUT_VTX_FMT_0, 2);
|
||||
ALLOC_STATE( unk20B0, always, 3, "unk20B0", 0 );
|
||||
r300->hw.unk20B0.cmd[0] = cmducs(0x20B0, 2);
|
||||
ALLOC_STATE( vte, always, 3, "vte", 0 );
|
||||
r300->hw.vte.cmd[0] = cmducs(R300_SE_VTE_CNTL, 2);
|
||||
ALLOC_STATE( unk2134, always, 3, "unk2134", 0 );
|
||||
r300->hw.unk2134.cmd[0] = cmducs(0x2134, 2);
|
||||
ALLOC_STATE( unk2140, always, 2, "unk2140", 0 );
|
||||
@@ -304,12 +311,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
r300->hw.unk2220.cmd[0] = cmducs(0x2220, 4);
|
||||
ALLOC_STATE( unk2288, always, 2, "unk2288", 0 );
|
||||
r300->hw.unk2288.cmd[0] = cmducs(0x2288, 1);
|
||||
ALLOC_STATE( vof, always, R300_VOF_CMDSIZE, "vof", 0 );
|
||||
r300->hw.vof.cmd[R300_VOF_CMD_0] = cmducs(R300_VAP_OUTPUT_VTX_FMT_0, 2);
|
||||
ALLOC_STATE( pvs, always, R300_PVS_CMDSIZE, "pvs", 0 );
|
||||
r300->hw.pvs.cmd[R300_PVS_CMD_0] = cmducs(R300_VAP_PVS_CNTL_1, 3);
|
||||
ALLOC_STATE( unk4008, always, 2, "unk4008", 0 );
|
||||
r300->hw.unk4008.cmd[0] = cmducs(0x4008, 1);
|
||||
ALLOC_STATE( unk4010, always, 6, "unk4010", 0 );
|
||||
r300->hw.unk4010.cmd[0] = cmducs(0x4010, 5);
|
||||
ALLOC_STATE( gb_enable, always, 2, "gb_enable", 0 );
|
||||
r300->hw.gb_enable.cmd[0] = cmducs(R300_GB_ENABLE, 1);
|
||||
ALLOC_STATE( gb_misc, always, R300_GB_MISC_CMDSIZE, "gb_misc", 0 );
|
||||
r300->hw.gb_misc.cmd[0] = cmducs(R300_GB_MSPOS0, 5);
|
||||
ALLOC_STATE( txe, always, R300_TXE_CMDSIZE, "txe", 0 );
|
||||
r300->hw.txe.cmd[R300_TXE_CMD_0] = cmducs(R300_TX_ENABLE, 1);
|
||||
ALLOC_STATE( unk4200, always, 5, "unk4200", 0 );
|
||||
@@ -380,6 +389,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
r300->hw.unk4E50.cmd[0] = cmducs(0x4E50, 9);
|
||||
ALLOC_STATE( unk4E88, always, 2, "unk4E88", 0 );
|
||||
r300->hw.unk4E88.cmd[0] = cmducs(0x4E88, 1);
|
||||
ALLOC_STATE( unk4EA0, always, 3, "unk4EA0 R350 only", 0 );
|
||||
r300->hw.unk4EA0.cmd[0] = cmducs(0x4EA0, 2);
|
||||
ALLOC_STATE( zc, always, R300_ZC_CMDSIZE, "zc", 0 );
|
||||
r300->hw.zc.cmd[R300_ZC_CMD_0] = cmducs(R300_RB3D_ZCNTL_0, 2);
|
||||
ALLOC_STATE( unk4F08, always, 2, "unk4F08", 0 );
|
||||
@@ -404,6 +415,29 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
ALLOC_STATE( vps, vpu, R300_VPS_CMDSIZE, "vps", 0 );
|
||||
r300->hw.vps.cmd[R300_VPS_CMD_0] = cmdvpu(R300_PVS_UPLOAD_POINTSIZE, 1);
|
||||
|
||||
/* Textures */
|
||||
ALLOC_STATE( tex.filter, variable, mtu+1, "tex_filter", 0 );
|
||||
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FILTER_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.unknown1, variable, mtu+1, "tex_unknown1", 0 );
|
||||
r300->hw.tex.unknown1.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK1_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.size, variable, mtu+1, "tex_size", 0 );
|
||||
r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_SIZE_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.format, variable, mtu+1, "tex_format", 0 );
|
||||
r300->hw.tex.format.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FORMAT_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.offset, variable, mtu+1, "tex_offset", 0 );
|
||||
r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_OFFSET_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.unknown4, variable, mtu+1, "tex_unknown4", 0 );
|
||||
r300->hw.tex.unknown4.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK4_0, 0);
|
||||
|
||||
ALLOC_STATE( tex.unknown5, variable, mtu+1, "tex_unknown5", 0 );
|
||||
r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK5_0, 0);
|
||||
|
||||
|
||||
/* Setup the atom linked list */
|
||||
make_empty_list(&r300->hw.atomlist);
|
||||
r300->hw.atomlist.name = "atom-list";
|
||||
@@ -411,7 +445,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vpt);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2080);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.ovf);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk20B0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vte);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2134);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2140);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[0]);
|
||||
@@ -421,9 +455,10 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk221C);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2220);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2288);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vof);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.pvs);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4008);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4010);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.gb_enable);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.gb_misc);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.txe);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4200);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4214);
|
||||
@@ -458,6 +493,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.cb);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E50);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E88);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4EA0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.zc);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F08);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F10);
|
||||
@@ -471,6 +507,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vpp);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vps);
|
||||
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.filter);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown1);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.size);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.format);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.offset);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown4);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown5);
|
||||
|
||||
r300->hw.is_dirty = GL_TRUE;
|
||||
r300->hw.all_dirty = GL_TRUE;
|
||||
|
||||
@@ -505,3 +549,206 @@ void r300DestroyCmdBuf(r300ContextPtr r300)
|
||||
}
|
||||
}
|
||||
|
||||
void r300EmitBlit(r300ContextPtr 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)
|
||||
{
|
||||
drm_radeon_cmd_header_t *cmd;
|
||||
|
||||
if (RADEON_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 =
|
||||
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(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 r300EmitWait(r300ContextPtr rmesa, GLuint flags)
|
||||
{
|
||||
if (rmesa->radeon.dri.drmMinor >= 6) {
|
||||
drm_radeon_cmd_header_t *cmd;
|
||||
|
||||
assert(!(flags & ~(RADEON_WAIT_2D | RADEON_WAIT_3D)));
|
||||
|
||||
cmd =
|
||||
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
|
||||
1 * sizeof(int),
|
||||
__FUNCTION__);
|
||||
cmd[0].i = 0;
|
||||
cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
|
||||
cmd[0].wait.flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start)
|
||||
{
|
||||
int i, a, count;
|
||||
GLuint dw;
|
||||
LOCAL_VARS
|
||||
|
||||
count=rmesa->state.aos_count;
|
||||
|
||||
a=1+(count>>1)*3+(count & 1)*2;
|
||||
start_packet3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, a-1);
|
||||
e32(count);
|
||||
for(i=0;i+1<count;i+=2){
|
||||
e32( (rmesa->state.aos[i].element_size << 0)
|
||||
|(rmesa->state.aos[i].stride << 8)
|
||||
|(rmesa->state.aos[i+1].element_size << 16)
|
||||
|(rmesa->state.aos[i+1].stride << 24)
|
||||
);
|
||||
e32(rmesa->state.aos[i].offset+start*4*rmesa->state.aos[i].stride);
|
||||
e32(rmesa->state.aos[i+1].offset+start*4*rmesa->state.aos[i+1].stride);
|
||||
}
|
||||
if(count & 1){
|
||||
e32( (rmesa->state.aos[count-1].element_size << 0)
|
||||
|(rmesa->state.aos[count-1].stride << 8)
|
||||
);
|
||||
e32(rmesa->state.aos[count-1].offset+start*4*rmesa->state.aos[count-1].stride);
|
||||
}
|
||||
|
||||
/* delay ? */
|
||||
#if 0
|
||||
e32(RADEON_CP_PACKET2);
|
||||
e32(RADEON_CP_PACKET2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline upload_vertex_shader_fragment(PREFIX int dest, struct r300_vertex_shader_fragment *vsf)
|
||||
{
|
||||
int i;
|
||||
LOCAL_VARS
|
||||
|
||||
if(vsf->length==0)return;
|
||||
|
||||
if(vsf->length & 0x3){
|
||||
fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
vsf_start_fragment(dest, vsf->length);
|
||||
for(i=0;i<vsf->length;i++)
|
||||
e32(vsf->body.d[i]);
|
||||
|
||||
}
|
||||
|
||||
void r300EmitVertexShader(r300ContextPtr rmesa)
|
||||
{
|
||||
LOCAL_VARS
|
||||
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program));
|
||||
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0]));
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0]));
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0]));
|
||||
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0]));
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1]));
|
||||
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
|
||||
upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
|
||||
|
||||
reg_start(R300_VAP_PVS_CNTL_1, 2);
|
||||
e32( (rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
|
||||
| (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
|
||||
| (rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT)
|
||||
);
|
||||
e32( (rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
|
||||
| (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT)
|
||||
);
|
||||
e32( (rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
|
||||
| (rmesa->state.vertex_shader.unknown_ptr3 << 0));
|
||||
|
||||
reg_start(R300_VAP_PVS_WAITIDLE,0);
|
||||
e32(0x00000000);
|
||||
}
|
||||
|
||||
void r300EmitPixelShader(r300ContextPtr rmesa)
|
||||
{
|
||||
int i,k;
|
||||
LOCAL_VARS
|
||||
|
||||
if(rmesa->state.pixel_shader.program.tex.length>0){
|
||||
reg_start(R300_PFS_TEXI_0, rmesa->state.pixel_shader.program.tex.length-1);
|
||||
for(i=0;i<rmesa->state.pixel_shader.program.tex.length;i++)
|
||||
e32(rmesa->state.pixel_shader.program.tex.inst[i]);
|
||||
}
|
||||
|
||||
if(rmesa->state.pixel_shader.program.alu.length>0){
|
||||
#define OUTPUT_FIELD(reg, field) \
|
||||
reg_start(reg,rmesa->state.pixel_shader.program.alu.length-1); \
|
||||
for(i=0;i<rmesa->state.pixel_shader.program.alu.length;i++) \
|
||||
e32(rmesa->state.pixel_shader.program.alu.inst[i].field);
|
||||
|
||||
OUTPUT_FIELD(R300_PFS_INSTR0_0, inst0);
|
||||
OUTPUT_FIELD(R300_PFS_INSTR1_0, inst1);
|
||||
OUTPUT_FIELD(R300_PFS_INSTR2_0, inst2);
|
||||
OUTPUT_FIELD(R300_PFS_INSTR3_0, inst3);
|
||||
#undef OUTPUT_FIELD
|
||||
}
|
||||
|
||||
reg_start(R300_PFS_NODE_0, 3);
|
||||
for(i=0;i<4;i++){
|
||||
e32( (rmesa->state.pixel_shader.program.node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT)
|
||||
| ( (i==3) ? R300_PFS_NODE_LAST_NODE : 0)
|
||||
);
|
||||
}
|
||||
|
||||
reg_start(R300_PFS_CNTL_0, 2);
|
||||
/* PFS_CNTL_0 */
|
||||
e32((rmesa->state.pixel_shader.program.active_nodes-1) | (rmesa->state.pixel_shader.program.first_node_has_tex<<3));
|
||||
/* PFS_CNTL_1 */
|
||||
e32(rmesa->state.pixel_shader.program.temp_register_count);
|
||||
/* PFS_CNTL_2 */
|
||||
e32( (rmesa->state.pixel_shader.program.alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.alu_end << R300_PFS_CNTL_ALU_END_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)
|
||||
| (rmesa->state.pixel_shader.program.tex_end << R300_PFS_CNTL_TEX_END_SHIFT)
|
||||
);
|
||||
|
||||
if(rmesa->state.pixel_shader.param_length>0){
|
||||
reg_start(R300_PFS_PARAM_0_X, rmesa->state.pixel_shader.param_length*4-1);
|
||||
for(i=0;i<rmesa->state.pixel_shader.param_length;i++){
|
||||
efloat(rmesa->state.pixel_shader.param[i].x);
|
||||
efloat(rmesa->state.pixel_shader.param[i].y);
|
||||
efloat(rmesa->state.pixel_shader.param[i].z);
|
||||
efloat(rmesa->state.pixel_shader.param[i].w);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,5 +98,18 @@ static __inline__ uint32_t* r300AllocCmdBuf(r300ContextPtr r300,
|
||||
return ptr;
|
||||
}
|
||||
|
||||
extern void r300EmitBlit(r300ContextPtr 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 r300EmitWait(r300ContextPtr rmesa, GLuint flags);
|
||||
extern void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start);
|
||||
extern void r300EmitVertexShader(r300ContextPtr rmesa);
|
||||
extern void r300EmitPixelShader(r300ContextPtr rmesa);
|
||||
|
||||
#endif /* __R300_CMDBUF_H__ */
|
||||
|
||||
@@ -57,6 +57,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "r300_state.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r300_tex.h"
|
||||
|
||||
#include "vblank.h"
|
||||
#include "utils.h"
|
||||
@@ -147,7 +148,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
struct dd_function_table functions;
|
||||
r300ContextPtr r300;
|
||||
GLcontext *ctx;
|
||||
int tcl_mode;
|
||||
int tcl_mode, i;
|
||||
|
||||
assert(glVisual);
|
||||
assert(driContextPriv);
|
||||
@@ -171,7 +172,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
_mesa_init_driver_functions(&functions);
|
||||
r300InitIoctlFuncs(&functions);
|
||||
r300InitStateFuncs(&functions);
|
||||
//r200InitTextureFuncs(&functions);
|
||||
r300InitTextureFuncs(&functions);
|
||||
|
||||
if (!radeonInitContext(&r300->radeon, &functions,
|
||||
glVisual, driContextPriv, sharedContextPrivate)) {
|
||||
@@ -180,6 +181,35 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
}
|
||||
|
||||
/* Init r300 context data */
|
||||
r300->dma.buf0_address = r300->radeon.radeonScreen->buffers->list[0].address;
|
||||
|
||||
(void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
|
||||
make_empty_list(&r300->swapped);
|
||||
|
||||
r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
|
||||
assert(r300->nr_heaps < R200_NR_TEX_HEAPS);
|
||||
for (i = 0; i < r300->nr_heaps; i++) {
|
||||
r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
|
||||
screen->
|
||||
texSize[i], 12,
|
||||
RADEON_NR_TEX_REGIONS,
|
||||
(drmTextureRegionPtr)
|
||||
r300->radeon.sarea->
|
||||
tex_list[i],
|
||||
&r300->radeon.sarea->
|
||||
tex_age[i],
|
||||
&r300->swapped,
|
||||
sizeof
|
||||
(r300TexObj),
|
||||
(destroy_texture_object_t
|
||||
*)
|
||||
r300DestroyTexObj);
|
||||
}
|
||||
r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
|
||||
"texture_depth");
|
||||
if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
|
||||
r300->texture_depth = (screen->cpp == 4) ?
|
||||
DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
|
||||
|
||||
/* 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
|
||||
@@ -239,8 +269,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
#if 0
|
||||
/* plug in a few more device driver functions */
|
||||
/* XXX these should really go right after _mesa_init_driver_functions() */
|
||||
r200InitPixelFuncs(ctx);
|
||||
r200InitSwtcl(ctx);
|
||||
r300InitPixelFuncs(ctx);
|
||||
r300InitSwtcl(ctx);
|
||||
#endif
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
|
||||
|
||||
@@ -54,9 +54,16 @@ typedef struct r300_context *r300ContextPtr;
|
||||
#include "radeon_lock.h"
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
typedef GLuint uint32_t;
|
||||
typedef GLubyte uint8_t;
|
||||
|
||||
/* We should probably change types within vertex_shader
|
||||
and pixel_shader structure later on */
|
||||
#define CARD32 GLuint
|
||||
#include "vertex_shader.h"
|
||||
#include "pixel_shader.h"
|
||||
#undef CARD32
|
||||
|
||||
static __inline__ uint32_t r300PackFloat32(float fl)
|
||||
{
|
||||
@@ -66,6 +73,114 @@ static __inline__ uint32_t r300PackFloat32(float fl)
|
||||
return u.u;
|
||||
}
|
||||
|
||||
|
||||
/************ DMA BUFFERS **************/
|
||||
|
||||
/* Need refcounting on dma buffers:
|
||||
*/
|
||||
struct r300_dma_buffer {
|
||||
int refcount; /* the number of retained regions in buf */
|
||||
drmBufPtr buf;
|
||||
};
|
||||
|
||||
#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
|
||||
(rvb)->address - rmesa->dma.buf0_address + \
|
||||
(rvb)->start)
|
||||
|
||||
/* A retained region, eg vertices for indexed vertices.
|
||||
*/
|
||||
struct r300_dma_region {
|
||||
struct r300_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 r300_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 r300_dma_region current;
|
||||
|
||||
void (*flush) (r300ContextPtr);
|
||||
|
||||
char *buf0_address; /* start of buf[0], for index calcs */
|
||||
GLuint nr_released_bufs; /* flush after so many buffers released */
|
||||
};
|
||||
|
||||
/* Texture related */
|
||||
|
||||
#define TEX_0 0x1
|
||||
#define TEX_1 0x2
|
||||
#define TEX_2 0x4
|
||||
#define TEX_3 0x8
|
||||
#define TEX_4 0x10
|
||||
#define TEX_5 0x20
|
||||
#define TEX_6 0x40
|
||||
#define TEX_7 0x80
|
||||
#define TEX_ALL 0xff
|
||||
|
||||
typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr;
|
||||
|
||||
/* Texture object in locally shared texture space.
|
||||
*/
|
||||
struct r300_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. */
|
||||
|
||||
drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
|
||||
/* Six, for the cube faces */
|
||||
|
||||
|
||||
/* hardware register values */
|
||||
/* Note that R200 has 8 registers per texture and R300 only 7 */
|
||||
GLuint filter;
|
||||
GLuint pitch; /* one of the unknown registers.. unknown 1 ?*/
|
||||
GLuint size; /* npot only */
|
||||
GLuint format;
|
||||
GLuint offset; /* Image location in texmem.
|
||||
All cube faces follow. */
|
||||
GLuint unknown4;
|
||||
GLuint unknown5;
|
||||
/* end hardware registers */
|
||||
|
||||
/* registers computed by r200 code - keep them here to
|
||||
compare against what is actually written.
|
||||
|
||||
to be removed later.. */
|
||||
GLuint pp_border_color;
|
||||
GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */
|
||||
GLuint format_x;
|
||||
|
||||
|
||||
GLboolean border_fallback;
|
||||
};
|
||||
|
||||
struct r300_texture_env_state {
|
||||
r300TexObjPtr texobj;
|
||||
GLenum format;
|
||||
GLenum envMode;
|
||||
};
|
||||
|
||||
#define R300_MAX_TEXTURE_UNITS 8
|
||||
|
||||
struct r300_texture_state {
|
||||
struct r300_texture_env_state unit[R300_MAX_TEXTURE_UNITS];
|
||||
int tc_count; /* number of incoming texture coordinates from VAP */
|
||||
};
|
||||
|
||||
/**
|
||||
* A block of hardware state.
|
||||
*
|
||||
@@ -115,12 +230,26 @@ struct r300_state_atom {
|
||||
#define R300_VIC_CNTL_1 2
|
||||
#define R300_VIC_CMDSIZE 3
|
||||
|
||||
#define R300_VOF_CMD_0 0
|
||||
#define R300_VOF_CNTL_0 1
|
||||
#define R300_VOF_CNTL_1 2
|
||||
#define R300_VOF_CMDSIZE 3
|
||||
|
||||
|
||||
#define R300_PVS_CMD_0 0
|
||||
#define R300_PVS_CNTL_1 1
|
||||
#define R300_PVS_CNTL_2 2
|
||||
#define R300_PVS_CNTL_3 3
|
||||
#define R300_PVS_CMDSIZE 4
|
||||
|
||||
#define R300_GB_MISC_CMD_0 0
|
||||
#define R300_GB_MISC_MSPOS_0 1
|
||||
#define R300_GB_MISC_MSPOS_1 2
|
||||
#define R300_GB_MISC_TILE_CONFIG 3
|
||||
#define R300_GB_MISC_SELECT 4
|
||||
#define R300_GB_MISC_AA_CONFIG 5
|
||||
#define R300_GB_MISC_CMDSIZE 6
|
||||
|
||||
#define R300_TXE_CMD_0 0
|
||||
#define R300_TXE_ENABLE 1
|
||||
#define R300_TXE_CMDSIZE 2
|
||||
@@ -219,6 +348,13 @@ struct r300_state_atom {
|
||||
#define R300_VPS_ZERO_3 4
|
||||
#define R300_VPS_CMDSIZE 5
|
||||
|
||||
/* the layout is common for all fields inside tex */
|
||||
#define R300_TEX_CMD_0 0
|
||||
#define R300_TEX_VALUE_0 1
|
||||
/* We don't really use this, instead specify mtu+1 dynamically
|
||||
#define R300_TEX_CMDSIZE (MAX_TEXTURE_UNITS+1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cache for hardware register state.
|
||||
*/
|
||||
@@ -232,7 +368,7 @@ struct r300_hw_state {
|
||||
struct r300_state_atom vpt; /* viewport (1D98) */
|
||||
struct r300_state_atom unk2080; /* (2080) */
|
||||
struct r300_state_atom ovf; /* output vertex format (2090) */
|
||||
struct r300_state_atom unk20B0; /* (20B0) */
|
||||
struct r300_state_atom vte; /* (20B0) */
|
||||
struct r300_state_atom unk2134; /* (2134) */
|
||||
struct r300_state_atom unk2140; /* (2140) */
|
||||
struct r300_state_atom vir[2]; /* vap input route (2150/21E0) */
|
||||
@@ -242,9 +378,9 @@ struct r300_hw_state {
|
||||
struct r300_state_atom unk2220; /* (2220) */
|
||||
struct r300_state_atom unk2288; /* (2288) */
|
||||
struct r300_state_atom pvs; /* pvs_cntl (22D0) */
|
||||
struct r300_state_atom unk4008; /* (4008) */
|
||||
struct r300_state_atom unk4010; /* (4010) */
|
||||
struct r300_state_atom txe; /* tex enable (4104) */
|
||||
struct r300_state_atom vof; /* VAP output format register 0x4000 */
|
||||
struct r300_state_atom gb_enable; /* (4008) */
|
||||
struct r300_state_atom gb_misc; /* Multisampling position shifts ? (4010) */
|
||||
struct r300_state_atom unk4200; /* (4200) */
|
||||
struct r300_state_atom unk4214; /* (4214) */
|
||||
struct r300_state_atom ps; /* pointsize (421C) */
|
||||
@@ -275,6 +411,7 @@ struct r300_hw_state {
|
||||
struct r300_state_atom cb; /* colorbuffer (4E28) */
|
||||
struct r300_state_atom unk4E50; /* (4E50) */
|
||||
struct r300_state_atom unk4E88; /* (4E88) */
|
||||
struct r300_state_atom unk4EA0; /* (4E88) I saw it only written on RV350 hardware.. */
|
||||
struct r300_state_atom zc; /* z control (4F00) */
|
||||
struct r300_state_atom unk4F08; /* (4F08) */
|
||||
struct r300_state_atom unk4F10; /* (4F10) */
|
||||
@@ -287,6 +424,22 @@ struct r300_hw_state {
|
||||
struct r300_state_atom vpi; /* vp instructions */
|
||||
struct r300_state_atom vpp; /* vp parameters */
|
||||
struct r300_state_atom vps; /* vertex point size (?) */
|
||||
|
||||
/* 8 texture units */
|
||||
/* the state is grouped by function and not by
|
||||
texture unit. This makes single unit updates
|
||||
really awkward - we are much better off
|
||||
updating the whole thing at once */
|
||||
struct {
|
||||
struct r300_state_atom filter;
|
||||
struct r300_state_atom unknown1;
|
||||
struct r300_state_atom size;
|
||||
struct r300_state_atom format;
|
||||
struct r300_state_atom offset;
|
||||
struct r300_state_atom unknown4;
|
||||
struct r300_state_atom unknown5;
|
||||
} tex;
|
||||
struct r300_state_atom txe; /* tex enable (4104) */
|
||||
};
|
||||
|
||||
|
||||
@@ -308,7 +461,156 @@ struct r300_cmdbuf {
|
||||
/**
|
||||
* State cache
|
||||
*/
|
||||
|
||||
struct r300_depthbuffer_state {
|
||||
GLfloat scale;
|
||||
};
|
||||
|
||||
struct r300_vap_reg_state {
|
||||
/* input register assigments */
|
||||
int i_coords;
|
||||
int i_color[2];
|
||||
int i_tex[R300_MAX_TEXTURE_UNITS];
|
||||
};
|
||||
|
||||
/* Vertex shader state */
|
||||
|
||||
/* 64 appears to be the maximum */
|
||||
#define VSF_MAX_FRAGMENT_LENGTH 64
|
||||
|
||||
|
||||
struct r300_vertex_shader_fragment {
|
||||
int length;
|
||||
union {
|
||||
GLuint d[VSF_MAX_FRAGMENT_LENGTH];
|
||||
float f[VSF_MAX_FRAGMENT_LENGTH];
|
||||
VERTEX_SHADER_INSTRUCTION i[VSF_MAX_FRAGMENT_LENGTH/4];
|
||||
} body;
|
||||
};
|
||||
|
||||
#define VSF_DEST_PROGRAM 0x0
|
||||
#define VSF_DEST_MATRIX0 0x200
|
||||
#define VSF_DEST_MATRIX1 0x204
|
||||
#define VSF_DEST_MATRIX2 0x208
|
||||
#define VSF_DEST_VECTOR0 0x20c
|
||||
#define VSF_DEST_VECTOR1 0x20d
|
||||
#define VSF_DEST_UNKNOWN1 0x400
|
||||
#define VSF_DEST_UNKNOWN2 0x406
|
||||
|
||||
struct r300_vertex_shader_state {
|
||||
struct r300_vertex_shader_fragment program;
|
||||
|
||||
/* a bit of a waste - each uses only a subset of allocated space..
|
||||
but easier to program */
|
||||
struct r300_vertex_shader_fragment matrix[3];
|
||||
struct r300_vertex_shader_fragment vector[2];
|
||||
|
||||
struct r300_vertex_shader_fragment unknown1;
|
||||
struct r300_vertex_shader_fragment unknown2;
|
||||
|
||||
int program_start;
|
||||
int unknown_ptr1; /* pointer within program space */
|
||||
int program_end;
|
||||
|
||||
int param_offset;
|
||||
int param_count;
|
||||
|
||||
int unknown_ptr2; /* pointer within program space */
|
||||
int unknown_ptr3; /* pointer within program space */
|
||||
};
|
||||
|
||||
/* 64 appears to be the maximum */
|
||||
#define PSF_MAX_PROGRAM_LENGTH 64
|
||||
|
||||
struct r300_pixel_shader_program {
|
||||
struct {
|
||||
int length;
|
||||
GLuint inst[PSF_MAX_PROGRAM_LENGTH];
|
||||
} tex;
|
||||
|
||||
/* ALU intructions (logic and integer) */
|
||||
struct {
|
||||
int length;
|
||||
struct {
|
||||
GLuint inst0;
|
||||
GLuint inst1;
|
||||
GLuint inst2;
|
||||
GLuint inst3;
|
||||
} inst[PSF_MAX_PROGRAM_LENGTH];
|
||||
} alu;
|
||||
|
||||
/* node information */
|
||||
/* nodes are used to synchronize ALU and TEX streams */
|
||||
/* There could be up to 4 nodes each consisting of
|
||||
a number of TEX instructions followed by some ALU
|
||||
instructions */
|
||||
/* the last node of a program should always be node3 */
|
||||
struct {
|
||||
int tex_offset;
|
||||
int tex_end;
|
||||
int alu_offset;
|
||||
int alu_end;
|
||||
} node[4];
|
||||
|
||||
int active_nodes; /* must be between 1 and 4, inclusive */
|
||||
int first_node_has_tex; /* other nodes always have it */
|
||||
|
||||
int temp_register_count; /* magic value goes into PFS_CNTL_1 */
|
||||
|
||||
/* entire program */
|
||||
int tex_offset;
|
||||
int tex_end;
|
||||
int alu_offset;
|
||||
int alu_end;
|
||||
|
||||
};
|
||||
|
||||
#define MAX_PIXEL_SHADER_PARAMS 32
|
||||
struct r300_pixel_shader_state {
|
||||
struct r300_pixel_shader_program program;
|
||||
|
||||
/* parameters */
|
||||
int param_length; /* to limit the number of unnecessary writes */
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
} param[MAX_PIXEL_SHADER_PARAMS];
|
||||
};
|
||||
|
||||
/* 8 is somewhat bogus... it is probably something like 24 */
|
||||
#define R300_MAX_AOS_ARRAYS 8
|
||||
|
||||
struct r300_aos_rec {
|
||||
GLuint offset;
|
||||
int element_size; /* in dwords */
|
||||
int stride; /* distance between elements, in dwords */
|
||||
|
||||
#define AOS_FORMAT_FLOAT 1
|
||||
#define AOS_FORMAT_UBYTE 2
|
||||
#define AOS_FORMAT_FLOAT_COLOR 3
|
||||
int format;
|
||||
|
||||
int ncomponents; /* number of components - between 1 and 4, inclusive */
|
||||
|
||||
/* just guesses */
|
||||
#define REG_COORDS 0
|
||||
#define REG_COLOR0 1
|
||||
#define REG_TEX0 2
|
||||
int reg; /* which register they are assigned to. */
|
||||
|
||||
};
|
||||
|
||||
struct r300_state {
|
||||
struct r300_depthbuffer_state depth;
|
||||
struct r300_texture_state texture;
|
||||
struct r300_vap_reg_state vap_reg;
|
||||
struct r300_vertex_shader_state vertex_shader;
|
||||
struct r300_pixel_shader_state pixel_shader;
|
||||
struct r300_aos_rec aos[R300_MAX_AOS_ARRAYS];
|
||||
int aos_count;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -321,6 +623,43 @@ struct r300_context {
|
||||
struct r300_hw_state hw;
|
||||
struct r300_cmdbuf cmdbuf;
|
||||
struct r300_state state;
|
||||
|
||||
/* Vertex buffers */
|
||||
int elt_count; /* size of the buffer for vertices */
|
||||
int attrib_count; /* size of the buffer for vertex attributes.. Somehow it can be different ? */
|
||||
|
||||
|
||||
/* Vertex buffers
|
||||
*/
|
||||
#if 0 /* we'll need it later, but not now */
|
||||
struct r300_ioctl ioctl;
|
||||
#endif
|
||||
struct r300_dma dma;
|
||||
GLboolean save_on_next_unlock;
|
||||
|
||||
/* Texture object bookkeeping
|
||||
*/
|
||||
unsigned nr_heaps;
|
||||
driTexHeap *texture_heaps[R200_NR_TEX_HEAPS];
|
||||
driTextureObject swapped;
|
||||
int texture_depth;
|
||||
float initialMaxAnisotropy;
|
||||
|
||||
/* Clientdata textures;
|
||||
*/
|
||||
GLuint prefer_gart_client_texturing;
|
||||
|
||||
/* TCL stuff
|
||||
*/
|
||||
GLmatrix TexGenMatrix[R300_MAX_TEXTURE_UNITS];
|
||||
GLboolean recheck_texgen[R300_MAX_TEXTURE_UNITS];
|
||||
GLboolean TexGenNeedNormals[R300_MAX_TEXTURE_UNITS];
|
||||
GLuint TexMatEnabled;
|
||||
GLuint TexMatCompSel;
|
||||
GLuint TexGenEnabled;
|
||||
GLuint TexGenInputs;
|
||||
GLuint TexGenCompSel;
|
||||
GLmatrix tmpmat;
|
||||
};
|
||||
|
||||
#define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx))
|
||||
|
||||
205
src/mesa/drivers/dri/r300/r300_emit.h
Normal file
205
src/mesa/drivers/dri/r300/r300_emit.h
Normal file
@@ -0,0 +1,205 @@
|
||||
#ifndef __EMIT_H__
|
||||
#define __EMIT_H__
|
||||
#include "glheader.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
|
||||
/* convenience macros */
|
||||
#define RADEON_CP_PACKET0 0x00000000
|
||||
#define RADEON_CP_PACKET1 0x40000000
|
||||
#define RADEON_CP_PACKET2 0x80000000
|
||||
#define RADEON_CP_PACKET3 0xC0000000
|
||||
|
||||
#define RADEON_CP_PACKET3_NOP 0xC0001000
|
||||
#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900
|
||||
#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00
|
||||
#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00
|
||||
#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300
|
||||
#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400
|
||||
#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00
|
||||
#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_VBUF_2 0xC0003400
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500
|
||||
#define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600
|
||||
#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
|
||||
#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100
|
||||
#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200
|
||||
#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300
|
||||
#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400
|
||||
#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500
|
||||
#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800
|
||||
#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00
|
||||
#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
|
||||
#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00
|
||||
#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003202
|
||||
#define RADEON_CP_PACKET3_3D_CLEAR_CMASK 0xC0003802
|
||||
#define RADEON_CP_PACKET3_3D_CLEAR_HIZ 0xC0003702
|
||||
|
||||
#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
|
||||
|
||||
/* Glue to R300 Mesa driver */
|
||||
#define LOCAL_VARS int cmd_reserved=0;\
|
||||
int cmd_written=0; \
|
||||
drm_radeon_cmd_header_t *cmd=NULL;
|
||||
|
||||
#define PREFIX_VOID r300ContextPtr rmesa
|
||||
|
||||
#define PREFIX PREFIX_VOID ,
|
||||
|
||||
#define PASS_PREFIX_VOID rmesa
|
||||
#define PASS_PREFIX rmesa ,
|
||||
|
||||
typedef GLuint CARD32;
|
||||
|
||||
/* This files defines functions for accessing R300 hardware.
|
||||
It needs to be customized to whatever code r300_lib.c is used
|
||||
in */
|
||||
|
||||
void static inline check_space(int dwords)
|
||||
{
|
||||
}
|
||||
|
||||
static __inline__ uint32_t cmducs(int reg, int count)
|
||||
{
|
||||
drm_r300_cmd_header_t cmd;
|
||||
|
||||
cmd.unchecked_state.cmd_type = R300_CMD_UNCHECKED_STATE;
|
||||
cmd.unchecked_state.count = count;
|
||||
cmd.unchecked_state.reghi = ((unsigned int)reg & 0xFF00) >> 8;
|
||||
cmd.unchecked_state.reglo = ((unsigned int)reg & 0x00FF);
|
||||
|
||||
return cmd.u;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t cmdvpu(int addr, int count)
|
||||
{
|
||||
drm_r300_cmd_header_t cmd;
|
||||
|
||||
cmd.vpu.cmd_type = R300_CMD_VPU;
|
||||
cmd.vpu.count = count;
|
||||
cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
|
||||
cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
|
||||
|
||||
return cmd.u;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t cmdpacket3(int packet)
|
||||
{
|
||||
drm_r300_cmd_header_t cmd;
|
||||
|
||||
cmd.packet3.cmd_type = R300_CMD_PACKET3;
|
||||
cmd.packet3.packet = packet;
|
||||
|
||||
return cmd.u;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t cmdcpdelay(unsigned short count)
|
||||
{
|
||||
drm_r300_cmd_header_t cmd;
|
||||
|
||||
cmd.delay.cmd_type = R300_CMD_CP_DELAY;
|
||||
cmd.delay.count = count;
|
||||
|
||||
return cmd.u;
|
||||
}
|
||||
|
||||
/* Prepare to write a register value to register at address reg.
|
||||
If num_extra > 0 then the following extra values are written
|
||||
to registers with address +4, +8 and so on.. */
|
||||
#define reg_start(reg, num_extra) \
|
||||
{ \
|
||||
int _n; \
|
||||
_n=(num_extra); \
|
||||
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
|
||||
(_n+2), \
|
||||
__FUNCTION__); \
|
||||
cmd_reserved=_n+2; \
|
||||
cmd_written=1; \
|
||||
cmd[0].i=cmducs((reg), _n+1); \
|
||||
}
|
||||
|
||||
/* Prepare to write a register value to register at address reg.
|
||||
If num_extra > 0 then the following extra values are written
|
||||
into the same register. */
|
||||
/* It is here to permit r300_lib to compile and link anyway, but
|
||||
complain if actually called */
|
||||
#define reg_start_pump(reg, num_extra) \
|
||||
{ \
|
||||
fprintf(stderr, "I am not defined.. Error ! in %s::%s at line %d\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__); \
|
||||
exit(-1); \
|
||||
}
|
||||
|
||||
/* Emit CARD32 freestyle*/
|
||||
#define e32(dword) { \
|
||||
if(cmd_written<cmd_reserved){\
|
||||
cmd[cmd_written].i=(dword); \
|
||||
cmd_written++; \
|
||||
} else { \
|
||||
fprintf(stderr, "e32 but no previous packet declaration.. Aborting! in %s::%s at line %d\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__); \
|
||||
exit(-1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define efloat(f) e32(r300PackFloat32(f))
|
||||
|
||||
#define vsf_start_fragment(dest, length) \
|
||||
{ \
|
||||
int _n; \
|
||||
_n=(length); \
|
||||
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
|
||||
(_n+1), \
|
||||
__FUNCTION__); \
|
||||
cmd_reserved=_n+2; \
|
||||
cmd_written=1; \
|
||||
cmd[0].i=cmdvpu((dest), _n/4); \
|
||||
}
|
||||
|
||||
#define start_packet3(packet, count) \
|
||||
{ \
|
||||
int _n; \
|
||||
CARD32 _p; \
|
||||
_n=(count); \
|
||||
_p=(packet); \
|
||||
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
|
||||
(_n+3), \
|
||||
__FUNCTION__); \
|
||||
cmd_reserved=_n+3; \
|
||||
cmd_written=2; \
|
||||
if(_n>0x3fff) {\
|
||||
fprintf(stderr,"Too big packet3 %08x: cannot store %d dwords\n", \
|
||||
_p, _n); \
|
||||
exit(-1); \
|
||||
} \
|
||||
cmd[0].i=cmdpacket3(R300_CMD_PACKET3_RAW); \
|
||||
cmd[1].i=_p | ((_n & 0x3fff)<<16); \
|
||||
}
|
||||
|
||||
/* must be sent to switch to 2d commands */
|
||||
void static inline end_3d(PREFIX_VOID)
|
||||
{
|
||||
LOCAL_VARS
|
||||
|
||||
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
|
||||
0, \
|
||||
__FUNCTION__); \
|
||||
|
||||
cmd[0].header.cmd_type=R300_CMD_END3D;
|
||||
}
|
||||
|
||||
void static inline cp_delay(PREFIX unsigned short count)
|
||||
{
|
||||
LOCAL_VARS
|
||||
|
||||
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
|
||||
0, \
|
||||
__FUNCTION__); \
|
||||
|
||||
cmd[0].i=cmdcpdelay(count);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -81,6 +81,26 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
||||
|
||||
cboffset += r300->radeon.radeonScreen->fbLocation;
|
||||
|
||||
R300_STATECHANGE(r300, vir[0]);
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
|
||||
r300->hw.vir[0].cmd[1] = 0x21030003;
|
||||
|
||||
R300_STATECHANGE(r300, vir[1]);
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
|
||||
r300->hw.vir[1].cmd[1] = 0xF688F688;
|
||||
|
||||
R300_STATECHANGE(r300, vic);
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
|
||||
|
||||
R300_STATECHANGE(r300, vof);
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
|
||||
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
|
||||
|
||||
R300_STATECHANGE(r300, txe);
|
||||
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
|
||||
|
||||
R300_STATECHANGE(r300, vpt);
|
||||
r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0);
|
||||
r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x);
|
||||
@@ -89,6 +109,13 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
||||
r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0);
|
||||
r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.0);
|
||||
|
||||
R300_STATECHANGE(r300, at);
|
||||
r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
|
||||
|
||||
R300_STATECHANGE(r300, bld);
|
||||
r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
|
||||
r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
|
||||
|
||||
R300_STATECHANGE(r300, cb);
|
||||
r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset;
|
||||
r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch | R300_COLOR_UNKNOWN_22_23;
|
||||
@@ -105,6 +132,11 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
|
||||
|
||||
R300_STATECHANGE(r300, rc);
|
||||
/* The second constant is needed to get glxgears display anything .. */
|
||||
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
|
||||
r300->hw.rc.cmd[2] = 0;
|
||||
|
||||
R300_STATECHANGE(r300, rr);
|
||||
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
|
||||
r300->hw.rr.cmd[1] = 0x00004000;
|
||||
@@ -282,6 +314,195 @@ void r300Flush(GLcontext * ctx)
|
||||
r300FlushCmdBuf(r300, __FUNCTION__);
|
||||
}
|
||||
|
||||
void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
|
||||
{
|
||||
struct r200_dma_buffer *dmabuf;
|
||||
int fd = rmesa->radeon.dri.fd;
|
||||
int index = 0;
|
||||
int size = 0;
|
||||
drmDMAReq dma;
|
||||
int ret;
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->dma.flush) {
|
||||
rmesa->dma.flush(rmesa);
|
||||
}
|
||||
|
||||
if (rmesa->dma.current.buf)
|
||||
r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
|
||||
|
||||
if (rmesa->dma.nr_released_bufs > 4)
|
||||
r300FlushCmdBuf(rmesa, __FUNCTION__);
|
||||
|
||||
dma.context = rmesa->radeon.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->radeon); /* 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->radeon.do_usleeps) {
|
||||
UNLOCK_HARDWARE(&rmesa->radeon);
|
||||
DO_USLEEP(1);
|
||||
LOCK_HARDWARE(&rmesa->radeon);
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE(&rmesa->radeon);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "Allocated buffer %d\n", index);
|
||||
|
||||
dmabuf = CALLOC_STRUCT(r300_dma_buffer);
|
||||
dmabuf->buf = &rmesa->radeon.radeonScreen->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 r300ReleaseDmaRegion(r300ContextPtr rmesa,
|
||||
struct r300_dma_region *region, const char *caller)
|
||||
{
|
||||
if (RADEON_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) {
|
||||
drm_radeon_cmd_header_t *cmd;
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
||||
fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
|
||||
region->buf->buf->idx);
|
||||
|
||||
cmd =
|
||||
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(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 r300AllocDmaRegion(r300ContextPtr rmesa,
|
||||
struct r300_dma_region *region,
|
||||
int bytes, int alignment)
|
||||
{
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
|
||||
|
||||
if (rmesa->dma.flush)
|
||||
rmesa->dma.flush(rmesa);
|
||||
|
||||
if (region->buf)
|
||||
r300ReleaseDmaRegion(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)
|
||||
r300RefillCurrentDmaRegion(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);
|
||||
}
|
||||
|
||||
/* Called via glXGetMemoryOffsetMESA() */
|
||||
GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
|
||||
const GLvoid * pointer)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r300ContextPtr rmesa;
|
||||
GLuint card_offset;
|
||||
|
||||
if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
|
||||
fprintf(stderr, "%s: no context\n", __FUNCTION__);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
if (!r300IsGartMemory(rmesa, pointer, 0))
|
||||
return ~0;
|
||||
|
||||
if (rmesa->radeon.dri.drmMinor < 6)
|
||||
return ~0;
|
||||
|
||||
card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
|
||||
|
||||
return card_offset - rmesa->radeon.radeonScreen->gart_base;
|
||||
}
|
||||
|
||||
GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
|
||||
GLint size)
|
||||
{
|
||||
int offset =
|
||||
(char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
|
||||
int valid = (size >= 0 && offset >= 0
|
||||
&& offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
|
||||
valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
|
||||
{
|
||||
int offset =
|
||||
(char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
|
||||
|
||||
fprintf(stderr, "offset=%08x\n", offset);
|
||||
|
||||
if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
|
||||
return ~0;
|
||||
else
|
||||
return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
|
||||
}
|
||||
|
||||
void r300InitIoctlFuncs(struct dd_function_table *functions)
|
||||
{
|
||||
functions->Clear = r300Clear;
|
||||
|
||||
@@ -36,7 +36,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#ifndef __R300_IOCTL_H__
|
||||
#define __R300_IOCTL_H__
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "radeon_drm.h"
|
||||
|
||||
extern GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
|
||||
const GLvoid * pointer);
|
||||
|
||||
extern GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
|
||||
GLint size);
|
||||
|
||||
extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa,
|
||||
const GLvoid * pointer);
|
||||
|
||||
extern void r300Flush(GLcontext * ctx);
|
||||
|
||||
extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa);
|
||||
extern void r300ReleaseDmaRegion(r300ContextPtr rmesa,
|
||||
struct r300_dma_region *region, const char *caller);
|
||||
extern void r300AllocDmaRegion(r300ContextPtr rmesa,
|
||||
struct r300_dma_region *region,
|
||||
int bytes, int alignment);
|
||||
|
||||
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
|
||||
|
||||
#endif /* __R300_IOCTL_H__ */
|
||||
|
||||
@@ -17,14 +17,47 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
#define R300_SE_VPORT_ZOFFSET 0x1DAC
|
||||
|
||||
|
||||
// BEGIN: Wild guesses
|
||||
/* This register is written directly and also starts data section in many 3d CP_PACKET3's */
|
||||
#define R300_VAP_VF_CNTL 0x2084
|
||||
|
||||
# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0
|
||||
# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0)
|
||||
# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0)
|
||||
|
||||
# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4
|
||||
/* State based - direct writes to registers trigger vertex generation */
|
||||
# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4)
|
||||
# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4)
|
||||
# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4)
|
||||
# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4)
|
||||
|
||||
/* I don't think I saw these three used.. */
|
||||
# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6
|
||||
# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9
|
||||
# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10
|
||||
|
||||
/* index size - when not set the indices are assumed to be 16 bit */
|
||||
# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
|
||||
/* number of vertices */
|
||||
# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
|
||||
|
||||
/* BEGIN: Wild guesses */
|
||||
#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) // GUESS
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) // GUESS
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) // GUESS
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) // GUESS
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
|
||||
|
||||
#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
|
||||
@@ -35,11 +68,24 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
|
||||
// END
|
||||
/* END */
|
||||
|
||||
// BEGIN: Vertex data assembly - lots of uncertainties
|
||||
#define R300_SE_VTE_CNTL 0x20b0
|
||||
# define R300_VPORT_X_SCALE_ENA 0x00000001
|
||||
# define R300_VPORT_X_OFFSET_ENA 0x00000002
|
||||
# define R300_VPORT_Y_SCALE_ENA 0x00000004
|
||||
# define R300_VPORT_Y_OFFSET_ENA 0x00000008
|
||||
# define R300_VPORT_Z_SCALE_ENA 0x00000010
|
||||
# define R300_VPORT_Z_OFFSET_ENA 0x00000020
|
||||
# define R300_VTX_XY_FMT 0x00000100
|
||||
# define R300_VTX_Z_FMT 0x00000200
|
||||
# define R300_VTX_W0_FMT 0x00000400
|
||||
# define R300_VTX_W0_NORMALIZE 0x00000800
|
||||
# define R300_VTX_ST_DENORMALIZED 0x00001000
|
||||
|
||||
/* BEGIN: Vertex data assembly - lots of uncertainties */
|
||||
/* gap */
|
||||
// Where do we get our vertex data?
|
||||
/* Where do we get our vertex data?
|
||||
//
|
||||
// Vertex data either comes either from immediate mode registers or from
|
||||
// vertex arrays.
|
||||
@@ -60,29 +106,30 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// The corresponding input is routed into the register with the given index.
|
||||
// The list is ended by a word with INPUT_ROUTE_END set.
|
||||
//
|
||||
// Always set COMPONENTS_4 in immediate mode.
|
||||
// Always set COMPONENTS_4 in immediate mode. */
|
||||
|
||||
#define R300_VAP_INPUT_ROUTE_0_0 0x2150
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) // GUESS
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) // GUESS
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
|
||||
# define R300_VAP_INPUT_ROUTE_END (1 << 13)
|
||||
# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) // GUESS
|
||||
# define R300_INPUT_ROUTE_FLOAT (1 << 14) // GUESS
|
||||
# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) // GUESS
|
||||
# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) // GUESS
|
||||
# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
|
||||
#define R300_VAP_INPUT_ROUTE_0_1 0x2154
|
||||
#define R300_VAP_INPUT_ROUTE_0_2 0x2158
|
||||
#define R300_VAP_INPUT_ROUTE_0_3 0x215C
|
||||
|
||||
/* gap */
|
||||
// Notes:
|
||||
/* Notes:
|
||||
// - always set up to produce at least two attributes:
|
||||
// if vertex program uses only position, fglrx will set normal, too
|
||||
// - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal
|
||||
// - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal */
|
||||
#define R300_VAP_INPUT_CNTL_0 0x2180
|
||||
# define R300_INPUT_CNTL_0_COLOR 0x00000001
|
||||
#define R300_VAP_INPUT_CNTL_1 0x2184
|
||||
@@ -91,20 +138,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_INPUT_CNTL_COLOR 0x00000004
|
||||
# define R300_INPUT_CNTL_TC0 0x00000400
|
||||
# define R300_INPUT_CNTL_TC1 0x00000800
|
||||
# define R300_INPUT_CNTL_TC2 0x00001000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC3 0x00002000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC4 0x00004000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC5 0x00008000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC6 0x00010000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC7 0x00020000 // GUESS
|
||||
# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
|
||||
|
||||
/* gap */
|
||||
// Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
|
||||
/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
|
||||
// are set to a swizzling bit pattern, other words are 0.
|
||||
//
|
||||
// In immediate mode, the pattern is always set to xyzw. In vertex array
|
||||
// mode, the swizzling pattern is e.g. used to set zw components in texture
|
||||
// coordinates with only tweo components.
|
||||
// coordinates with only tweo components. */
|
||||
#define R300_VAP_INPUT_ROUTE_1_0 0x21E0
|
||||
# define R300_INPUT_ROUTE_SELECT_X 0
|
||||
# define R300_INPUT_ROUTE_SELECT_Y 1
|
||||
@@ -122,10 +169,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
#define R300_VAP_INPUT_ROUTE_1_2 0x21E8
|
||||
#define R300_VAP_INPUT_ROUTE_1_3 0x21EC
|
||||
|
||||
// END
|
||||
/* END */
|
||||
|
||||
/* gap */
|
||||
// BEGIN: Upload vertex program and data
|
||||
/* BEGIN: Upload vertex program and data
|
||||
// The programmable vertex shader unit has a memory bank of unknown size
|
||||
// that can be written to in 16 byte units by writing the address into
|
||||
// UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs).
|
||||
@@ -147,37 +194,37 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// as there is also the R300_RE_POINTSIZE register.
|
||||
//
|
||||
// Multiple vertex programs and parameter sets can be loaded at once,
|
||||
// which could explain the size discrepancy.
|
||||
// which could explain the size discrepancy. */
|
||||
#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200
|
||||
# define R300_PVS_UPLOAD_PROGRAM 0x00000000
|
||||
# define R300_PVS_UPLOAD_PARAMETERS 0x00000200
|
||||
# define R300_PVS_UPLOAD_POINTSIZE 0x00000406
|
||||
/* gap */
|
||||
#define R300_VAP_PVS_UPLOAD_DATA 0x2208
|
||||
// END
|
||||
/* END */
|
||||
|
||||
/* gap */
|
||||
// I do not know the purpose of this register. However, I do know that
|
||||
/* I do not know the purpose of this register. However, I do know that
|
||||
// it is set to 221C_CLEAR for clear operations and to 221C_NORMAL
|
||||
// for normal rendering.
|
||||
// for normal rendering. */
|
||||
#define R300_VAP_UNKNOWN_221C 0x221C
|
||||
# define R300_221C_NORMAL 0x00000000
|
||||
# define R300_221C_CLEAR 0x0001C000
|
||||
|
||||
/* gap */
|
||||
// Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
|
||||
/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
|
||||
// rendering commands and overwriting vertex program parameters.
|
||||
// Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
|
||||
// avoids bugs caused by still running shaders reading bad data from memory.
|
||||
#define R300_VAP_PVS_WAITIDLE 0x2284 // GUESS
|
||||
// avoids bugs caused by still running shaders reading bad data from memory. */
|
||||
#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
|
||||
|
||||
// Absolutely no clue what this register is about.
|
||||
/* Absolutely no clue what this register is about. */
|
||||
#define R300_VAP_UNKNOWN_2288 0x2288
|
||||
# define R300_2288_R300 0x00750000 // -- nh
|
||||
# define R300_2288_RV350 0x0000FFFF // -- Vladimir
|
||||
# define R300_2288_R300 0x00750000 /* -- nh */
|
||||
# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
|
||||
|
||||
/* gap */
|
||||
// Addresses are relative to the vertex program instruction area of the
|
||||
/* Addresses are relative to the vertex program instruction area of the
|
||||
// memory bank. PROGRAM_END points to the last instruction of the active
|
||||
// program
|
||||
//
|
||||
@@ -185,58 +232,166 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// experiments so far have shown that both *must* point to an instruction
|
||||
// inside the vertex program, otherwise the GPU locks up.
|
||||
// fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
|
||||
// CNTL_1_UNKNOWN somewhere in the middle, but the criteria are not clear.
|
||||
// CNTL_1_UNKNOWN somewhere in the middle, but the criteria are not clear. */
|
||||
#define R300_VAP_PVS_CNTL_1 0x22D0
|
||||
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
|
||||
# define R300_PVS_CNTL_1_UNKNOWN_SHIFT 10
|
||||
# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20
|
||||
// Addresses are relative the the vertex program parameters area.
|
||||
/* Addresses are relative the the vertex program parameters area. */
|
||||
#define R300_VAP_PVS_CNTL_2 0x22D4
|
||||
# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
|
||||
# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16
|
||||
#define R300_VAP_PVS_CNTL_3 0x22D8
|
||||
# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10
|
||||
# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0
|
||||
|
||||
// The entire range from 0x2300 to 0x2AC inclusive seems to be used for
|
||||
// immediate vertices
|
||||
/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for
|
||||
// immediate vertices */
|
||||
#define R300_VAP_VTX_COLOR_R 0x2464
|
||||
#define R300_VAP_VTX_COLOR_G 0x2468
|
||||
#define R300_VAP_VTX_COLOR_B 0x246C
|
||||
#define R300_VAP_VTX_POS_0_X_1 0x2490 // used for glVertex2*()
|
||||
#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
|
||||
#define R300_VAP_VTX_POS_0_Y_1 0x2494
|
||||
#define R300_VAP_VTX_COLOR_PKD 0x249C // RGBA
|
||||
#define R300_VAP_VTX_POS_0_X_2 0x24A0 // used for glVertex3*()
|
||||
#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
|
||||
#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
|
||||
#define R300_VAP_VTX_POS_0_Y_2 0x24A4
|
||||
#define R300_VAP_VTX_POS_0_Z_2 0x24A8
|
||||
#define R300_VAP_VTX_END_OF_PKT 0x24AC // write 0 to indicate end of packet?
|
||||
#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
|
||||
|
||||
/* gap */
|
||||
// BEGIN: !unverified!
|
||||
#define R300_GB_TILE_CONFIG 0x4018
|
||||
#define R300_GB_TILE_ENABLE (1 << 0)
|
||||
#define R300_GB_TILE_PIPE_COUNT_R300 (0 << 1)
|
||||
#define R300_GB_TILE_PIPE_COUNT_RV300 (3 << 1)
|
||||
#define R300_GB_TILE_SIZE_8 (0 << 4)
|
||||
#define R300_GB_TILE_SIZE_16 (1 << 4)
|
||||
#define R300_GB_TILE_SIZE_32 (2 << 4)
|
||||
#define R300_GB_SUPER_SIZE_1 (0 << 6)
|
||||
#define R300_GB_SUPER_SIZE_2 (1 << 6)
|
||||
#define R300_GB_SUPER_SIZE_4 (2 << 6)
|
||||
#define R300_GB_SUPER_SIZE_8 (3 << 6)
|
||||
#define R300_GB_SUPER_SIZE_16 (4 << 6)
|
||||
#define R300_GB_SUPER_SIZE_32 (5 << 6)
|
||||
#define R300_GB_SUPER_SIZE_64 (6 << 6)
|
||||
#define R300_GB_SUPER_SIZE_128 (7 << 6)
|
||||
#define R300_GB_SUPER_X_SHIFT 9 // 3 bits wide
|
||||
#define R300_GB_SUPER_Y_SHIFT 12 // 3 bits wide
|
||||
#define R300_GB_SUPER_TILE_A (0 << 15)
|
||||
#define R300_GB_SUPER_TILE_B (1 << 15)
|
||||
#define R300_GB_SUBPIXEL_1_12 (0 << 16)
|
||||
#define R300_GB_SUBPIXEL_1_16 (1 << 16)
|
||||
// END
|
||||
|
||||
/* These are values from r300_reg/r300_reg.h - they are known to be correct
|
||||
and are here so we can use one register file instead of several
|
||||
- Vladimir */
|
||||
#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5)
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16)
|
||||
|
||||
#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004
|
||||
/* each of the following is 3 bits wide, specifies number
|
||||
of components */
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
|
||||
# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
|
||||
|
||||
#define R300_GB_ENABLE 0x4008
|
||||
# define R300_GB_POINT_STUFF_ENABLE (1<<0)
|
||||
# define R300_GB_LINE_STUFF_ENABLE (1<<1)
|
||||
# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2)
|
||||
# define R300_GB_STENCIL_AUTO_ENABLE (1<<4)
|
||||
/* each of the following is 2 bits wide */
|
||||
#define R300_GB_TEX_REPLICATE 0
|
||||
#define R300_GB_TEX_ST 1
|
||||
#define R300_GB_TEX_STR 2
|
||||
# define R300_GB_TEX0_SOURCE_SHIFT 16
|
||||
# define R300_GB_TEX1_SOURCE_SHIFT 18
|
||||
# define R300_GB_TEX2_SOURCE_SHIFT 20
|
||||
# define R300_GB_TEX3_SOURCE_SHIFT 22
|
||||
# define R300_GB_TEX4_SOURCE_SHIFT 24
|
||||
# define R300_GB_TEX5_SOURCE_SHIFT 26
|
||||
# define R300_GB_TEX6_SOURCE_SHIFT 28
|
||||
# define R300_GB_TEX7_SOURCE_SHIFT 30
|
||||
|
||||
/* MSPOS - positions for multisample antialiasing (?) */
|
||||
#define R300_GB_MSPOS0 0x4010
|
||||
/* shifts - each of the fields is 4 bits */
|
||||
# define R300_GB_MSPOS0__MS_X0_SHIFT 0
|
||||
# define R300_GB_MSPOS0__MS_Y0_SHIFT 4
|
||||
# define R300_GB_MSPOS0__MS_X1_SHIFT 8
|
||||
# define R300_GB_MSPOS0__MS_Y1_SHIFT 12
|
||||
# define R300_GB_MSPOS0__MS_X2_SHIFT 16
|
||||
# define R300_GB_MSPOS0__MS_Y2_SHIFT 20
|
||||
# define R300_GB_MSPOS0__MSBD0_Y 24
|
||||
# define R300_GB_MSPOS0__MSBD0_X 28
|
||||
|
||||
#define R300_GB_MSPOS1 0x4014
|
||||
# define R300_GB_MSPOS1__MS_X3_SHIFT 0
|
||||
# define R300_GB_MSPOS1__MS_Y3_SHIFT 4
|
||||
# define R300_GB_MSPOS1__MS_X4_SHIFT 8
|
||||
# define R300_GB_MSPOS1__MS_Y4_SHIFT 12
|
||||
# define R300_GB_MSPOS1__MS_X5_SHIFT 16
|
||||
# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
|
||||
# define R300_GB_MSPOS1__MSBD1 24
|
||||
|
||||
|
||||
#define R300_GB_TILE_CONFIG 0x4018
|
||||
# define R300_GB_TILE_ENABLE (1<<0)
|
||||
# define R300_GB_TILE_PIPE_COUNT_RV300 0
|
||||
# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1)
|
||||
# define R300_GB_TILE_SIZE_8 0
|
||||
# define R300_GB_TILE_SIZE_16 (1<<4)
|
||||
# define R300_GB_TILE_SIZE_32 (2<<4)
|
||||
# define R300_GB_SUPER_SIZE_1 (0<<6)
|
||||
# define R300_GB_SUPER_SIZE_2 (1<<6)
|
||||
# define R300_GB_SUPER_SIZE_4 (2<<6)
|
||||
# define R300_GB_SUPER_SIZE_8 (3<<6)
|
||||
# define R300_GB_SUPER_SIZE_16 (4<<6)
|
||||
# define R300_GB_SUPER_SIZE_32 (5<<6)
|
||||
# define R300_GB_SUPER_SIZE_64 (6<<6)
|
||||
# define R300_GB_SUPER_SIZE_128 (7<<6)
|
||||
# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */
|
||||
# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */
|
||||
# define R300_GB_SUPER_TILE_A 0
|
||||
# define R300_GB_SUPER_TILE_B (1<<15)
|
||||
# define R300_GB_SUBPIXEL_1_12 0
|
||||
# define R300_GB_SUBPIXEL_1_16 (1<<16)
|
||||
|
||||
#define R300_GB_FIFO_SIZE 0x4024
|
||||
/* each of the following is 2 bits wide */
|
||||
#define R300_GB_FIFO_SIZE_32 0
|
||||
#define R300_GB_FIFO_SIZE_64 1
|
||||
#define R300_GB_FIFO_SIZE_128 2
|
||||
#define R300_GB_FIFO_SIZE_256 3
|
||||
# define R300_SC_IFIFO_SIZE_SHIFT 0
|
||||
# define R300_SC_TZFIFO_SIZE_SHIFT 2
|
||||
# define R300_SC_BFIFO_SIZE_SHIFT 4
|
||||
|
||||
# define R300_US_OFIFO_SIZE_SHIFT 12
|
||||
# define R300_US_WFIFO_SIZE_SHIFT 14
|
||||
/* the following use the same constants as above, but meaning is
|
||||
is times 2 (i.e. instead of 32 words it means 64 */
|
||||
# define R300_RS_TFIFO_SIZE_SHIFT 6
|
||||
# define R300_RS_CFIFO_SIZE_SHIFT 8
|
||||
# define R300_US_RAM_SIZE_SHIFT 10
|
||||
/* watermarks, 3 bits wide */
|
||||
# define R300_RS_HIGHWATER_COL_SHIFT 16
|
||||
# define R300_RS_HIGHWATER_TEX_SHIFT 19
|
||||
# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */
|
||||
# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24
|
||||
|
||||
#define R300_GB_SELECT 0x401C
|
||||
# define R300_GB_FOG_SELECT_C0A 0
|
||||
# define R300_GB_FOG_SELECT_C1A 1
|
||||
# define R300_GB_FOG_SELECT_C2A 2
|
||||
# define R300_GB_FOG_SELECT_C3A 3
|
||||
# define R300_GB_FOG_SELECT_1_1_W 4
|
||||
# define R300_GB_FOG_SELECT_Z 5
|
||||
# define R300_GB_DEPTH_SELECT_Z 0
|
||||
# define R300_GB_DEPTH_SELECT_1_1_W (1<<3)
|
||||
# define R300_GB_W_SELECT_1_W 0
|
||||
# define R300_GB_W_SELECT_1 (1<<4)
|
||||
|
||||
#define R300_GB_AA_CONFIG 0x4020
|
||||
# define R300_AA_ENABLE 0x01
|
||||
# define R300_AA_SUBSAMPLES_2 0
|
||||
# define R300_AA_SUBSAMPLES_3 (1<<1)
|
||||
# define R300_AA_SUBSAMPLES_4 (2<<1)
|
||||
# define R300_AA_SUBSAMPLES_6 (3<<1)
|
||||
|
||||
/* END */
|
||||
|
||||
/* gap */
|
||||
// The upper enable bits are guessed, based on fglrx reported limits.
|
||||
/* The upper enable bits are guessed, based on fglrx reported limits. */
|
||||
#define R300_TX_ENABLE 0x4104
|
||||
# define R300_TX_ENABLE_0 (1 << 0)
|
||||
# define R300_TX_ENABLE_1 (1 << 1)
|
||||
@@ -255,14 +410,21 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_TX_ENABLE_14 (1 << 14)
|
||||
# define R300_TX_ENABLE_15 (1 << 15)
|
||||
|
||||
// The pointsize is given in multiples of 6. The pointsize can be
|
||||
/* The pointsize is given in multiples of 6. The pointsize can be
|
||||
// enormous: Clear() renders a single point that fills the entire
|
||||
// framebuffer.
|
||||
// framebuffer. */
|
||||
#define R300_RE_POINTSIZE 0x421C
|
||||
# define R300_POINTSIZE_Y_SHIFT 0
|
||||
# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) // GUESS
|
||||
# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
|
||||
# define R300_POINTSIZE_X_SHIFT 16
|
||||
# define R300_POINTSIZE_X_MASK (0xFFFF << 16) // GUESS
|
||||
# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
|
||||
|
||||
/* This register needs to be set to (1<<1) for RV350 to correctly
|
||||
perform depth test (see --vb-triangles in r300_demo)
|
||||
Don't know about other chips. - Vladimir
|
||||
*/
|
||||
#define R300_RE_OCCLUSION_CNTL 0x42B4
|
||||
# define R300_OCCLUSION_ON (1<<1)
|
||||
|
||||
#define R300_RE_CULL_CNTL 0x42B8
|
||||
# define R300_CULL_FRONT (1 << 0)
|
||||
@@ -271,21 +433,21 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_FRONT_FACE_CW (1 << 2)
|
||||
|
||||
|
||||
// BEGIN: Rasterization / Interpolators - many guesses
|
||||
/* BEGIN: Rasterization / Interpolators - many guesses
|
||||
// So far, 0_UNKOWN_7 has always been set.
|
||||
// 0_UNKNOWN_18 has always been set except for clear operations.
|
||||
// TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
|
||||
// on the vertex program, *not* the fragment program)
|
||||
// on the vertex program, *not* the fragment program) */
|
||||
#define R300_RS_CNTL_0 0x4300
|
||||
# define R300_RS_CNTL_TC_CNT_SHIFT 2
|
||||
# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
|
||||
# define R300_RS_CNTL_0_UNKNOWN_7 (1 << 7)
|
||||
# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
|
||||
// Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register.
|
||||
/* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */
|
||||
#define R300_RS_CNTL_1 0x4304
|
||||
|
||||
/* gap */
|
||||
// Only used for texture coordinates (color seems to be always interpolated).
|
||||
/* Only used for texture coordinates (color seems to be always interpolated).
|
||||
// Use the source field to route texture coordinate input from the vertex program
|
||||
// to the desired interpolator. Note that the source field is relative to the
|
||||
// outputs the vertex program *actually* writes. If a vertex program only writes
|
||||
@@ -295,7 +457,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// I haven't seen it used that way.
|
||||
//
|
||||
// Note: The _UNKNOWN constants are always set in their respective register.
|
||||
// I don't know if this is necessary.
|
||||
// I don't know if this is necessary. */
|
||||
#define R300_RS_INTERP_0 0x4310
|
||||
#define R300_RS_INTERP_1 0x4314
|
||||
# define R300_RS_INTERP_1_UNKNOWN 0x40
|
||||
@@ -311,37 +473,37 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_RS_INTERP_SRC_MASK (7 << 2)
|
||||
# define R300_RS_INTERP_USED 0x00D10000
|
||||
|
||||
// These DWORDs control how vertex data is routed into fragment program
|
||||
// registers, after interpolators.
|
||||
/* These DWORDs control how vertex data is routed into fragment program
|
||||
// registers, after interpolators. */
|
||||
#define R300_RS_ROUTE_0 0x4330
|
||||
#define R300_RS_ROUTE_1 0x4334
|
||||
#define R300_RS_ROUTE_2 0x4338
|
||||
#define R300_RS_ROUTE_3 0x433C // GUESS
|
||||
#define R300_RS_ROUTE_4 0x4340 // GUESS
|
||||
#define R300_RS_ROUTE_5 0x4344 // GUESS
|
||||
#define R300_RS_ROUTE_6 0x4348 // GUESS
|
||||
#define R300_RS_ROUTE_7 0x434C // GUESS
|
||||
#define R300_RS_ROUTE_3 0x433C /* GUESS */
|
||||
#define R300_RS_ROUTE_4 0x4340 /* GUESS */
|
||||
#define R300_RS_ROUTE_5 0x4344 /* GUESS */
|
||||
#define R300_RS_ROUTE_6 0x4348 /* GUESS */
|
||||
#define R300_RS_ROUTE_7 0x434C /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_0 0
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_1 1
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_2 2
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_3 3
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_4 4
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_5 5 // GUESS
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_6 6 // GUESS
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_7 7 // GUESS
|
||||
# define R300_RS_ROUTE_ENABLE (1 << 3) // GUESS
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
|
||||
# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
|
||||
# define R300_RS_ROUTE_DEST_SHIFT 6
|
||||
# define R300_RS_ROUTE_DEST_MASK (31 << 6) // GUESS
|
||||
# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
|
||||
|
||||
// Special handling for color: When the fragment program uses color,
|
||||
/* Special handling for color: When the fragment program uses color,
|
||||
// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
|
||||
// color register index.
|
||||
// color register index. */
|
||||
# define R300_RS_ROUTE_0_COLOR (1 << 14)
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT (1 << 17)
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 6) // GUESS
|
||||
// END
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 6) /* GUESS */
|
||||
/* END */
|
||||
|
||||
// BEGIN: Scissors and cliprects
|
||||
/* BEGIN: Scissors and cliprects
|
||||
// There are four clipping rectangles. Their corner coordinates are inclusive.
|
||||
// Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
|
||||
// on whether the pixel is inside cliprects 0-3, respectively. For example,
|
||||
@@ -354,7 +516,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// scissors rectangle are drawn. (coordinates are inclusive)
|
||||
//
|
||||
// For some reason, the top-left corner of the framebuffer is at (1440, 1440)
|
||||
// for the purpose of clipping and scissors.
|
||||
// for the purpose of clipping and scissors. */
|
||||
#define R300_RE_CLIPRECT_TL_0 0x43B0
|
||||
#define R300_RE_CLIPRECT_BR_0 0x43B4
|
||||
#define R300_RE_CLIPRECT_TL_1 0x43B8
|
||||
@@ -395,12 +557,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_SCISSORS_X_MASK (0x1FFF << 0)
|
||||
# define R300_SCISSORS_Y_SHIFT 13
|
||||
# define R300_SCISSORS_Y_MASK (0x1FFF << 13)
|
||||
// END
|
||||
/* END */
|
||||
|
||||
// BEGIN: Texture specification
|
||||
/* BEGIN: Texture specification
|
||||
// The texture specification dwords are grouped by meaning and not by texture unit.
|
||||
// This means that e.g. the offset for texture image unit N is found in register
|
||||
// TX_OFFSET_0 + (4*N)
|
||||
// TX_OFFSET_0 + (4*N) */
|
||||
#define R300_TX_FILTER_0 0x4400
|
||||
# define R300_TX_REPEAT 0
|
||||
# define R300_TX_CLAMP_TO_EDGE 1
|
||||
@@ -422,23 +584,28 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_TX_WIDTHMASK_MASK (2047 << 0)
|
||||
# define R300_TX_HEIGHTMASK_SHIFT 11
|
||||
# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
|
||||
# define R300_TX_SIZE_SHIFT 26 // largest of width, height
|
||||
# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
|
||||
# define R300_TX_SIZE_MASK (15 << 26)
|
||||
#define R300_TX_FORMAT_0 0x44C0
|
||||
/* Note - other bits are not known yet.. */
|
||||
# define R300_TX_FORMAT_WIDTH_SHIFT 12
|
||||
# define R300_TX_FORMAT_WIDTH_MASK (0xf<<R300_TX_FORMAT_WIDTH_SHIFT)
|
||||
# define R300_TX_FORMAT_HEIGHT_SHIFT 16
|
||||
# define R300_TX_FORMAT_HEIGHT_MASK (0xf<<R300_TX_FORMAT_HEIGHT_SHIFT)
|
||||
#define R300_TX_OFFSET_0 0x4540
|
||||
// BEGIN: Guess from R200
|
||||
/* BEGIN: Guess from R200 */
|
||||
# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
|
||||
# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
|
||||
# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
|
||||
# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
|
||||
# define R300_TXO_OFFSET_MASK 0xffffffe0
|
||||
# define R300_TXO_OFFSET_SHIFT 5
|
||||
// END
|
||||
/* END */
|
||||
#define R300_TX_UNK4_0 0x4580
|
||||
#define R300_TX_UNK5_0 0x45C0
|
||||
// END
|
||||
/* END */
|
||||
|
||||
// BEGIN: Fragment program instruction set
|
||||
/* BEGIN: Fragment program instruction set
|
||||
// Fragment programs are written directly into register space.
|
||||
// There are separate instruction streams for texture instructions and ALU
|
||||
// instructions.
|
||||
@@ -453,32 +620,32 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// 1 node, a value of 3 means 4 nodes.
|
||||
// The total amount of instructions is defined in PFS_CNTL_2. The offsets are
|
||||
// offsets into the respective instruction streams, while *_END points to the
|
||||
// last instruction relative to this offset.
|
||||
// last instruction relative to this offset. */
|
||||
#define R300_PFS_CNTL_0 0x4600
|
||||
# define R300_PFS_CNTL_LAST_NODES_SHIFT 0
|
||||
# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0)
|
||||
# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3)
|
||||
#define R300_PFS_CNTL_1 0x4604
|
||||
// There is an unshifted value here which has so far always been equal to the
|
||||
// index of the highest used temporary register.
|
||||
/* There is an unshifted value here which has so far always been equal to the
|
||||
// index of the highest used temporary register. */
|
||||
#define R300_PFS_CNTL_2 0x4608
|
||||
# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0
|
||||
# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0)
|
||||
# define R300_PFS_CNTL_ALU_END_SHIFT 6
|
||||
# define R300_PFS_CNTL_ALU_END_MASK (63 << 0)
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) // GUESS
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
|
||||
# define R300_PFS_CNTL_TEX_END_SHIFT 18
|
||||
# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) // GUESS
|
||||
# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
|
||||
|
||||
/* gap */
|
||||
// Nodes are stored backwards. The last active node is always stored in
|
||||
/* Nodes are stored backwards. The last active node is always stored in
|
||||
// PFS_NODE_3.
|
||||
// Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
|
||||
// first node is stored in NODE_2, the second node is stored in NODE_3.
|
||||
//
|
||||
// Offsets are relative to the master offset from PFS_CNTL_2.
|
||||
// LAST_NODE is set for the last node, and only for the last node.
|
||||
// LAST_NODE is set for the last node, and only for the last node. */
|
||||
#define R300_PFS_NODE_0 0x4610
|
||||
#define R300_PFS_NODE_1 0x4614
|
||||
#define R300_PFS_NODE_2 0x4618
|
||||
@@ -493,20 +660,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
|
||||
# define R300_PFS_NODE_LAST_NODE (1 << 22)
|
||||
|
||||
// TEX
|
||||
/* TEX
|
||||
// As far as I can tell, texture instructions cannot write into output
|
||||
// registers directly. A subsequent ALU instruction is always necessary,
|
||||
// even if it's just MAD o0, r0, 1, 0
|
||||
// even if it's just MAD o0, r0, 1, 0 */
|
||||
#define R300_PFS_TEXI_0 0x4620
|
||||
# define R300_FPITX_SRC_SHIFT 0
|
||||
# define R300_FPITX_SRC_MASK (31 << 0)
|
||||
# define R300_FPITX_SRC_CONST (1 << 5) // GUESS
|
||||
# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
|
||||
# define R300_FPITX_DST_SHIFT 6
|
||||
# define R300_FPITX_DST_MASK (31 << 6)
|
||||
# define R300_FPITX_IMAGE_SHIFT 11
|
||||
# define R300_FPITX_IMAGE_MASK (15 << 11) // GUESS based on layout and native limits
|
||||
# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
|
||||
|
||||
// ALU
|
||||
/* ALU
|
||||
// The ALU instructions register blocks are enumerated according to the order
|
||||
// in which fglrx. I assume there is space for 64 instructions, since
|
||||
// each block has space for a maximum of 64 DWORDs, and this matches reported
|
||||
@@ -556,7 +723,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// The destination register index is in FPI1 (color) and FPI3 (alpha) together
|
||||
// with enable bits.
|
||||
// There are separate enable bits for writing into temporary registers
|
||||
// (DSTC_REG_*/DSTA_REG) and and program output registers (DSTC_OUTPUT_*/DSTA_OUTPUT).
|
||||
// (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* /DSTA_OUTPUT).
|
||||
// You can write to both at once, or not write at all (the same index
|
||||
// must be used for both).
|
||||
//
|
||||
@@ -565,7 +732,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// - Operation is MAD
|
||||
// - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP
|
||||
// - Set FPI0/FPI2_SPECIAL_LRP
|
||||
// Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD
|
||||
// Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD */
|
||||
#define R300_PFS_INSTR1_0 0x46C0
|
||||
# define R300_FPI1_SRC0C_SHIFT 0
|
||||
# define R300_FPI1_SRC0C_MASK (31 << 0)
|
||||
@@ -619,7 +786,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_FPI0_ARGC_SRC1C_LRP 15
|
||||
# define R300_FPI0_ARGC_ZERO 20
|
||||
# define R300_FPI0_ARGC_ONE 21
|
||||
# define R300_FPI0_ARGC_HALF 22 // GUESS
|
||||
# define R300_FPI0_ARGC_HALF 22 /* GUESS */
|
||||
# define R300_FPI0_ARGC_SRC0C_YZX 23
|
||||
# define R300_FPI0_ARGC_SRC1C_YZX 24
|
||||
# define R300_FPI0_ARGC_SRC2C_YZX 25
|
||||
@@ -670,7 +837,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_FPI2_ARGA_SRC1A_LRP 15
|
||||
# define R300_FPI2_ARGA_ZERO 16
|
||||
# define R300_FPI2_ARGA_ONE 17
|
||||
# define R300_FPI2_ARGA_HALF 18 // GUESS
|
||||
# define R300_FPI2_ARGA_HALF 18 /* GUESS */
|
||||
|
||||
# define R300_FPI2_ARG0A_SHIFT 0
|
||||
# define R300_FPI2_ARG0A_MASK (31 << 0)
|
||||
@@ -694,7 +861,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_FPI2_OUTA_RSQ (11 << 23)
|
||||
# define R300_FPI2_OUTA_SAT (1 << 30)
|
||||
# define R300_FPI2_UNKNOWN_31 (1 << 31)
|
||||
// END
|
||||
/* END */
|
||||
|
||||
/* gap */
|
||||
#define R300_PP_ALPHA_TEST 0x4BD4
|
||||
@@ -711,22 +878,22 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
# define R300_ALPHA_TEST_ENABLE (1 << 11)
|
||||
|
||||
/* gap */
|
||||
// Fragment program parameters in 7.16 floating point
|
||||
/* Fragment program parameters in 7.16 floating point */
|
||||
#define R300_PFS_PARAM_0_X 0x4C00
|
||||
#define R300_PFS_PARAM_0_Y 0x4C04
|
||||
#define R300_PFS_PARAM_0_Z 0x4C08
|
||||
#define R300_PFS_PARAM_0_W 0x4C0C
|
||||
// GUESS: PARAM_31 is last, based on native limits reported by fglrx
|
||||
/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */
|
||||
#define R300_PFS_PARAM_31_X 0x4DF0
|
||||
#define R300_PFS_PARAM_31_Y 0x4DF4
|
||||
#define R300_PFS_PARAM_31_Z 0x4DF8
|
||||
#define R300_PFS_PARAM_31_W 0x4DFC
|
||||
|
||||
// Notes:
|
||||
/* Notes:
|
||||
// - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in the application
|
||||
// - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND are set to the same
|
||||
// function (both registers are always set up completely in any case)
|
||||
// - Most blend flags are simply copied from R200 and not tested yet
|
||||
// - Most blend flags are simply copied from R200 and not tested yet */
|
||||
#define R300_RB3D_CBLEND 0x4E04
|
||||
#define R300_RB3D_ABLEND 0x4E08
|
||||
/* the following only appear in CBLEND */
|
||||
@@ -770,61 +937,63 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
|
||||
/* gap */
|
||||
#define R300_RB3D_COLOROFFSET0 0x4E28
|
||||
# define R300_COLOROFFSET_MASK 0xFFFFFFF0 // GUESS
|
||||
#define R300_RB3D_COLOROFFSET1 0x4E2C // GUESS
|
||||
#define R300_RB3D_COLOROFFSET2 0x4E30 // GUESS
|
||||
#define R300_RB3D_COLOROFFSET3 0x4E34 // GUESS
|
||||
# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
|
||||
/* gap */
|
||||
// Bit 16: Larger tiles
|
||||
/* Bit 16: Larger tiles
|
||||
// Bit 17: 4x2 tiles
|
||||
// Bit 18: Extremely weird tile like, but some pixels duplicated?
|
||||
// Bit 18: Extremely weird tile like, but some pixels duplicated? */
|
||||
#define R300_RB3D_COLORPITCH0 0x4E38
|
||||
# define R300_COLORPITCH_MASK 0x00001FF8 // GUESS
|
||||
# define R300_COLOR_TILE_ENABLE (1 << 16) // GUESS
|
||||
# define R300_COLOR_MICROTILE_ENABLE (1 << 17) // GUESS
|
||||
# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) // GUESS
|
||||
# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) // GUESS
|
||||
# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) // GUESS
|
||||
# define R300_COLOR_UNKNOWN_22_23 (3 << 22) // GUESS: Format?
|
||||
#define R300_RB3D_COLORPITCH1 0x4E3C // GUESS
|
||||
#define R300_RB3D_COLORPITCH2 0x4E40 // GUESS
|
||||
#define R300_RB3D_COLORPITCH3 0x4E44 // GUESS
|
||||
# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
# define R300_COLOR_UNKNOWN_22_23 (3 << 22) /* GUESS: Format? */
|
||||
#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
|
||||
|
||||
/* gap */
|
||||
// Guess by Vladimir.
|
||||
// Set to 0A before 3D operations, set to 02 afterwards.
|
||||
/* Guess by Vladimir.
|
||||
// Set to 0A before 3D operations, set to 02 afterwards. */
|
||||
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C
|
||||
# define R300_RB3D_DSTCACHE_02 0x00000002
|
||||
# define R300_RB3D_DSTCACHE_0A 0x0000000A
|
||||
|
||||
/* gap */
|
||||
// There seems to be no "write only" setting, so use Z-test = ALWAYS for this.
|
||||
/* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */
|
||||
/* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */
|
||||
#define R300_RB3D_ZCNTL_0 0x4F00
|
||||
# define R300_RB3D_Z_DISABLED_1 0x00000010 // GUESS
|
||||
# define R300_RB3D_Z_DISABLED_2 0x00000014 // GUESS
|
||||
# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
|
||||
# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
|
||||
# define R300_RB3D_Z_TEST 0x00000012
|
||||
# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
|
||||
# define R300_RB3D_Z_WRITE_ONLY 0x00000006
|
||||
#define R300_RB3D_ZCNTL_1 0x4F04
|
||||
# define R300_Z_TEST_NEVER (0 << 0) // GUESS (based on R200)
|
||||
# define R300_Z_TEST_NEVER (0 << 0) /* GUESS (based on R200) */
|
||||
# define R300_Z_TEST_LESS (1 << 0)
|
||||
# define R300_Z_TEST_LEQUAL (2 << 0)
|
||||
# define R300_Z_TEST_EQUAL (3 << 0) // GUESS
|
||||
# define R300_Z_TEST_GEQUAL (4 << 0) // GUESS
|
||||
# define R300_Z_TEST_GREATER (5 << 0) // GUESS
|
||||
# define R300_Z_TEST_EQUAL (3 << 0) /* GUESS */
|
||||
# define R300_Z_TEST_GEQUAL (4 << 0) /* GUESS */
|
||||
# define R300_Z_TEST_GREATER (5 << 0) /* GUESS */
|
||||
# define R300_Z_TEST_NEQUAL (6 << 0)
|
||||
# define R300_Z_TEST_ALWAYS (7 << 0)
|
||||
# define R300_Z_TEST_MASK (7 << 0)
|
||||
/* gap */
|
||||
#define R300_RB3D_DEPTHOFFSET 0x4F20
|
||||
#define R300_RB3D_DEPTHPITCH 0x4F24
|
||||
# define R300_DEPTHPITCH_MASK 0x00001FF8 // GUESS
|
||||
# define R300_DEPTH_TILE_ENABLE (1 << 16) // GUESS
|
||||
# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) // GUESS
|
||||
# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) // GUESS
|
||||
# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) // GUESS
|
||||
# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) // GUESS
|
||||
# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
|
||||
// BEGIN: Vertex program instruction set
|
||||
/* BEGIN: Vertex program instruction set
|
||||
// Every instruction is four dwords long:
|
||||
// DWORD 0: output and opcode
|
||||
// DWORD 1: first argument
|
||||
@@ -851,7 +1020,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
// Second argument: xyzx
|
||||
// Third argument: xyzw
|
||||
// Whenever the result is used later in the fragment program, fglrx forces x and w
|
||||
// to be 1.0 in the input selection; I don't know whether this is strictly necessary
|
||||
// to be 1.0 in the input selection; I don't know whether this is strictly necessary */
|
||||
#define R300_VPI_OUT_OP_DOT (1 << 0)
|
||||
#define R300_VPI_OUT_OP_MUL (2 << 0)
|
||||
#define R300_VPI_OUT_OP_ADD (3 << 0)
|
||||
@@ -876,7 +1045,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
|
||||
|
||||
#define R300_VPI_OUT_REG_INDEX_SHIFT 13
|
||||
#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) // GUESS based on fglrx native limits
|
||||
#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
|
||||
|
||||
#define R300_VPI_OUT_WRITE_X (1 << 20)
|
||||
#define R300_VPI_OUT_WRITE_Y (1 << 21)
|
||||
@@ -887,14 +1056,14 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) // GUESS
|
||||
#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
|
||||
|
||||
#define R300_VPI_IN_REG_INDEX_SHIFT 5
|
||||
#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) // GUESS based on fglrx native limits
|
||||
#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
|
||||
|
||||
// The R300 can select components from the input register arbitrarily.
|
||||
/* The R300 can select components from the input register arbitrarily.
|
||||
// Use the following constants, shifted by the component shift you
|
||||
// want to select
|
||||
// want to select */
|
||||
#define R300_VPI_IN_SELECT_X 0
|
||||
#define R300_VPI_IN_SELECT_Y 1
|
||||
#define R300_VPI_IN_SELECT_Z 2
|
||||
@@ -912,6 +1081,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
#define R300_VPI_IN_NEG_Y (1 << 26)
|
||||
#define R300_VPI_IN_NEG_Z (1 << 27)
|
||||
#define R300_VPI_IN_NEG_W (1 << 28)
|
||||
// END
|
||||
/* END */
|
||||
|
||||
#endif // _R300_REG_H
|
||||
#endif /* _R300_REG_H */
|
||||
|
||||
@@ -45,6 +45,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon_macros.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_state.h"
|
||||
#include "r300_context.h"
|
||||
@@ -52,6 +54,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_state.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_program.h"
|
||||
#include "r300_tex.h"
|
||||
|
||||
#include "r300_lib.h"
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
@@ -61,6 +66,440 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* rasterization hardware for rendering.
|
||||
**********************************************************************/
|
||||
|
||||
static int r300_get_primitive_type(r300ContextPtr rmesa,
|
||||
GLcontext *ctx,
|
||||
int start,
|
||||
int end,
|
||||
int prim)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
int type=-1, min_vertices=0;
|
||||
char *name="UNKNOWN";
|
||||
|
||||
if(end<=start)return -1; /* do we need to watch for this ? */
|
||||
|
||||
switch (prim & PRIM_MODE_MASK) {
|
||||
case GL_POINTS:
|
||||
name="P";
|
||||
type=R300_VAP_VF_CNTL__PRIM_POINTS;
|
||||
min_vertices=1;
|
||||
break;
|
||||
case GL_LINES:
|
||||
name="L";
|
||||
type=R300_VAP_VF_CNTL__PRIM_LINES;
|
||||
min_vertices=2;
|
||||
break;
|
||||
case GL_LINE_STRIP:
|
||||
name="LS";
|
||||
type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
|
||||
min_vertices=2;
|
||||
break;
|
||||
case GL_LINE_LOOP:
|
||||
name="LL";
|
||||
min_vertices=2;
|
||||
return -1;
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
name="T";
|
||||
type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
|
||||
min_vertices=3;
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
name="TS";
|
||||
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
|
||||
min_vertices=3;
|
||||
break;
|
||||
case GL_TRIANGLE_FAN:
|
||||
name="TF";
|
||||
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
|
||||
min_vertices=3;
|
||||
break;
|
||||
case GL_QUADS:
|
||||
name="Q";
|
||||
type=R300_VAP_VF_CNTL__PRIM_QUADS;
|
||||
min_vertices=4;
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
name="QS";
|
||||
type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
|
||||
min_vertices=4;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
|
||||
__FILE__, __FUNCTION__,
|
||||
prim & PRIM_MODE_MASK);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "[%d-%d]%s ", start, end, name);
|
||||
#endif
|
||||
if(start+min_vertices>=end){
|
||||
static int warn_once=1;
|
||||
if(warn_once){
|
||||
fprintf(stderr, "%s:%s Not enough vertices to draw primitive %02x - help me !\n",
|
||||
__FILE__, __FUNCTION__,
|
||||
prim & PRIM_MODE_MASK);
|
||||
warn_once=0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/* This function compiles GL context into state registers that
|
||||
describe data routing inside of R300 pipeline.
|
||||
|
||||
In particular, it programs input_route, output_vtx_fmt, texture
|
||||
unit configuration and gb_output_vtx_fmt
|
||||
|
||||
This function encompasses setup_AOS() from r300_lib.c
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* Immediate implementation - vertex data is sent via command stream */
|
||||
|
||||
static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
|
||||
|
||||
#define output_vector(v, i) \
|
||||
{ \
|
||||
int _i; \
|
||||
for(_i=0;_i<v->size;_i++){ \
|
||||
efloat(VEC_ELT(v, GLfloat, i)[_i]); \
|
||||
} \
|
||||
for(_i=v->size;_i<4;_i++){ \
|
||||
efloat(default_vector[_i]); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Immediate implementation - vertex data is sent via command stream */
|
||||
|
||||
static void r300_render_immediate_primitive(r300ContextPtr rmesa,
|
||||
GLcontext *ctx,
|
||||
int start,
|
||||
int end,
|
||||
int prim)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
int k, type;
|
||||
LOCAL_VARS
|
||||
|
||||
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
|
||||
VB->ObjPtr->size, VB->ObjPtr->stride);
|
||||
fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
|
||||
VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
|
||||
fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
|
||||
VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
|
||||
#endif
|
||||
|
||||
if(type<0)return;
|
||||
|
||||
|
||||
start_immediate_packet(end-start, type, 8+4*rmesa->state.texture.tc_count);
|
||||
|
||||
for(i=start;i<end;i++){
|
||||
#if 0
|
||||
fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
|
||||
VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
|
||||
VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
|
||||
VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
|
||||
VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
|
||||
|
||||
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
|
||||
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
|
||||
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
|
||||
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* coordinates */
|
||||
output_vector(VB->ObjPtr, i);
|
||||
|
||||
/* color components */
|
||||
output_vector(VB->ColorPtr[0], i);
|
||||
|
||||
/* texture coordinates */
|
||||
for(k=0;k < ctx->Const.MaxTextureUnits;k++)
|
||||
if(ctx->Texture.Unit[k].Enabled)
|
||||
output_vector(VB->TexCoordPtr[k], i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void assign_pipeline(r300ContextPtr rmesa, R300_PIPELINE *p)
|
||||
{
|
||||
/* Watch out ! This is buggy .. but will do for now */
|
||||
|
||||
/* At least one sanity check is in order */
|
||||
if(sizeof(rmesa->state.vertex_shader) != sizeof(p->vertex_shader)){
|
||||
fprintf(stderr, "Aieee ! vertex_shader sizes don't match.\n");
|
||||
exit(-1);
|
||||
}
|
||||
if(sizeof(rmesa->state.pixel_shader) != sizeof(p->pixel_shader)){
|
||||
fprintf(stderr, "Aieee ! vertex_shader sizes don't match.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memcpy(&rmesa->state.vertex_shader, &(p->vertex_shader), sizeof(rmesa->state.vertex_shader));
|
||||
memcpy(&rmesa->state.pixel_shader, &(p->pixel_shader), sizeof(rmesa->state.pixel_shader));
|
||||
|
||||
}
|
||||
|
||||
static GLboolean r300_run_immediate_render(GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
/* Only do 2d textures */
|
||||
struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
|
||||
r300TexObjPtr t=to->DriverData;
|
||||
LOCAL_VARS
|
||||
|
||||
|
||||
/* Update texture state - needs to be done only when actually changed..
|
||||
All the time for now.. */
|
||||
/* Flush state - make sure command buffer is nice and large */
|
||||
r300Flush(ctx);
|
||||
|
||||
|
||||
if (RADEON_DEBUG == DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
|
||||
/* needed before starting 3d operation .. */
|
||||
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
|
||||
e32(0x0000000a);
|
||||
|
||||
reg_start(0x4f18,0);
|
||||
e32(0x00000003);
|
||||
|
||||
|
||||
#if 0 /* looks like the Z offset issue got fixed */
|
||||
rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
|
||||
| R300_VPORT_X_OFFSET_ENA
|
||||
| R300_VPORT_Y_SCALE_ENA
|
||||
| R300_VPORT_Y_OFFSET_ENA
|
||||
| R300_VTX_W0_FMT;
|
||||
#endif
|
||||
R300_STATECHANGE(rmesa, vte);
|
||||
|
||||
r300EmitState(rmesa);
|
||||
|
||||
/* Magic register - note it is right after 20b0 */
|
||||
|
||||
if(rmesa->state.texture.tc_count>0){
|
||||
reg_start(0x20b4,0);
|
||||
e32(0x0000000c);
|
||||
|
||||
assign_pipeline(rmesa, &SINGLE_TEXTURE_PIPELINE);
|
||||
} else {
|
||||
assign_pipeline(rmesa, &FLAT_COLOR_PIPELINE);
|
||||
}
|
||||
|
||||
rmesa->state.vertex_shader.matrix[0].length=16;
|
||||
memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
|
||||
|
||||
rmesa->state.vertex_shader.unknown2.length=4;
|
||||
rmesa->state.vertex_shader.unknown2.body.f[0]=0.0;
|
||||
rmesa->state.vertex_shader.unknown2.body.f[1]=0.0;
|
||||
rmesa->state.vertex_shader.unknown2.body.f[2]=1.0;
|
||||
rmesa->state.vertex_shader.unknown2.body.f[3]=0.0;
|
||||
|
||||
|
||||
r300EmitVertexShader(rmesa);
|
||||
r300EmitPixelShader(rmesa);
|
||||
|
||||
#if 0
|
||||
reg_start(R300_RB3D_COLORMASK, 0);
|
||||
e32(0xf);
|
||||
#endif
|
||||
/* ----------------------------------- */
|
||||
|
||||
/* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
|
||||
r300EmitLOAD_VBPNTR(rmesa, 0);
|
||||
|
||||
for(i=0; i < VB->PrimitiveCount; i++){
|
||||
GLuint prim = VB->Primitive[i].mode;
|
||||
GLuint start = VB->Primitive[i].start;
|
||||
GLuint length = VB->Primitive[i].count;
|
||||
r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
|
||||
}
|
||||
|
||||
/* This sequence is required after any 3d drawing packet
|
||||
I suspect it work arounds a bug (or deficiency) in hardware */
|
||||
|
||||
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
|
||||
e32(0x0000000a);
|
||||
|
||||
reg_start(0x4f18,0);
|
||||
e32(0x00000003);
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* vertex buffer implementation */
|
||||
|
||||
/* We use the start part of GART texture buffer for vertices */
|
||||
|
||||
|
||||
static void upload_vertex_buffer(r300ContextPtr rmesa,
|
||||
GLcontext *ctx, AOS_DATA *array, int *n_arrays)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
int offset=0, idx=0;
|
||||
int i,j;
|
||||
radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
|
||||
/* Not the most efficient implementation, but, for now, I just want something that
|
||||
works */
|
||||
/* to do - make single memcpy per column (is it possible ?) */
|
||||
/* to do - use dirty flags to avoid redundant copies */
|
||||
#define UPLOAD_VECTOR(v, r, f)\
|
||||
{ \
|
||||
/* Is the data dirty ? */ \
|
||||
if (v->flags & ((1<<v->size)-1)) { \
|
||||
fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); \
|
||||
if(v->size*4==v->stride){\
|
||||
/* fast path */ \
|
||||
memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
|
||||
} else { \
|
||||
for(i=0;i<VB->Count;i++){ \
|
||||
/* copy one vertex at a time*/ \
|
||||
memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
|
||||
} \
|
||||
} \
|
||||
/* v->flags &= ~((1<<v->size)-1);*/ \
|
||||
} \
|
||||
array[idx].element_size=v->size; \
|
||||
array[idx].stride=v->size; \
|
||||
array[idx].format=(f); \
|
||||
array[idx].ncomponents=v->size; \
|
||||
array[idx].offset=rsp->gartTextures.handle+offset; \
|
||||
array[idx].reg=r; \
|
||||
offset+=v->size*4*VB->Count; \
|
||||
idx++; \
|
||||
}
|
||||
|
||||
UPLOAD_VECTOR(VB->ObjPtr, REG_COORDS, AOS_FORMAT_FLOAT);
|
||||
UPLOAD_VECTOR(VB->ColorPtr[0], REG_COLOR0, AOS_FORMAT_FLOAT_COLOR);
|
||||
|
||||
*n_arrays=idx;
|
||||
if(idx>=R300_MAX_AOS_ARRAYS){
|
||||
fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void r300_render_vb_flat_primitive(r300ContextPtr rmesa,
|
||||
GLcontext *ctx,
|
||||
int start,
|
||||
int end,
|
||||
int prim)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
int k, type, n_arrays;
|
||||
LOCAL_VARS
|
||||
|
||||
if(end<=start)return; /* do we need to watch for this ? */
|
||||
|
||||
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
|
||||
if(type<0)return;
|
||||
|
||||
fire_AOS(PASS_PREFIX end-start, type);
|
||||
}
|
||||
|
||||
static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
int i, j, n_arrays;
|
||||
AOS_DATA vb_arrays[R300_MAX_AOS_ARRAYS];
|
||||
AOS_DATA vb_arrays2[R300_MAX_AOS_ARRAYS];
|
||||
LOCAL_VARS
|
||||
|
||||
if (RADEON_DEBUG == DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* setup array of structures data */
|
||||
|
||||
upload_vertex_buffer(rmesa, ctx, vb_arrays, &n_arrays);
|
||||
fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
|
||||
|
||||
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
|
||||
e32(0x0000000a);
|
||||
|
||||
reg_start(0x4f18,0);
|
||||
e32(0x00000003);
|
||||
|
||||
r300_setup_routing(rmesa, ctx, GL_FALSE);
|
||||
|
||||
r300EmitState(rmesa);
|
||||
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].length=16;
|
||||
memcpy(FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
|
||||
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.length=4;
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[0]=0.0;
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
|
||||
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
|
||||
|
||||
program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
|
||||
|
||||
set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0);
|
||||
set_init21(PASS_PREFIX 0.0,1.0);
|
||||
|
||||
for(i=0; i < VB->PrimitiveCount; i++){
|
||||
GLuint prim = VB->Primitive[i].mode;
|
||||
GLuint start = VB->Primitive[i].start;
|
||||
GLuint length = VB->Primitive[i].count;
|
||||
|
||||
/* copy arrays */
|
||||
memcpy(vb_arrays2, vb_arrays, sizeof(AOS_DATA)*n_arrays);
|
||||
for(j=0;j<n_arrays;j++){
|
||||
vb_arrays2[j].offset+=vb_arrays2[j].stride*start*4;
|
||||
}
|
||||
|
||||
setup_AOS(PASS_PREFIX vb_arrays2, n_arrays);
|
||||
|
||||
r300_render_vb_flat_primitive(rmesa, ctx, start, start + length, prim);
|
||||
}
|
||||
|
||||
/* This sequence is required after any 3d drawing packet
|
||||
I suspect it work arounds a bug (or deficiency) in hardware */
|
||||
|
||||
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
|
||||
e32(0x0000000a);
|
||||
|
||||
reg_start(0x4f18,0);
|
||||
e32(0x00000003);
|
||||
|
||||
end_3d(PASS_PREFIX_VOID);
|
||||
|
||||
/* Flush state - we are done drawing.. */
|
||||
r300Flush(ctx);
|
||||
fprintf(stderr, "\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the pipeline manager to render a batch of primitives.
|
||||
@@ -71,10 +510,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
static GLboolean r300_run_render(GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
|
||||
if (RADEON_DEBUG == DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
return r300_run_immediate_render(ctx, stage);
|
||||
#else
|
||||
return GL_TRUE;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
|
||||
@@ -148,8 +598,10 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
//FALLBACK_IF(ctx->Color.DitherFlag);
|
||||
|
||||
/* I'm almost certain I forgot something here */
|
||||
#if 0 /* This should work now.. */
|
||||
FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
|
||||
FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
|
||||
#endif
|
||||
//FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
|
||||
FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG
|
||||
FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
|
||||
FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
|
||||
@@ -164,10 +616,15 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
|
||||
FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
|
||||
|
||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
|
||||
/* One step at a time - let one texture pass.. */
|
||||
for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
|
||||
FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
|
||||
|
||||
|
||||
/* let r300_run_render do its job */
|
||||
#if 0
|
||||
stage->active = GL_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,315 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "r300_reg.h"
|
||||
#include "r300_program.h"
|
||||
|
||||
static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
int pp_misc = rmesa->hw.at.cmd[R300_AT_ALPHA_TEST];
|
||||
GLubyte refByte;
|
||||
|
||||
CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
|
||||
|
||||
R300_STATECHANGE(rmesa, at);
|
||||
|
||||
pp_misc &= ~(R300_ALPHA_TEST_OP_MASK | R300_REF_ALPHA_MASK);
|
||||
pp_misc |= (refByte & R300_REF_ALPHA_MASK);
|
||||
|
||||
switch (func) {
|
||||
case GL_NEVER:
|
||||
pp_misc |= R300_ALPHA_TEST_FAIL;
|
||||
break;
|
||||
case GL_LESS:
|
||||
pp_misc |= R300_ALPHA_TEST_LESS;
|
||||
break;
|
||||
case GL_EQUAL:
|
||||
pp_misc |= R300_ALPHA_TEST_EQUAL;
|
||||
break;
|
||||
case GL_LEQUAL:
|
||||
pp_misc |= R300_ALPHA_TEST_LEQUAL;
|
||||
break;
|
||||
case GL_GREATER:
|
||||
pp_misc |= R300_ALPHA_TEST_GREATER;
|
||||
break;
|
||||
case GL_NOTEQUAL:
|
||||
pp_misc |= R300_ALPHA_TEST_NEQUAL;
|
||||
break;
|
||||
case GL_GEQUAL:
|
||||
pp_misc |= R300_ALPHA_TEST_GEQUAL;
|
||||
break;
|
||||
case GL_ALWAYS:
|
||||
pp_misc |= R300_ALPHA_TEST_PASS;
|
||||
break;
|
||||
}
|
||||
|
||||
rmesa->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
|
||||
}
|
||||
|
||||
static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
|
||||
{
|
||||
GLubyte color[4];
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
fprintf(stderr, "%s:%s is not implemented yet. Fixme !\n", __FILE__, __FUNCTION__);
|
||||
#if 0
|
||||
R200_STATECHANGE(rmesa, ctx);
|
||||
CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
|
||||
if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] =
|
||||
radeonPackColor(4, color[0], color[1], color[2], color[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the hardware blend factor setting. This same function is used
|
||||
* for source and destination of both alpha and RGB.
|
||||
*
|
||||
* \returns
|
||||
* The hardware register value for the specified blend factor. This value
|
||||
* will need to be shifted into the correct position for either source or
|
||||
* destination factor.
|
||||
*
|
||||
* \todo
|
||||
* Since the two cases where source and destination are handled differently
|
||||
* are essentially error cases, they should never happen. Determine if these
|
||||
* cases can be removed.
|
||||
*/
|
||||
static int blend_factor(GLenum factor, GLboolean is_src)
|
||||
{
|
||||
int func;
|
||||
|
||||
switch (factor) {
|
||||
case GL_ZERO:
|
||||
func = R200_BLEND_GL_ZERO;
|
||||
break;
|
||||
case GL_ONE:
|
||||
func = R200_BLEND_GL_ONE;
|
||||
break;
|
||||
case GL_DST_COLOR:
|
||||
func = R200_BLEND_GL_DST_COLOR;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR:
|
||||
func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
|
||||
break;
|
||||
case GL_SRC_COLOR:
|
||||
func = R200_BLEND_GL_SRC_COLOR;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR:
|
||||
func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
func = R200_BLEND_GL_SRC_ALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
func = R200_BLEND_GL_DST_ALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
|
||||
break;
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
func =
|
||||
(is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE :
|
||||
R200_BLEND_GL_ZERO;
|
||||
break;
|
||||
case GL_CONSTANT_COLOR:
|
||||
func = R200_BLEND_GL_CONST_COLOR;
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
|
||||
break;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
func = R200_BLEND_GL_CONST_ALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
|
||||
break;
|
||||
default:
|
||||
func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets both the blend equation and the blend function.
|
||||
* This is done in a single
|
||||
* function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
|
||||
* change the interpretation of the blend function.
|
||||
* Also, make sure that blend function and blend equation are set to their default
|
||||
* value if color blending is not enabled, since at least blend equations GL_MIN
|
||||
* and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
|
||||
* unknown reasons.
|
||||
*/
|
||||
static void r300_set_blend_state(GLcontext * ctx)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
#if 0
|
||||
GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
|
||||
~(R300_ROP_ENABLE | R300_ALPHA_BLEND_ENABLE |
|
||||
R300_SEPARATE_ALPHA_ENABLE);
|
||||
#endif
|
||||
|
||||
int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
|
||||
int eqn = R200_COMB_FCN_ADD_CLAMP;
|
||||
int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
|
||||
int eqnA = R200_COMB_FCN_ADD_CLAMP;
|
||||
|
||||
R300_STATECHANGE(rmesa, bld);
|
||||
|
||||
if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
|
||||
if (ctx->Color._LogicOpEnabled) {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
|
||||
cntl | R300_ROP_ENABLE;
|
||||
#endif
|
||||
rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
|
||||
rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
|
||||
return;
|
||||
} else if (ctx->Color.BlendEnabled) {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
|
||||
cntl | R300_ALPHA_BLEND_ENABLE |
|
||||
R300_SEPARATE_ALPHA_ENABLE;
|
||||
#endif
|
||||
} else {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
|
||||
#endif
|
||||
rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
|
||||
rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (ctx->Color._LogicOpEnabled) {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
|
||||
cntl | R300_ROP_ENABLE;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
|
||||
#endif
|
||||
return;
|
||||
} else if (ctx->Color.BlendEnabled) {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
|
||||
cntl | R300_ALPHA_BLEND_ENABLE;
|
||||
#endif
|
||||
} else {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
func =
|
||||
(blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
|
||||
R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
|
||||
GL_FALSE) <<
|
||||
R200_DST_BLEND_SHIFT);
|
||||
|
||||
switch (ctx->Color.BlendEquationRGB) {
|
||||
case GL_FUNC_ADD:
|
||||
eqn = R300_COMB_FCN_ADD_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_FUNC_SUBTRACT:
|
||||
eqn = R300_COMB_FCN_SUB_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
eqn = R200_COMB_FCN_RSUB_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_MIN:
|
||||
eqn = R200_COMB_FCN_MIN;
|
||||
func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
|
||||
break;
|
||||
|
||||
case GL_MAX:
|
||||
eqn = R200_COMB_FCN_MAX;
|
||||
func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"[%s:%u] Invalid RGB blend equation (0x%04x).\n",
|
||||
__func__, __LINE__, ctx->Color.BlendEquationRGB);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
|
||||
#if 0
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
funcA =
|
||||
(blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
|
||||
R200_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
|
||||
GL_FALSE) <<
|
||||
R200_DST_BLEND_SHIFT);
|
||||
|
||||
switch (ctx->Color.BlendEquationA) {
|
||||
case GL_FUNC_ADD:
|
||||
eqnA = R300_COMB_FCN_ADD_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_FUNC_SUBTRACT:
|
||||
eqnA = R300_COMB_FCN_SUB_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
eqnA = R200_COMB_FCN_RSUB_CLAMP;
|
||||
break;
|
||||
|
||||
case GL_MIN:
|
||||
eqnA = R200_COMB_FCN_MIN;
|
||||
funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
|
||||
break;
|
||||
|
||||
case GL_MAX:
|
||||
eqnA = R200_COMB_FCN_MAX;
|
||||
funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
|
||||
(R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
|
||||
__func__, __LINE__, ctx->Color.BlendEquationA);
|
||||
return;
|
||||
}
|
||||
|
||||
rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqnA | funcA;
|
||||
rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func ;
|
||||
if(rmesa->hw.bld.cmd[R300_BLD_ABLEND] == rmesa->hw.bld.cmd[R300_BLD_CBLEND]){
|
||||
rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE | R300_BLEND_NO_SEPARATE;
|
||||
} else {
|
||||
rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void r300BlendEquationSeparate(GLcontext * ctx,
|
||||
GLenum modeRGB, GLenum modeA)
|
||||
{
|
||||
r300_set_blend_state(ctx);
|
||||
}
|
||||
|
||||
static void r300BlendFuncSeparate(GLcontext * ctx,
|
||||
GLenum sfactorRGB, GLenum dfactorRGB,
|
||||
GLenum sfactorA, GLenum dfactorA)
|
||||
{
|
||||
r300_set_blend_state(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update our tracked culling state based on Mesa's state.
|
||||
@@ -225,6 +534,395 @@ static void r300ColorMask(GLcontext* ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
* Point state
|
||||
*/
|
||||
static void r300PointSize(GLcontext * ctx, GLfloat size)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
/* This might need fixing later */
|
||||
R300_STATECHANGE(r300, vps);
|
||||
r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
* Window position and viewport transformation
|
||||
*/
|
||||
|
||||
/*
|
||||
* To correctly position primitives:
|
||||
*/
|
||||
#define SUBPIXEL_X 0.125
|
||||
#define SUBPIXEL_Y 0.125
|
||||
|
||||
void r300UpdateWindow(GLcontext * ctx)
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
|
||||
GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
|
||||
GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
|
||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||
|
||||
GLfloat sx = v[MAT_SX];
|
||||
GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
|
||||
GLfloat sy = -v[MAT_SY];
|
||||
GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
|
||||
GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
|
||||
GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
|
||||
|
||||
R300_FIREVERTICES(rmesa);
|
||||
R300_STATECHANGE(rmesa, vpt);
|
||||
|
||||
rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);
|
||||
rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
|
||||
rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);
|
||||
rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
|
||||
rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);
|
||||
rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);
|
||||
}
|
||||
|
||||
static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height)
|
||||
{
|
||||
/* Don't pipeline viewport changes, conflict with window offset
|
||||
* setting below. Could apply deltas to rescue pipelined viewport
|
||||
* values, or keep the originals hanging around.
|
||||
*/
|
||||
R200_FIREVERTICES(R200_CONTEXT(ctx));
|
||||
r300UpdateWindow(ctx);
|
||||
}
|
||||
|
||||
static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
|
||||
{
|
||||
r300UpdateWindow(ctx);
|
||||
}
|
||||
|
||||
/* Routing and texture-related */
|
||||
|
||||
void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
|
||||
{
|
||||
int i, count=0,reg=0;
|
||||
GLuint dw, mask;
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
|
||||
/* Stage 1 - input to VAP */
|
||||
|
||||
/* Assign register number automatically, retaining it in rmesa->state.reg */
|
||||
|
||||
/* Note: immediate vertex data includes all coordinates.
|
||||
To save bandwidth use either VBUF or state-based vertex generation */
|
||||
|
||||
#define CONFIGURE_AOS(v, o, r, f) \
|
||||
{\
|
||||
if(immediate){ \
|
||||
r300->state.aos[count].element_size=4; \
|
||||
r300->state.aos[count].stride=4; \
|
||||
r300->state.aos[count].ncomponents=4; \
|
||||
} else { \
|
||||
r300->state.aos[count].element_size=v->size; \
|
||||
r300->state.aos[count].stride=v->size; \
|
||||
r300->state.aos[count].ncomponents=v->size; \
|
||||
} \
|
||||
r300->state.aos[count].offset=o; \
|
||||
r300->state.aos[count].reg=reg; \
|
||||
r300->state.aos[count].format=(f); \
|
||||
r300->state.vap_reg.r=reg; \
|
||||
count++; \
|
||||
reg++; \
|
||||
}
|
||||
|
||||
/* All offsets are 0 - for use by immediate mode.
|
||||
Should change later to handle vertex buffers */
|
||||
CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
|
||||
CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
|
||||
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
|
||||
if(ctx->Texture.Unit[i].Enabled)
|
||||
CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
|
||||
|
||||
r300->state.aos_count=count;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "aos_count=%d\n", count);
|
||||
|
||||
if(count>R300_MAX_AOS_ARRAYS){
|
||||
fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Implement AOS */
|
||||
|
||||
/* setup INPUT_ROUTE */
|
||||
R300_STATECHANGE(r300, vir[0]);
|
||||
for(i=0;i+1<count;i+=2){
|
||||
dw=(r300->state.aos[i].ncomponents-1)
|
||||
| ((r300->state.aos[i].reg)<<8)
|
||||
| (r300->state.aos[i].format<<14)
|
||||
| (((r300->state.aos[i+1].ncomponents-1)
|
||||
| ((r300->state.aos[i+1].reg)<<8)
|
||||
| (r300->state.aos[i+1].format<<14))<<16);
|
||||
|
||||
if(i+2==count){
|
||||
dw|=(1<<(13+16));
|
||||
}
|
||||
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
|
||||
}
|
||||
if(count & 1){
|
||||
dw=(r300->state.aos[count-1].ncomponents-1)
|
||||
| (r300->state.aos[count-1].format<<14)
|
||||
| ((r300->state.aos[count-1].reg)<<8)
|
||||
| (1<<13);
|
||||
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
|
||||
//fprintf(stderr, "vir0 dw=%08x\n", dw);
|
||||
}
|
||||
/* Set the rest of INPUT_ROUTE_0 to 0 */
|
||||
//for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1;
|
||||
|
||||
|
||||
/* Mesa assumes that all missing components are from (0, 0, 0, 1) */
|
||||
#define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
|
||||
|
||||
#define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
|
||||
| (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
|
||||
|
||||
R300_STATECHANGE(r300, vir[1]);
|
||||
|
||||
for(i=0;i+1<count;i+=2){
|
||||
/* do i first.. */
|
||||
mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
|
||||
dw=(ALL_COMPONENTS & mask)
|
||||
| (ALL_DEFAULT & ~mask)
|
||||
| R300_INPUT_ROUTE_ENABLE;
|
||||
|
||||
/* i+1 */
|
||||
mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
|
||||
dw|=(
|
||||
(ALL_COMPONENTS & mask)
|
||||
| (ALL_DEFAULT & ~mask)
|
||||
| R300_INPUT_ROUTE_ENABLE
|
||||
)<<16;
|
||||
|
||||
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
|
||||
}
|
||||
if(count & 1){
|
||||
mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
|
||||
dw=(ALL_COMPONENTS & mask)
|
||||
| (ALL_DEFAULT & ~mask)
|
||||
| R300_INPUT_ROUTE_ENABLE;
|
||||
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=dw;
|
||||
//fprintf(stderr, "vir1 dw=%08x\n", dw);
|
||||
}
|
||||
/* Set the rest of INPUT_ROUTE_1 to 0 */
|
||||
//for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1;
|
||||
|
||||
/* Set up input_cntl */
|
||||
|
||||
R300_STATECHANGE(r300, vic);
|
||||
r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
|
||||
|
||||
r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
|
||||
| R300_INPUT_CNTL_COLOR;
|
||||
|
||||
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
|
||||
if(ctx->Texture.Unit[i].Enabled)
|
||||
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
|
||||
|
||||
/* Stage 3: VAP output */
|
||||
R300_STATECHANGE(r300, vof);
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
|
||||
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
|
||||
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
|
||||
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
|
||||
if(ctx->Texture.Unit[i].Enabled)
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
|
||||
|
||||
}
|
||||
|
||||
static r300TexObj default_tex_obj={
|
||||
filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
|
||||
pitch: 0x8000,
|
||||
size: (0xff << R300_TX_WIDTHMASK_SHIFT)
|
||||
| (0xff << R300_TX_HEIGHTMASK_SHIFT)
|
||||
| (0x8 << R300_TX_SIZE_SHIFT),
|
||||
format: 0x88a0c,
|
||||
offset: 0x0,
|
||||
unknown4: 0x0,
|
||||
unknown5: 0x0
|
||||
};
|
||||
|
||||
/* there is probably a system to these value, but, for now,
|
||||
we just try by hand */
|
||||
static GLuint translate_texture_format(GLuint format)
|
||||
{
|
||||
switch(format){
|
||||
case 0x88047:
|
||||
case 0x55047:
|
||||
return 0x53a0c;
|
||||
default:
|
||||
{
|
||||
static int warn_once=1;
|
||||
if(warn_once){
|
||||
fprintf(stderr, "%s:%s Do not know how to translate texture format %08x - help me !\n",
|
||||
__FILE__, __FUNCTION__,
|
||||
format);
|
||||
warn_once=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void r300_setup_textures(GLcontext *ctx)
|
||||
{
|
||||
int i, mtu;
|
||||
struct r300_tex_obj *t;
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
|
||||
|
||||
R300_STATECHANGE(r300, txe);
|
||||
R300_STATECHANGE(r300, tex.filter);
|
||||
R300_STATECHANGE(r300, tex.unknown1);
|
||||
R300_STATECHANGE(r300, tex.size);
|
||||
R300_STATECHANGE(r300, tex.format);
|
||||
R300_STATECHANGE(r300, tex.offset);
|
||||
R300_STATECHANGE(r300, tex.unknown4);
|
||||
R300_STATECHANGE(r300, tex.unknown5);
|
||||
|
||||
r300->state.texture.tc_count=0;
|
||||
|
||||
r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
|
||||
|
||||
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "mtu=%d\n", mtu);
|
||||
|
||||
if(mtu>R300_MAX_TEXTURE_UNITS){
|
||||
fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
|
||||
mtu, R300_MAX_TEXTURE_UNITS);
|
||||
exit(-1);
|
||||
}
|
||||
for(i=0;i<mtu;i++){
|
||||
if(ctx->Texture.Unit[i].Enabled){
|
||||
t=r300->state.texture.unit[i].texobj;
|
||||
r300->state.texture.tc_count++;
|
||||
if(t==NULL){
|
||||
fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
|
||||
//exit(-1);
|
||||
t=&default_tex_obj;
|
||||
}
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "Activating texture unit %d\n", i);
|
||||
max_texture_unit=i;
|
||||
r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
|
||||
|
||||
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter;
|
||||
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=t->pitch;
|
||||
r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
|
||||
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
|
||||
r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
|
||||
r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
|
||||
r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
|
||||
|
||||
|
||||
/* We don't know how to set this yet */
|
||||
//value from r300_lib.c for RGB24
|
||||
//r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c;
|
||||
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=translate_texture_format(t->format);
|
||||
/* Use the code below to quickly find matching texture
|
||||
formats. Requires an app that displays the same texture
|
||||
repeatedly */
|
||||
#if 1
|
||||
if(r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]==0){
|
||||
static int fmt=0;
|
||||
static int k=0;
|
||||
k++;
|
||||
if(k>200){
|
||||
k=0;
|
||||
fmt++;
|
||||
fprintf(stderr, "Want to set format %08x\n", t->format);
|
||||
if(fmt>0xff){
|
||||
//exit(-1);
|
||||
fmt=0;
|
||||
}
|
||||
//sleep(1);
|
||||
fprintf(stderr, "Instead trying format %08x\n",
|
||||
0x00a0c | (fmt<<12));
|
||||
}
|
||||
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x00a0c | (fmt<<12);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
|
||||
}
|
||||
|
||||
void r300_setup_rs_unit(GLcontext *ctx)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
/* This needs to be rewritten - it is a hack at best */
|
||||
|
||||
R300_STATECHANGE(r300, ri);
|
||||
R300_STATECHANGE(r300, rc);
|
||||
R300_STATECHANGE(r300, rr);
|
||||
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.ri.cmd[i] = 0x00d10000;
|
||||
r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
|
||||
r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
|
||||
r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
|
||||
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.rr.cmd[i] = 0;
|
||||
/* textures enabled ? */
|
||||
if(r300->state.texture.tc_count>0){
|
||||
|
||||
/* This code only really works with one set of texture coordinates */
|
||||
|
||||
/* The second constant is needed to get glxgears display anything .. */
|
||||
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
|
||||
| R300_RS_CNTL_0_UNKNOWN_18
|
||||
| (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
|
||||
r300->hw.rc.cmd[2] = 0xc0;
|
||||
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
|
||||
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
|
||||
|
||||
} else {
|
||||
|
||||
/* The second constant is needed to get glxgears display anything .. */
|
||||
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
|
||||
r300->hw.rc.cmd[2] = 0;
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
|
||||
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Mesa after an internal state update.
|
||||
@@ -255,26 +953,8 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
||||
GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
|
||||
GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
|
||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||
|
||||
r300->hw.vpt.cmd[R300_VPT_XSCALE] =
|
||||
r300PackFloat32(v[MAT_SX]);
|
||||
r300->hw.vpt.cmd[R300_VPT_XOFFSET] =
|
||||
r300PackFloat32(v[MAT_TX] + xoffset);
|
||||
r300->hw.vpt.cmd[R300_VPT_YSCALE] =
|
||||
r300PackFloat32(-v[MAT_SY]);
|
||||
r300->hw.vpt.cmd[R300_VPT_YOFFSET] =
|
||||
r300PackFloat32(-v[MAT_TY] + yoffset);
|
||||
r300->hw.vpt.cmd[R300_VPT_ZSCALE] =
|
||||
r300PackFloat32(v[MAT_SZ]);
|
||||
r300->hw.vpt.cmd[R300_VPT_ZOFFSET] =
|
||||
r300PackFloat32(v[MAT_TZ]);
|
||||
}
|
||||
|
||||
r300UpdateWindow(ctx);
|
||||
|
||||
r300ColorMask(ctx,
|
||||
ctx->Color.ColorMask[RCOMP],
|
||||
ctx->Color.ColorMask[GCOMP],
|
||||
@@ -286,6 +966,16 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
r300DepthFunc(ctx, ctx->Depth.Func);
|
||||
|
||||
r300UpdateCulling(ctx);
|
||||
|
||||
r300_setup_routing(ctx, GL_TRUE);
|
||||
|
||||
r300UpdateTextureState(ctx);
|
||||
r300_setup_textures(ctx);
|
||||
r300_setup_rs_unit(ctx);
|
||||
|
||||
|
||||
r300_set_blend_state(ctx);
|
||||
r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
|
||||
|
||||
//BEGIN: TODO
|
||||
r300->hw.unk2080.cmd[1] = 0x0030045A;
|
||||
@@ -293,14 +983,21 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
|
||||
r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
|
||||
|
||||
r300->hw.unk20B0.cmd[1] = 0x0000040A;
|
||||
r300->hw.unk20B0.cmd[2] = 0x00000008;
|
||||
r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
|
||||
| R300_VPORT_X_OFFSET_ENA
|
||||
| R300_VPORT_Y_SCALE_ENA
|
||||
| R300_VPORT_Y_OFFSET_ENA
|
||||
| R300_VPORT_Z_SCALE_ENA
|
||||
| R300_VPORT_Z_OFFSET_ENA
|
||||
| R300_VTX_W0_FMT;
|
||||
r300->hw.vte.cmd[2] = 0x00000008;
|
||||
|
||||
r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
|
||||
r300->hw.unk2134.cmd[2] = 0x00000000;
|
||||
|
||||
r300->hw.unk2140.cmd[1] = 0x00000000;
|
||||
|
||||
#if 0 /* Done in setup routing */
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
|
||||
r300->hw.vir[0].cmd[1] = 0x21030003;
|
||||
|
||||
@@ -309,7 +1006,8 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
|
||||
|
||||
#endif
|
||||
|
||||
r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
|
||||
|
||||
r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
|
||||
@@ -324,22 +1022,34 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
else
|
||||
r300->hw.unk2288.cmd[1] = R300_2288_RV350;
|
||||
|
||||
#if 0
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
|
||||
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
|
||||
r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
|
||||
#endif
|
||||
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
|
||||
|
||||
r300->hw.unk4008.cmd[1] = 0x00000007;
|
||||
r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
|
||||
| R300_GB_LINE_STUFF_ENABLE
|
||||
| R300_GB_TRIANGLE_STUFF_ENABLE;
|
||||
|
||||
r300->hw.unk4010.cmd[1] = 0x66666666;
|
||||
r300->hw.unk4010.cmd[2] = 0x06666666;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
|
||||
if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
|
||||
r300->hw.unk4010.cmd[3] = 0x00000017;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
|
||||
| R300_GB_TILE_PIPE_COUNT_R300
|
||||
| R300_GB_TILE_SIZE_16;
|
||||
else
|
||||
r300->hw.unk4010.cmd[3] = 0x00000011;
|
||||
r300->hw.unk4010.cmd[4] = 0x00000000;
|
||||
r300->hw.unk4010.cmd[5] = 0x00000000;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
|
||||
| R300_GB_TILE_PIPE_COUNT_RV300
|
||||
| R300_GB_TILE_SIZE_16;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
|
||||
r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
|
||||
|
||||
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
|
||||
//r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
|
||||
|
||||
r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
|
||||
r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
|
||||
@@ -377,15 +1087,6 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
|
||||
r300->hw.unk42C0.cmd[2] = 0x00000000;
|
||||
|
||||
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7;
|
||||
r300->hw.rc.cmd[2] = 0;
|
||||
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.ri.cmd[i] = 0;
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.rr.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk43A4.cmd[1] = 0x0000001C;
|
||||
r300->hw.unk43A4.cmd[2] = 0x2DA49525;
|
||||
@@ -420,14 +1121,18 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
r300->hw.unk4BC8.cmd[2] = 0;
|
||||
r300->hw.unk4BC8.cmd[3] = 0;
|
||||
|
||||
#if 0
|
||||
r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
|
||||
#endif
|
||||
|
||||
r300->hw.unk4BD8.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4E00.cmd[1] = 0;
|
||||
|
||||
#if 0
|
||||
r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
|
||||
r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
|
||||
#endif
|
||||
|
||||
r300->hw.unk4E10.cmd[1] = 0;
|
||||
r300->hw.unk4E10.cmd[2] = 0;
|
||||
@@ -451,6 +1156,9 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
|
||||
r300->hw.unk4E88.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4EA0.cmd[1] = 0x00000000;
|
||||
r300->hw.unk4EA0.cmd[2] = 0xffffffff;
|
||||
|
||||
r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
|
||||
|
||||
r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format?
|
||||
@@ -489,8 +1197,9 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
|
||||
r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
|
||||
r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
|
||||
|
||||
//END: TODO
|
||||
|
||||
|
||||
r300->hw.all_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
@@ -503,12 +1212,35 @@ void r300ResetHwState(r300ContextPtr r300)
|
||||
*/
|
||||
void r300InitState(r300ContextPtr r300)
|
||||
{
|
||||
GLcontext *ctx = r300->radeon.glCtx;
|
||||
GLuint depth_fmt;
|
||||
|
||||
radeonInitState(&r300->radeon);
|
||||
|
||||
switch (ctx->Visual.depthBits) {
|
||||
case 16:
|
||||
r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
|
||||
depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
|
||||
//r300->state.stencil.clear = 0x00000000;
|
||||
break;
|
||||
case 24:
|
||||
r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
|
||||
depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
|
||||
//r300->state.stencil.clear = 0xff000000;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
|
||||
ctx->Visual.depthBits);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
|
||||
|
||||
r300ResetHwState(r300);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize driver's state callback functions
|
||||
*/
|
||||
@@ -517,11 +1249,20 @@ void r300InitStateFuncs(struct dd_function_table* functions)
|
||||
radeonInitStateFuncs(functions);
|
||||
|
||||
functions->UpdateState = r300InvalidateState;
|
||||
//functions->AlphaFunc = r300AlphaFunc;
|
||||
functions->BlendColor = r300BlendColor;
|
||||
functions->BlendEquationSeparate = r300BlendEquationSeparate;
|
||||
functions->BlendFuncSeparate = r300BlendFuncSeparate;
|
||||
functions->Enable = r300Enable;
|
||||
functions->ColorMask = r300ColorMask;
|
||||
functions->DepthFunc = r300DepthFunc;
|
||||
functions->DepthMask = r300DepthMask;
|
||||
functions->CullFace = r300CullFace;
|
||||
functions->FrontFace = r300FrontFace;
|
||||
|
||||
/* Viewport related */
|
||||
functions->Viewport = r300Viewport;
|
||||
functions->DepthRange = r300DepthRange;
|
||||
functions->PointSize = r300PointSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
r300->hw.is_dirty = GL_TRUE; \
|
||||
} while(0)
|
||||
|
||||
/* Fire the buffered vertices no matter what.
|
||||
TODO: This has not been implemented yet
|
||||
*/
|
||||
#define R300_FIREVERTICES( r300 ) \
|
||||
do { \
|
||||
/* \
|
||||
if ( (r300)->store.cmd_used || (r300)->dma.flush ) { \
|
||||
radeonFlush( (r300)->radeon.glCtx ); \
|
||||
} \
|
||||
*/ \
|
||||
} while (0)
|
||||
|
||||
|
||||
extern void r300ResetHwState(r300ContextPtr r300);
|
||||
|
||||
extern void r300InitState(r300ContextPtr r300);
|
||||
|
||||
1045
src/mesa/drivers/dri/r300/r300_tex.c
Normal file
1045
src/mesa/drivers/dri/r300/r300_tex.c
Normal file
File diff suppressed because it is too large
Load Diff
53
src/mesa/drivers/dri/r300/r300_tex.h
Normal file
53
src/mesa/drivers/dri/r300/r300_tex.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_tex.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
|
||||
/*
|
||||
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 __r300_TEX_H__
|
||||
#define __r300_TEX_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r300UpdateTextureState(GLcontext * ctx);
|
||||
|
||||
extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t,
|
||||
GLuint face);
|
||||
|
||||
extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t);
|
||||
|
||||
extern void r300InitTextureFuncs(struct dd_function_table *functions);
|
||||
|
||||
extern void r300UpdateTextureState(GLcontext * ctx);
|
||||
|
||||
#endif
|
||||
#endif /* __r300_TEX_H__ */
|
||||
490
src/mesa/drivers/dri/r300/r300_texmem.c
Normal file
490
src/mesa/drivers/dri/r300/r300_texmem.c
Normal file
@@ -0,0 +1,490 @@
|
||||
/* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texmem.c,v 1.5 2002/12/17 00:32:56 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
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 "r300_context.h"
|
||||
#include "r300_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
/*
|
||||
#include "r300_swtcl.h"
|
||||
*/
|
||||
#include "r300_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 r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t)
|
||||
{
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE) {
|
||||
fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
|
||||
(void *)t, (void *)t->base.tObj);
|
||||
}
|
||||
|
||||
if (rmesa != NULL) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) {
|
||||
if (t == rmesa->state.texture.unit[i].texobj) {
|
||||
rmesa->state.texture.unit[i].texobj = NULL;
|
||||
/* This code below is meant to shorten state
|
||||
pushed to the hardware by not programming
|
||||
unneeded units.
|
||||
|
||||
This does not appear to be worthwhile on R300 */
|
||||
#if 0
|
||||
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]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Texture image conversions
|
||||
*/
|
||||
|
||||
static void r300UploadGARTClientSubImage(r300ContextPtr rmesa,
|
||||
r300TexObjPtr 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 = r300GartOffsetFromVirtual(rmesa, texImage->Data);
|
||||
|
||||
assert(srcOffset != ~0);
|
||||
|
||||
/* Don't currently need to cope with small pitches?
|
||||
*/
|
||||
width = texImage->Width;
|
||||
height = texImage->Height;
|
||||
|
||||
r300EmitWait(rmesa, RADEON_WAIT_3D);
|
||||
|
||||
r300EmitBlit(rmesa, blit_format,
|
||||
srcPitch,
|
||||
srcOffset,
|
||||
dstPitch,
|
||||
t->bufAddr,
|
||||
x,
|
||||
y,
|
||||
t->image[0][hwlevel].x + x,
|
||||
t->image[0][hwlevel].y + y, width, height);
|
||||
|
||||
r300EmitWait(rmesa, RADEON_WAIT_2D);
|
||||
}
|
||||
|
||||
static void r300UploadRectSubImage(r300ContextPtr rmesa,
|
||||
r300TexObjPtr 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->pitch + 32;
|
||||
|
||||
if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
|
||||
/* In this case, could also use GART texturing. This is
|
||||
* currently disabled, but has been tested & works.
|
||||
*/
|
||||
t->offset =
|
||||
r300GartOffsetFromVirtual(rmesa, texImage->Data);
|
||||
t->pitch =
|
||||
texImage->RowStride * texFormat->TexelBytes - 32;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"Using GART 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 GART memory, with usable pitch.
|
||||
*/
|
||||
GLuint srcPitch;
|
||||
srcPitch = texImage->RowStride * texFormat->TexelBytes;
|
||||
r300EmitBlit(rmesa,
|
||||
blit_format,
|
||||
srcPitch,
|
||||
r300GartOffsetFromVirtual(rmesa, texImage->Data),
|
||||
dstPitch, t->bufAddr, 0, 0, 0, 0, width, height);
|
||||
} else {
|
||||
/* Data not in GART memory, or bad pitch.
|
||||
*/
|
||||
for (done = 0; done < height;) {
|
||||
struct r300_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));
|
||||
r300AllocDmaRegion(rmesa, ®ion, lines * dstPitch,
|
||||
1024);
|
||||
|
||||
/* 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 + region.start, tex,
|
||||
lines * src_pitch);
|
||||
} else {
|
||||
char *buf = region.address + region.start;
|
||||
int i;
|
||||
for (i = 0; i < lines; i++) {
|
||||
memcpy(buf, tex, src_pitch);
|
||||
buf += dstPitch;
|
||||
tex += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
r300EmitWait(rmesa, RADEON_WAIT_3D);
|
||||
|
||||
/* Blit to framebuffer
|
||||
*/
|
||||
r300EmitBlit(rmesa,
|
||||
blit_format,
|
||||
dstPitch, GET_START(®ion),
|
||||
dstPitch, t->bufAddr,
|
||||
0, 0, 0, done, width, lines);
|
||||
|
||||
r300EmitWait(rmesa, RADEON_WAIT_2D);
|
||||
|
||||
r300ReleaseDmaRegion(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(r300ContextPtr rmesa, r300TexObjPtr 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;
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
const int level = hwlevel + t->base.firstLevel;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE) {
|
||||
fprintf(stderr,
|
||||
"%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
||||
__FUNCTION__, (void *)t, (void *)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;
|
||||
}
|
||||
|
||||
texImage = t->base.tObj->Image[face][level];
|
||||
|
||||
if (!texImage) {
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: texImage %d is NULL!\n",
|
||||
__FUNCTION__, level);
|
||||
return;
|
||||
}
|
||||
if (!texImage->Data) {
|
||||
if (RADEON_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 (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: image data is rectangular\n",
|
||||
__FUNCTION__);
|
||||
r300UploadRectSubImage(rmesa, t, texImage, x, y, width, height);
|
||||
return;
|
||||
} else if (texImage->IsClientData) {
|
||||
if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"%s: image data is in GART client storage\n",
|
||||
__FUNCTION__);
|
||||
r300UploadGARTClientSubImage(rmesa, t, texImage, hwlevel, x, y,
|
||||
width, height);
|
||||
return;
|
||||
} else if (RADEON_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr, "%s: image data is in normal memory\n",
|
||||
__FUNCTION__);
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr;
|
||||
|
||||
if (RADEON_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 / drm_radeon_texture_t 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(tmp));
|
||||
|
||||
LOCK_HARDWARE(&rmesa->radeon);
|
||||
do {
|
||||
ret = drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drm_radeon_texture_t));
|
||||
if (ret) {
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr,
|
||||
"DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while (ret && errno == EAGAIN);
|
||||
|
||||
UNLOCK_HARDWARE(&rmesa->radeon);
|
||||
|
||||
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 r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
|
||||
{
|
||||
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
|
||||
fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
||||
(void *)rmesa->radeon.glCtx, (void *)t->base.tObj,
|
||||
t->base.totalSize, t->base.firstLevel,
|
||||
t->base.lastLevel);
|
||||
}
|
||||
|
||||
if (!t || t->base.totalSize == 0)
|
||||
return 0;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
|
||||
radeonFinish(rmesa->radeon.glCtx);
|
||||
}
|
||||
|
||||
LOCK_HARDWARE(&rmesa->radeon);
|
||||
|
||||
if (t->base.memBlock == NULL) {
|
||||
int heap;
|
||||
|
||||
heap = driAllocateTexture(rmesa->texture_heaps, rmesa->nr_heaps,
|
||||
(driTextureObject *) t);
|
||||
if (heap == -1) {
|
||||
UNLOCK_HARDWARE(&rmesa->radeon);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the base offset of the texture image */
|
||||
t->bufAddr = rmesa->radeon.radeonScreen->texOffset[heap]
|
||||
+ t->base.memBlock->ofs;
|
||||
t->offset = 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->radeon);
|
||||
|
||||
/* 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 (RADEON_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
|
||||
radeonFinish(rmesa->radeon.glCtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1389
src/mesa/drivers/dri/r300/r300_texstate.c
Normal file
1389
src/mesa/drivers/dri/r300/r300_texstate.c
Normal file
File diff suppressed because it is too large
Load Diff
90
src/mesa/drivers/dri/r300/vertex_shader.h
Normal file
90
src/mesa/drivers/dri/r300/vertex_shader.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef __VERTEX_SHADER_H__
|
||||
#define __VERTEX_SHADER_H__
|
||||
|
||||
#include "r300_reg.h"
|
||||
|
||||
typedef struct {
|
||||
CARD32 op;
|
||||
CARD32 src1;
|
||||
CARD32 src2;
|
||||
CARD32 src3;
|
||||
} VERTEX_SHADER_INSTRUCTION;
|
||||
|
||||
#define VSF_FLAG_X 1
|
||||
#define VSF_FLAG_Y 2
|
||||
#define VSF_FLAG_Z 4
|
||||
#define VSF_FLAG_W 8
|
||||
#define VSF_FLAG_ALL 0xf
|
||||
#define VSF_FLAG_NONE 0
|
||||
|
||||
#define VSF_OUT_CLASS_TMP 0
|
||||
#define VSF_OUT_CLASS_RESULT 2
|
||||
|
||||
|
||||
/* first CARD32 of an instruction */
|
||||
|
||||
/* possible operations:
|
||||
DOT, MUL, ADD, MAD, FRC, MAX, MIN, SGE, SLT, EXP, LOG, LIT, POW, RCP, RSQ, EX2,
|
||||
LG2, MAD_2 */
|
||||
|
||||
#define MAKE_VSF_OP(op, out_reg_index, out_reg_fields, class) \
|
||||
((op) \
|
||||
| ((out_reg_index) << R300_VPI_OUT_REG_INDEX_SHIFT) \
|
||||
| ((out_reg_fields) << 20) \
|
||||
| ( (class) << 8 ) )
|
||||
|
||||
#define EASY_VSF_OP(op, out_reg_index, out_reg_fields, class) \
|
||||
MAKE_VSF_OP(R300_VPI_OUT_OP_##op, out_reg_index, VSF_FLAG_##out_reg_fields, VSF_OUT_CLASS_##class) \
|
||||
|
||||
/* according to Nikolai, the subsequent 3 CARD32 are sources, use same define for each */
|
||||
|
||||
#define VSF_IN_CLASS_TMP 0
|
||||
#define VSF_IN_CLASS_ATTR 1
|
||||
#define VSF_IN_CLASS_PARAM 2
|
||||
#define VSF_IN_CLASS_NONE 9
|
||||
|
||||
#define VSF_IN_COMPONENT_X 0
|
||||
#define VSF_IN_COMPONENT_Y 1
|
||||
#define VSF_IN_COMPONENT_Z 2
|
||||
#define VSF_IN_COMPONENT_W 3
|
||||
#define VSF_IN_COMPONENT_ZERO 4
|
||||
#define VSF_IN_COMPONENT_ONE 5
|
||||
|
||||
#define MAKE_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
|
||||
( ((in_reg_index)<<R300_VPI_IN_REG_INDEX_SHIFT) \
|
||||
| ((comp_x)<<R300_VPI_IN_X_SHIFT) \
|
||||
| ((comp_y)<<R300_VPI_IN_Y_SHIFT) \
|
||||
| ((comp_z)<<R300_VPI_IN_Z_SHIFT) \
|
||||
| ((comp_w)<<R300_VPI_IN_W_SHIFT) \
|
||||
| ((negate)<<25) | ((class)))
|
||||
|
||||
#define EASY_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
|
||||
MAKE_VSF_SOURCE(in_reg_index, \
|
||||
VSF_IN_COMPONENT_##comp_x, \
|
||||
VSF_IN_COMPONENT_##comp_y, \
|
||||
VSF_IN_COMPONENT_##comp_z, \
|
||||
VSF_IN_COMPONENT_##comp_w, \
|
||||
VSF_IN_CLASS_##class, VSF_FLAG_##negate)
|
||||
|
||||
/* special sources: */
|
||||
|
||||
/* (1.0,1.0,1.0,1.0) vector (ATTR, plain ) */
|
||||
#define VSF_ATTR_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, ATTR, NONE)
|
||||
#define VSF_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, NONE, NONE)
|
||||
|
||||
/* contents of unmodified register */
|
||||
#define VSF_REG(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, ATTR, NONE)
|
||||
|
||||
/* contents of unmodified parameter */
|
||||
#define VSF_PARAM(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, PARAM, NONE)
|
||||
|
||||
/* contents of unmodified temporary register */
|
||||
#define VSF_TMP(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, TMP, NONE)
|
||||
|
||||
/* components of ATTR register */
|
||||
#define VSF_ATTR_X(reg) EASY_VSF_SOURCE(reg, X, X, X, X, ATTR, NONE)
|
||||
#define VSF_ATTR_Y(reg) EASY_VSF_SOURCE(reg, Y, Y, Y, Y, ATTR, NONE)
|
||||
#define VSF_ATTR_Z(reg) EASY_VSF_SOURCE(reg, Z, Z, Z, Z, ATTR, NONE)
|
||||
#define VSF_ATTR_W(reg) EASY_VSF_SOURCE(reg, W, W, W, W, ATTR, NONE)
|
||||
|
||||
#endif
|
||||
46
src/mesa/drivers/dri/s3v/Makefile
Normal file
46
src/mesa/drivers/dri/s3v/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
# src/mesa/drivers/dri/s3v/Makefile
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = s3v_dri.so
|
||||
|
||||
# Doesn't exist yet.
|
||||
#MINIGLX_SOURCES = server/savage_dri.c
|
||||
|
||||
COMMON_SOURCES = \
|
||||
../../common/driverfuncs.c \
|
||||
../common/mm.c \
|
||||
../common/utils.c \
|
||||
../common/texmem.c \
|
||||
../common/vblank.c \
|
||||
../common/xmlconfig.c \
|
||||
../common/dri_util.c \
|
||||
../common/glcontextmodes.c
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
s3v_context.c \
|
||||
s3v_dd.c \
|
||||
s3v_inithw.c \
|
||||
s3v_lock.c \
|
||||
s3v_render.c \
|
||||
s3v_screen.c \
|
||||
s3v_span.c \
|
||||
s3v_state.c \
|
||||
s3v_tex.c \
|
||||
s3v_texmem.c \
|
||||
s3v_texstate.c \
|
||||
s3v_tris.c \
|
||||
s3v_vb.c \
|
||||
s3v_xmesa.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
symlinks:
|
||||
83
src/mesa/drivers/dri/s3v/s3v_common.h
Normal file
83
src/mesa/drivers/dri/s3v/s3v_common.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Author: Max Lingua <sunmax@libero.it>
|
||||
*/
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change
|
||||
* the kernel include file as well (s3v_drm.h)
|
||||
*/
|
||||
|
||||
#ifndef _XF86DRI_S3V_H_
|
||||
#define _XF86DRI_S3V_H_
|
||||
|
||||
#ifndef _S3V_DEFINES_
|
||||
#define _S3V_DEFINES_
|
||||
#define S3V_USE_BATCH 1
|
||||
|
||||
/* #define S3V_BUF_4K 1 */
|
||||
|
||||
#ifdef S3V_BUF_4K
|
||||
#define S3V_DMA_BUF_ORDER 12
|
||||
#define S3V_DMA_BUF_NR 256
|
||||
#else
|
||||
#define S3V_DMA_BUF_ORDER 16 /* -much- better */
|
||||
#define S3V_DMA_BUF_NR 16
|
||||
#endif
|
||||
/* on s3virge you can only choose between *
|
||||
* 4k (2^12) and 64k (2^16) dma bufs */
|
||||
#define S3V_DMA_BUF_SZ (1<<S3V_DMA_BUF_ORDER)
|
||||
|
||||
#define S3V_NR_SAREA_CLIPRECTS 8
|
||||
|
||||
/* Each region is a minimum of 16k (64*64@4bpp)
|
||||
* and there are at most 40 of them.
|
||||
*/
|
||||
#define S3V_NR_TEX_REGIONS 64 /* was 40 */
|
||||
#define S3V_LOG_TEX_GRANULARITY 16 /* was 4 */
|
||||
/* 40 * (2 ^ 4) = 640k, that's all we have for tex on 4mb gfx card */
|
||||
/* FIXME: will it work with card with less than 4mb? */
|
||||
/* FIXME: we should set this at run time */
|
||||
|
||||
#endif /* _S3V_DEFINES */
|
||||
|
||||
/*
|
||||
* WARNING: If you change any of these defines, make sure to change
|
||||
* the kernel include file as well (gamma_drm.h)
|
||||
*/
|
||||
|
||||
/* Driver specific DRM command indices
|
||||
* NOTE: these are not OS specific, but they are driver specific
|
||||
*/
|
||||
#define DRM_S3V_INIT_DMA 0x00
|
||||
#define DRM_S3V_CLEANUP_DMA 0x01
|
||||
|
||||
typedef struct _drmS3VInit {
|
||||
enum {
|
||||
S3V_INIT_DMA = 0x01,
|
||||
S3V_CLEANUP_DMA = 0x02
|
||||
} func;
|
||||
|
||||
unsigned int pcimode; /* bool: 1=pci 0=agp */
|
||||
|
||||
unsigned int mmio_offset;
|
||||
unsigned int buffers_offset;
|
||||
unsigned int sarea_priv_offset;
|
||||
|
||||
unsigned int front_offset;
|
||||
unsigned int front_width;
|
||||
unsigned int front_height;
|
||||
unsigned int front_pitch;
|
||||
|
||||
unsigned int back_offset;
|
||||
unsigned int back_width;
|
||||
unsigned int back_height;
|
||||
unsigned int back_pitch;
|
||||
|
||||
unsigned int depth_offset;
|
||||
unsigned int depth_width;
|
||||
unsigned int depth_height;
|
||||
unsigned int depth_pitch;
|
||||
|
||||
unsigned int texture_offset;
|
||||
} drmS3VInit;
|
||||
|
||||
#endif
|
||||
@@ -13,24 +13,22 @@
|
||||
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "mem.h"
|
||||
#include "matrix.h"
|
||||
#include "extensions.h"
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#include "x86/common_x86_asm.h"
|
||||
#endif
|
||||
#include "simple_list.h"
|
||||
#include "mem.h"
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "s3v_vb.h"
|
||||
#include "s3v_tris.h"
|
||||
|
||||
#if 0
|
||||
extern const struct gl_pipeline_stage _s3v_render_stage;
|
||||
extern const struct tnl_pipeline_stage _s3v_render_stage;
|
||||
|
||||
static const struct gl_pipeline_stage *s3v_pipeline[] = {
|
||||
static const struct tnl_pipeline_stage *s3v_pipeline[] = {
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
@@ -46,16 +44,17 @@ static const struct gl_pipeline_stage *s3v_pipeline[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
GLboolean s3vCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
GLboolean s3vCreateContext(const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
GLcontext *ctx, *shareCtx;
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
s3vContextPtr vmesa;
|
||||
s3vScreenPtr s3vScrn;
|
||||
S3VSAREAPtr saPriv=(S3VSAREAPtr)(((char*)sPriv->pSAREA)+
|
||||
sizeof(XF86DRISAREARec));
|
||||
S3VSAREAPtr saPriv=(S3VSAREAPtr)(((char*)sPriv->pSAREA) +
|
||||
sizeof(drm_sarea_t));
|
||||
struct dd_function_table functions;
|
||||
|
||||
DEBUG_WHERE(("*** s3vCreateContext ***\n"));
|
||||
|
||||
@@ -68,20 +67,21 @@ GLboolean s3vCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
else
|
||||
shareCtx = NULL;
|
||||
|
||||
vmesa->glCtx = _mesa_create_context(glVisual, shareCtx, vmesa, GL_TRUE);
|
||||
_mesa_init_driver_functions(&functions);
|
||||
|
||||
vmesa->glCtx = _mesa_create_context(glVisual, shareCtx, &functions,
|
||||
(void *)vmesa);
|
||||
if (!vmesa->glCtx) {
|
||||
FREE(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
vmesa->display = dpy;
|
||||
|
||||
vmesa->driContext = driContextPriv;
|
||||
vmesa->driScreen = sPriv;
|
||||
vmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
|
||||
|
||||
vmesa->hHWContext = driContextPriv->hHWContext;
|
||||
vmesa->driHwLock = &sPriv->pSAREA->lock;
|
||||
vmesa->driHwLock = (drmLock *)&sPriv->pSAREA->lock;
|
||||
vmesa->driFd = sPriv->fd;
|
||||
vmesa->sarea = saPriv;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "s3v_regs.h"
|
||||
#include "s3v_macros.h"
|
||||
#include "s3v_screen.h"
|
||||
#include "colormac.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "drm.h"
|
||||
@@ -32,8 +33,7 @@
|
||||
extern void s3vDDUpdateHWState(GLcontext *ctx);
|
||||
extern s3vScreenPtr s3vCreateScreen(__DRIscreenPrivate *sPriv);
|
||||
extern void s3vDestroyScreen(__DRIscreenPrivate *sPriv);
|
||||
extern GLboolean s3vCreateContext( Display *dpy,
|
||||
const __GLcontextModes *glVisual,
|
||||
extern GLboolean s3vCreateContext(const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate);
|
||||
|
||||
@@ -129,17 +129,17 @@ struct s3v_texture_object_t {
|
||||
int internalFormat;
|
||||
} image[S3V_TEX_MAXLEVELS];
|
||||
|
||||
CARD32 TextureCMD;
|
||||
GLuint TextureCMD;
|
||||
|
||||
CARD32 TextureColorMode;
|
||||
CARD32 TextureFilterMode;
|
||||
CARD32 TextureBorderColor;
|
||||
CARD32 TextureWrap;
|
||||
CARD32 TextureMipSize;
|
||||
GLuint TextureColorMode;
|
||||
GLuint TextureFilterMode;
|
||||
GLuint TextureBorderColor;
|
||||
GLuint TextureWrap;
|
||||
GLuint TextureMipSize;
|
||||
|
||||
CARD32 TextureBaseAddr[S3V_TEX_MAXLEVELS];
|
||||
CARD32 TextureFormat;
|
||||
CARD32 TextureReadMode;
|
||||
GLuint TextureBaseAddr[S3V_TEX_MAXLEVELS];
|
||||
GLuint TextureFormat;
|
||||
GLuint TextureReadMode;
|
||||
};
|
||||
|
||||
#define S3V_NO_PALETTE 0x0
|
||||
@@ -222,17 +222,16 @@ struct s3v_context {
|
||||
|
||||
/* Mirrors of some DRI state
|
||||
*/
|
||||
Display *display; /* X server display */
|
||||
|
||||
drmContext hHWContext;
|
||||
drm_context_t hHWContext;
|
||||
drmLock *driHwLock;
|
||||
int driFd;
|
||||
|
||||
GLuint numClipRects; /* Cliprects for the draw buffer */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
drm_clip_rect_t *pClipRects;
|
||||
|
||||
CARD32* buf; /* FIXME */
|
||||
CARD32* _buf[2];
|
||||
GLuint* buf; /* FIXME */
|
||||
GLuint* _buf[2];
|
||||
int _bufNum;
|
||||
int bufIndex[2];
|
||||
int bufSize;
|
||||
@@ -281,40 +280,40 @@ struct s3v_context {
|
||||
|
||||
unsigned int S3V_REG[S3V_REGS_NUM];
|
||||
|
||||
CARD32 texMode;
|
||||
CARD32 alphaMode;
|
||||
CARD32 lightMode;
|
||||
GLuint texMode;
|
||||
GLuint alphaMode;
|
||||
GLuint lightMode;
|
||||
|
||||
CARD32 SrcBase;
|
||||
CARD32 DestBase;
|
||||
CARD32 DestBlit;
|
||||
CARD32 ScissorLR;
|
||||
CARD32 ScissorTB;
|
||||
CARD32 ScissorWH; /* SubScissorWH */ /* RectWH */
|
||||
CARD32 FrontStride;
|
||||
CARD32 BackStride;
|
||||
CARD32 SrcStride;
|
||||
CARD32 DestStride;
|
||||
CARD32 SrcXY;
|
||||
CARD32 DestXY;
|
||||
GLuint SrcBase;
|
||||
GLuint DestBase;
|
||||
GLuint DestBlit;
|
||||
GLuint ScissorLR;
|
||||
GLuint ScissorTB;
|
||||
GLuint ScissorWH; /* SubScissorWH */ /* RectWH */
|
||||
GLuint FrontStride;
|
||||
GLuint BackStride;
|
||||
GLuint SrcStride;
|
||||
GLuint DestStride;
|
||||
GLuint SrcXY;
|
||||
GLuint DestXY;
|
||||
|
||||
CARD32 ClearColor;
|
||||
CARD32 Color;
|
||||
CARD32 DitherMode;
|
||||
CARD32 ClearDepth;
|
||||
GLuint ClearColor;
|
||||
GLuint Color;
|
||||
GLuint DitherMode;
|
||||
GLuint ClearDepth;
|
||||
|
||||
CARD32 TextureBorderColor;
|
||||
CARD32 TexOffset;
|
||||
CARD32 TexStride;
|
||||
GLuint TextureBorderColor;
|
||||
GLuint TexOffset;
|
||||
GLuint TexStride;
|
||||
|
||||
CARD32 CMD;
|
||||
CARD32 prim_cmd;
|
||||
CARD32 _tri[2]; /* 0 = gouraud; 1 = tex (lit or unlit) */
|
||||
CARD32 alpha_cmd; /* actual alpha cmd */
|
||||
CARD32 _alpha[2];
|
||||
CARD32 _alpha_tex; /* tex alpha type */
|
||||
GLuint CMD;
|
||||
GLuint prim_cmd;
|
||||
GLuint _tri[2]; /* 0 = gouraud; 1 = tex (lit or unlit) */
|
||||
GLuint alpha_cmd; /* actual alpha cmd */
|
||||
GLuint _alpha[2];
|
||||
GLuint _alpha_tex; /* tex alpha type */
|
||||
/* (3d_mode) 0 = 3d line/gourad tri; 1 = 3d tex tri */
|
||||
CARD32 _3d_mode;
|
||||
GLuint _3d_mode;
|
||||
|
||||
GLfloat backface_sign;
|
||||
GLfloat cull_zero;
|
||||
@@ -323,14 +322,14 @@ struct s3v_context {
|
||||
|
||||
/* *** 2check *** */
|
||||
|
||||
CARD32 FogMode;
|
||||
CARD32 AreaStippleMode;
|
||||
CARD32 LBReadFormat;
|
||||
CARD32 LBWriteFormat;
|
||||
CARD32 LineMode;
|
||||
CARD32 PointMode;
|
||||
CARD32 TriangleMode;
|
||||
CARD32 AntialiasMode;
|
||||
GLuint FogMode;
|
||||
GLuint AreaStippleMode;
|
||||
GLuint LBReadFormat;
|
||||
GLuint LBWriteFormat;
|
||||
GLuint LineMode;
|
||||
GLuint PointMode;
|
||||
GLuint TriangleMode;
|
||||
GLuint AntialiasMode;
|
||||
GLfloat ViewportScaleX;
|
||||
GLfloat ViewportScaleY;
|
||||
GLfloat ViewportScaleZ;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "s3v_vb.h"
|
||||
#include "s3v_lock.h"
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#include "x86/common_x86_asm.h"
|
||||
#endif
|
||||
|
||||
#include "context.h"
|
||||
|
||||
143
src/mesa/drivers/dri/s3v/s3v_dri.h
Normal file
143
src/mesa/drivers/dri/s3v/s3v_dri.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Author: Max Lingua <sunmax@libero.it>
|
||||
*/
|
||||
|
||||
#ifndef _S3V_DRI
|
||||
#define _S3V_DRI
|
||||
|
||||
#include "s3v_common.h"
|
||||
|
||||
#define S3V_MAX_DRAWABLES (S3V_DMA_BUF_NR/2) /* 32 */ /* 256 */ /* FIXME */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int deviceID;
|
||||
int width;
|
||||
int height;
|
||||
int mem;
|
||||
int cpp;
|
||||
int bitsPerPixel;
|
||||
|
||||
int fbOffset;
|
||||
int fbStride;
|
||||
|
||||
int logTextureGranularity;
|
||||
int textureOffset;
|
||||
|
||||
drm_handle_t regs;
|
||||
drmSize regsSize;
|
||||
|
||||
unsigned int sarea_priv_offset;
|
||||
/*
|
||||
drmAddress regsMap;
|
||||
|
||||
drmSize textureSize;
|
||||
drm_handle_t textures;
|
||||
*/
|
||||
|
||||
#if 0
|
||||
drm_handle_t agp_buffers;
|
||||
drmSize agp_buf_size;
|
||||
#endif
|
||||
|
||||
/*
|
||||
drmBufMapPtr drmBufs;
|
||||
int irq;
|
||||
unsigned int sarea_priv_offset;
|
||||
*/
|
||||
|
||||
/* FIXME: cleanup ! */
|
||||
|
||||
drmSize registerSize; /* == S3V_MMIO_REGSIZE */
|
||||
drm_handle_t registerHandle;
|
||||
|
||||
drmSize pciSize;
|
||||
drm_handle_t pciMemHandle;
|
||||
|
||||
drmSize frontSize; /* == videoRambytes */
|
||||
/* drm_handle_t frontHandle; */
|
||||
unsigned long frontOffset; /* == fbOffset */
|
||||
int frontPitch;
|
||||
/* unsigned char *front; */
|
||||
|
||||
unsigned int bufferSize; /* size of depth/back buffer */
|
||||
|
||||
drmSize backSize;
|
||||
/* drm_handle_t backHandle; */
|
||||
unsigned long backOffset;
|
||||
int backPitch;
|
||||
/* unsigned char *back; */
|
||||
|
||||
drmSize depthSize;
|
||||
/* drm_handle_t depthHandle; */
|
||||
unsigned long depthOffset;
|
||||
int depthPitch;
|
||||
/* unsigned char *depth; */
|
||||
|
||||
drmSize texSize;
|
||||
/* drm_handle_t texHandle; */
|
||||
unsigned long texOffset;
|
||||
int texPitch;
|
||||
/* unsigned char *tex; */
|
||||
|
||||
drmSize dmaBufSize; /* Size of buffers (in bytes) */
|
||||
drm_handle_t dmaBufHandle; /* Handle from drmAddMap */
|
||||
unsigned long dmaBufOffset; /* Offset/Start */
|
||||
int dmaBufPitch; /* Pitch */
|
||||
unsigned char *dmaBuf; /* Map */
|
||||
int bufNumBufs; /* Number of buffers */
|
||||
drmBufMapPtr buffers; /* Buffer map */
|
||||
|
||||
} S3VDRIRec, *S3VDRIPtr;
|
||||
|
||||
/* WARNING: Do not change the SAREA structure without changing the kernel
|
||||
* as well */
|
||||
|
||||
typedef struct {
|
||||
unsigned char next, prev; /* indices to form a circular LRU */
|
||||
unsigned char in_use; /* owned by a client, or free? */
|
||||
int age; /* tracked by clients to update local LRU's */
|
||||
} S3VTexRegionRec, *S3VTexRegionPtr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int nbox;
|
||||
drm_clip_rect_t boxes[S3V_NR_SAREA_CLIPRECTS];
|
||||
|
||||
/* Maintain an LRU of contiguous regions of texture space. If
|
||||
* you think you own a region of texture memory, and it has an
|
||||
* age different to the one you set, then you are mistaken and
|
||||
* it has been stolen by another client. If global texAge
|
||||
* hasn't changed, there is no need to walk the list.
|
||||
*
|
||||
* These regions can be used as a proxy for the fine-grained
|
||||
* texture information of other clients - by maintaining them
|
||||
* in the same lru which is used to age their own textures,
|
||||
* clients have an approximate lru for the whole of global
|
||||
* texture space, and can make informed decisions as to which
|
||||
* areas to kick out. There is no need to choose whether to
|
||||
* kick out your own texture or someone else's - simply eject
|
||||
* them all in LRU order.
|
||||
*/
|
||||
S3VTexRegionRec texList[S3V_NR_TEX_REGIONS+1]; /* Last elt is sentinal */
|
||||
|
||||
int texAge; /* last time texture was uploaded */
|
||||
|
||||
int last_enqueue; /* last time a buffer was enqueued */
|
||||
int last_dispatch; /* age of the most recently dispatched buffer */
|
||||
int last_quiescent; /* */
|
||||
|
||||
int ctxOwner; /* last context to upload state */
|
||||
} S3VSAREARec, *S3VSAREAPtr;
|
||||
|
||||
typedef struct {
|
||||
/* Nothing here yet */
|
||||
int dummy;
|
||||
} S3VConfigPrivRec, *S3VConfigPrivPtr;
|
||||
|
||||
typedef struct {
|
||||
/* Nothing here yet */
|
||||
int dummy;
|
||||
} S3VDRIContextRec, *S3VDRIContextPtr;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -5,9 +5,7 @@
|
||||
#include "glheader.h"
|
||||
#include "context.h"
|
||||
#include "macros.h"
|
||||
#include "mem.h"
|
||||
#include "mtypes.h"
|
||||
#include "mmath.h"
|
||||
|
||||
#include "tnl/t_context.h"
|
||||
|
||||
@@ -29,6 +27,7 @@
|
||||
|
||||
#define HAVE_ELTS 0
|
||||
|
||||
#if 0
|
||||
static void VERT_FALLBACK( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
@@ -50,8 +49,9 @@ static void VERT_FALLBACK( GLcontext *ctx,
|
||||
_flags = flags & PRIM_MODE_MASK;
|
||||
|
||||
tnl->Driver.Render.PrimTabVerts[_flags]( ctx, start, count, flags );
|
||||
S3V_CONTEXT(ctx)->SetupNewInputs = VERT_CLIP;
|
||||
S3V_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_POS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const GLuint hw_prim[GL_POLYGON+1] = {
|
||||
PrimType_Points,
|
||||
@@ -126,12 +126,10 @@ static __inline void s3vEndPrimitive( s3vContextPtr vmesa )
|
||||
(vmesa->bufSize - vmesa->bufCount) / 2
|
||||
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
|
||||
S3V_DMA_BUF_SZ / 2
|
||||
#define EMIT_VERTS( ctx, j, nr ) \
|
||||
do { \
|
||||
printf("Alas, emit...\n"); \
|
||||
/* s3v_emit(ctx, j, (j)+(nr)) */ \
|
||||
/* we don't need emit on s3v */ \
|
||||
} while (0)
|
||||
/* XXX */
|
||||
#define ALLOC_VERTS(nr) NULL
|
||||
#define EMIT_VERTS(ctx, start, count, buf) NULL
|
||||
#define FLUSH() s3vEndPrimitive( vmesa )
|
||||
|
||||
#define TAG(x) s3v_##x
|
||||
|
||||
@@ -143,13 +141,13 @@ do { \
|
||||
|
||||
|
||||
static GLboolean s3v_run_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i, length, flags = 0;
|
||||
render_func *tab;
|
||||
GLuint i;
|
||||
tnl_render_func *tab;
|
||||
|
||||
DEBUG(("s3v_run_render\n"));
|
||||
|
||||
@@ -170,19 +168,20 @@ static GLboolean s3v_run_render( GLcontext *ctx,
|
||||
|
||||
tnl->Driver.Render.Start( ctx );
|
||||
|
||||
for (i = 0 ; !(flags & PRIM_LAST) ; i += length)
|
||||
for (i = 0 ; i < VB->PrimitiveCount ; i++ )
|
||||
{
|
||||
flags = VB->Primitive[i];
|
||||
length = VB->PrimitiveLength[i];
|
||||
GLuint prim = VB->Primitive[i].mode;
|
||||
GLuint start = VB->Primitive[i].start;
|
||||
GLuint length = VB->Primitive[i].count;
|
||||
|
||||
DEBUG(("s3v_run_render (loop=%i) (lenght=%i)\n", i, length));
|
||||
|
||||
if (length) {
|
||||
tnl->Driver.Render.BuildVertices( ctx, i, i+length,
|
||||
~0 /*stage->inputs*/);
|
||||
tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK]
|
||||
( ctx, i, i + length, flags );
|
||||
vmesa->SetupNewInputs = VERT_CLIP;
|
||||
tnl->Driver.Render.BuildVertices( ctx, start,
|
||||
start+length, ~0 /*stage->inputs*/); /* XXX */
|
||||
tnl->Driver.Render.PrimTabVerts[prim & PRIM_MODE_MASK]
|
||||
( ctx, start, start + length, prim );
|
||||
vmesa->SetupNewInputs = VERT_BIT_POS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,10 +192,10 @@ static GLboolean s3v_run_render( GLcontext *ctx,
|
||||
|
||||
|
||||
static void s3v_check_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
GLuint inputs = VERT_CLIP | VERT_RGBA;
|
||||
GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
|
||||
|
||||
DEBUG(("s3v_check_render\n"));
|
||||
|
||||
@@ -204,22 +203,22 @@ static void s3v_check_render( GLcontext *ctx,
|
||||
|
||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
|
||||
DEBUG(("DD_SEPARATE_SPECULAR\n"));
|
||||
inputs |= VERT_SPEC_RGB;
|
||||
inputs |= VERT_BIT_COLOR1;
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
DEBUG(("ctx->Texture.Unit[0]._ReallyEnabled\n"));
|
||||
inputs |= VERT_TEX(0);
|
||||
inputs |= VERT_BIT_TEX(0);
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
DEBUG(("ctx->Texture.Unit[1]._ReallyEnabled\n"));
|
||||
inputs |= VERT_TEX(1);
|
||||
inputs |= VERT_BIT_TEX(1);
|
||||
}
|
||||
|
||||
if (ctx->Fog.Enabled) {
|
||||
DEBUG(("ctx->Fog.Enabled\n"));
|
||||
inputs |= VERT_FOG_COORD;
|
||||
inputs |= VERT_BIT_FOG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,13 +227,15 @@ static void s3v_check_render( GLcontext *ctx,
|
||||
}
|
||||
|
||||
|
||||
static void dtr( struct gl_pipeline_stage *stage )
|
||||
static void dtr( struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
(void)stage;
|
||||
/* hack to silence a compiler warning */
|
||||
(void) &s3v_validate_render;
|
||||
}
|
||||
|
||||
|
||||
const struct gl_pipeline_stage _s3v_render_stage =
|
||||
const struct tnl_pipeline_stage _s3v_render_stage =
|
||||
{
|
||||
"s3v render",
|
||||
(_DD_NEW_SEPARATE_SPECULAR |
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "s3v_vb.h"
|
||||
#include "s3v_dri.h"
|
||||
|
||||
#include "mem.h"
|
||||
|
||||
s3vScreenPtr s3vCreateScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
s3vScreenPtr s3vScreen;
|
||||
@@ -25,7 +23,7 @@ s3vScreenPtr s3vCreateScreen( __DRIscreenPrivate *sPriv )
|
||||
|
||||
s3vScreen->regionCount = 4; /* Magic number. Can we fix this? */
|
||||
|
||||
s3vScreen->regions = Xmalloc(s3vScreen->regionCount *
|
||||
s3vScreen->regions = _mesa_malloc(s3vScreen->regionCount *
|
||||
sizeof(s3vRegion));
|
||||
DEBUG(("sPriv->fd = %i\nvDRIPriv->dmaBufHandle = %x\n",
|
||||
sPriv->fd, vDRIPriv->dmaBufHandle));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
typedef struct _s3vRegion {
|
||||
drmHandle handle;
|
||||
drm_handle_t handle;
|
||||
drmSize size;
|
||||
drmAddress map;
|
||||
} s3vRegion, *s3vRegionPtr;
|
||||
|
||||
@@ -226,18 +226,19 @@ do { \
|
||||
|
||||
#endif
|
||||
|
||||
static void s3vSetReadBuffer( GLcontext *ctx,
|
||||
GLframebuffer *colorBuffer,
|
||||
GLenum mode )
|
||||
static void s3vSetBuffer( GLcontext *ctx, GLframebuffer *colorBuffer,
|
||||
GLuint bufferBit )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
|
||||
switch ( mode ) {
|
||||
case GL_FRONT_LEFT:
|
||||
vmesa->readOffset = 0;
|
||||
switch ( bufferBit ) {
|
||||
case DD_FRONT_LEFT_BIT:
|
||||
vmesa->drawOffset = vmesa->readOffset = 0;
|
||||
break;
|
||||
case GL_BACK_LEFT:
|
||||
vmesa->readOffset = vmesa->driScreen->fbHeight * vmesa->driScreen->fbWidth * vmesa->s3vScreen->cpp;
|
||||
case DD_BACK_LEFT_BIT:
|
||||
vmesa->drawOffset = vmesa->readOffset = vmesa->driScreen->fbHeight *
|
||||
vmesa->driScreen->fbWidth *
|
||||
vmesa->s3vScreen->cpp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +249,7 @@ void s3vInitSpanFuncs( GLcontext *ctx )
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
|
||||
|
||||
swdd->SetReadBuffer = s3vSetReadBuffer;
|
||||
swdd->SetBuffer = s3vSetBuffer;
|
||||
|
||||
switch ( vmesa->s3vScreen->cpp ) {
|
||||
case 2:
|
||||
|
||||
@@ -51,7 +51,7 @@ static void s3vUpdateAlphaMode( GLcontext *ctx )
|
||||
|
||||
}
|
||||
|
||||
static void s3vDDAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref )
|
||||
static void s3vDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
|
||||
@@ -492,7 +492,7 @@ static void s3vDDColorMask( GLcontext *ctx, GLboolean r, GLboolean g,
|
||||
* Miscellaneous
|
||||
*/
|
||||
|
||||
static void s3vDDClearColor( GLcontext *ctx, const GLchan color[4])
|
||||
static void s3vDDClearColor( GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
|
||||
@@ -842,14 +842,17 @@ void s3vInitStateFuncs( GLcontext *ctx )
|
||||
ctx->Driver.Clear = s3vDDClear;
|
||||
ctx->Driver.ClearIndex = NULL;
|
||||
ctx->Driver.ClearColor = s3vDDClearColor;
|
||||
ctx->Driver.SetDrawBuffer = s3vDDSetDrawBuffer;
|
||||
ctx->Driver.DrawBuffer = s3vDDSetDrawBuffer;
|
||||
ctx->Driver.ReadBuffer = NULL; /* XXX */
|
||||
|
||||
ctx->Driver.IndexMask = NULL;
|
||||
ctx->Driver.ColorMask = NULL; /* s3vDDColorMask; */ /* FIXME */
|
||||
|
||||
ctx->Driver.AlphaFunc = s3vDDAlphaFunc; /* FIXME */
|
||||
#if 0
|
||||
ctx->Driver.BlendEquation = NULL; /* s3vDDBlendEquation; */
|
||||
ctx->Driver.BlendFunc = s3vDDBlendFunc; /* FIXME */
|
||||
#endif
|
||||
ctx->Driver.BlendFuncSeparate = NULL; /* s3vDDBlendFuncSeparate; */
|
||||
ctx->Driver.ClearDepth = s3vDDClearDepth;
|
||||
ctx->Driver.CullFace = s3vDDCullFace;
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
|
||||
#include "glheader.h"
|
||||
#include "mtypes.h"
|
||||
#include "mem.h"
|
||||
#include "simple_list.h"
|
||||
#include "enums.h"
|
||||
#include "texstore.h"
|
||||
#include "texformat.h"
|
||||
#include "teximage.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "mm.h"
|
||||
#include "mmath.h"
|
||||
#include "s3v_context.h"
|
||||
#include "s3v_tex.h"
|
||||
|
||||
@@ -37,8 +36,8 @@ static void s3vSetTexWrapping(s3vContextPtr vmesa,
|
||||
s3vTextureObjectPtr t,
|
||||
GLenum wraps, GLenum wrapt)
|
||||
{
|
||||
CARD32 t0 = t->TextureCMD;
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint t0 = t->TextureCMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vSetTexWrapping: #%i ***\n", ++times));
|
||||
@@ -64,8 +63,8 @@ static void s3vSetTexFilter(s3vContextPtr vmesa,
|
||||
s3vTextureObjectPtr t,
|
||||
GLenum minf, GLenum magf)
|
||||
{
|
||||
CARD32 t0 = t->TextureCMD;
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint t0 = t->TextureCMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vSetTexFilter: #%i ***\n", ++times));
|
||||
@@ -183,7 +182,7 @@ static void s3vTexParameter( GLcontext *ctx, GLenum target,
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
|
||||
s3vSetTexBorderColor( vmesa, t, tObj->_BorderChan );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BASE_LEVEL:
|
||||
@@ -402,7 +401,7 @@ static void s3vBindTexture( GLcontext *ctx, GLenum target,
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT( ctx );
|
||||
s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vBindTexture: #%i ***\n", ++times));
|
||||
@@ -440,11 +439,6 @@ static void s3vBindTexture( GLcontext *ctx, GLenum target,
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!ctx->Texture._ReallyEnabled) {
|
||||
DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = vmesa->CMD & ~MIP_MASK;
|
||||
vmesa->dirty |= S3V_UPLOAD_TEX0;
|
||||
vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#define TEX_DEBUG_ON 0
|
||||
|
||||
extern void s3vUpdateTexLRU( s3vContextPtr vmesa, s3vTextureObjectPtr t );
|
||||
|
||||
#if TEX_DEBUG_ON
|
||||
#define DEBUG_TEX(str) printf str
|
||||
#else
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "enums.h"
|
||||
|
||||
#include "mm.h"
|
||||
#include "mem.h"
|
||||
#include "s3v_context.h"
|
||||
#include "s3v_lock.h"
|
||||
#include "s3v_tex.h"
|
||||
@@ -103,7 +102,7 @@ static void s3vUploadTexLevel( s3vContextPtr vmesa, s3vTextureObjectPtr t,
|
||||
int l2d;
|
||||
/* int offset = 0; */
|
||||
int words;
|
||||
CARD32* dest;
|
||||
GLuint* dest;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
#endif
|
||||
@@ -121,9 +120,9 @@ static void s3vUploadTexLevel( s3vContextPtr vmesa, s3vTextureObjectPtr t,
|
||||
DEBUG_TEX(("t->image[%i].offset = 0x%x\n",
|
||||
level, t->image[level].offset));
|
||||
|
||||
t->TextureBaseAddr[level] = (CARD32)(t->BufAddr + t->image[level].offset
|
||||
+ _TEXALIGN) & (CARD32)(~_TEXALIGN);
|
||||
dest = (CARD32*)(sPriv->pFB + t->TextureBaseAddr[level]);
|
||||
t->TextureBaseAddr[level] = (GLuint)(t->BufAddr + t->image[level].offset
|
||||
+ _TEXALIGN) & (GLuint)(~_TEXALIGN);
|
||||
dest = (GLuint*)(sPriv->pFB + t->TextureBaseAddr[level]);
|
||||
|
||||
DEBUG_TEX(("sPriv->pFB = 0x%x\n", sPriv->pFB));
|
||||
DEBUG_TEX(("dest = 0x%x\n", dest));
|
||||
|
||||
@@ -21,7 +21,7 @@ static void s3vSetTexImages( s3vContextPtr vmesa,
|
||||
{
|
||||
GLuint height, width, pitch, i, /*textureFormat,*/ log_pitch;
|
||||
s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
|
||||
const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
|
||||
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
|
||||
GLint firstLevel, lastLevel, numLevels;
|
||||
GLint log2Width, log2Height;
|
||||
#if TEX_DEBUG_ON
|
||||
@@ -55,15 +55,15 @@ static void s3vSetTexImages( s3vContextPtr vmesa,
|
||||
|
||||
numLevels = lastLevel - firstLevel + 1;
|
||||
|
||||
log2Width = tObj->Image[firstLevel]->WidthLog2;
|
||||
log2Height = tObj->Image[firstLevel]->HeightLog2;
|
||||
log2Width = tObj->Image[0][firstLevel]->WidthLog2;
|
||||
log2Height = tObj->Image[0][firstLevel]->HeightLog2;
|
||||
|
||||
|
||||
/* Figure out the amount of memory required to hold all the mipmap
|
||||
* levels. Choose the smallest pitch to accomodate the largest
|
||||
* mipmap:
|
||||
*/
|
||||
width = tObj->Image[firstLevel]->Width * t->texelBytes;
|
||||
width = tObj->Image[0][firstLevel]->Width * t->texelBytes;
|
||||
for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
|
||||
log_pitch++;
|
||||
|
||||
@@ -71,12 +71,12 @@ static void s3vSetTexImages( s3vContextPtr vmesa,
|
||||
* lines required:
|
||||
*/
|
||||
for ( height = i = 0 ; i < numLevels ; i++ ) {
|
||||
t->image[i].image = tObj->Image[firstLevel + i];
|
||||
t->image[i].image = tObj->Image[0][firstLevel + i];
|
||||
t->image[i].offset = height * pitch;
|
||||
t->image[i].internalFormat = baseImage->Format;
|
||||
height += t->image[i].image->Height;
|
||||
t->TextureBaseAddr[i] = (t->BufAddr + t->image[i].offset +
|
||||
_TEXALIGN) & (CARD32)(~_TEXALIGN);
|
||||
_TEXALIGN) & (GLuint)(~_TEXALIGN);
|
||||
}
|
||||
|
||||
t->Pitch = pitch;
|
||||
@@ -96,13 +96,13 @@ static void s3vUpdateTexEnv( GLcontext *ctx, GLuint unit )
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
||||
const struct gl_texture_object *tObj = texUnit->_Current;
|
||||
const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
|
||||
const GLuint format = tObj->Image[0][tObj->BaseLevel]->Format;
|
||||
/*
|
||||
s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
|
||||
GLuint tc;
|
||||
*/
|
||||
GLuint alpha = 0;
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times));
|
||||
@@ -205,14 +205,14 @@ static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times));
|
||||
DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa->CMD));
|
||||
#endif
|
||||
|
||||
if (texUnit->_ReallyEnabled == TEXTURE0_2D)
|
||||
if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT)
|
||||
{
|
||||
struct gl_texture_object *tObj = texUnit->_Current;
|
||||
s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
|
||||
@@ -246,8 +246,9 @@ static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
|
||||
/* Update texture environment if texture object image format or
|
||||
* texture environment state has changed.
|
||||
*/
|
||||
if (tObj->Image[tObj->BaseLevel]->Format != vmesa->TexEnvImageFmt[unit]) {
|
||||
vmesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
|
||||
if (tObj->Image[0][tObj->BaseLevel]->Format !=
|
||||
vmesa->TexEnvImageFmt[unit]) {
|
||||
vmesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->Format;
|
||||
s3vUpdateTexEnv( ctx, unit );
|
||||
}
|
||||
#if 1
|
||||
@@ -283,16 +284,12 @@ static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
|
||||
void s3vUpdateTextureState( GLcontext *ctx )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
(void) vmesa;
|
||||
#if TEX_DEBUG_ON
|
||||
static unsigned int times=0;
|
||||
DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times));
|
||||
#endif
|
||||
|
||||
if (!ctx->Texture._ReallyEnabled) {
|
||||
DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
#if _TEXFALLBACK
|
||||
FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_FALSE );
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#define HAVE_BACK_COLORS 0
|
||||
#define HAVE_HW_FLATSHADE 1
|
||||
#define VERTEX s3vVertex
|
||||
#define TAB rast_tab
|
||||
#define TAB rast_tab
|
||||
|
||||
#define VERT_SET_RGBA( v, c ) \
|
||||
do { \
|
||||
@@ -55,10 +55,10 @@ do { \
|
||||
|
||||
|
||||
static struct {
|
||||
points_func points;
|
||||
line_func line;
|
||||
triangle_func triangle;
|
||||
quad_func quad;
|
||||
tnl_points_func points;
|
||||
tnl_line_func line;
|
||||
tnl_triangle_func triangle;
|
||||
tnl_quad_func quad;
|
||||
} rast_tab[S3V_MAX_TRIFUNC];
|
||||
|
||||
#define S3V_RAST_CULL_BIT 0x01
|
||||
@@ -236,7 +236,7 @@ void s3vChooseRasterState(GLcontext *ctx)
|
||||
if ( flags & DD_FLATSHADE )
|
||||
ind |= S3V_RAST_FLAT_BIT;
|
||||
|
||||
if ( ctx->Texture._ReallyEnabled ) {
|
||||
if ( ctx->Texture.Unit[0]._ReallyEnabled ) {
|
||||
ind |= S3V_RAST_TEX_BIT;
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
/* __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
|
||||
unsigned int _hw_prim = hwprim;
|
||||
|
||||
@@ -650,7 +650,7 @@ static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim )
|
||||
{
|
||||
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
CARD32 cmd = vmesa->CMD;
|
||||
GLuint cmd = vmesa->CMD;
|
||||
|
||||
unsigned int _hw_prim = hw_prim[prim];
|
||||
|
||||
|
||||
@@ -17,18 +17,26 @@
|
||||
int start02, end01; \
|
||||
int ystart, y01y12; \
|
||||
int i, tmp, tmp2, tmp3; \
|
||||
GLfloat ydiff, fy[3]
|
||||
GLfloat ydiff, fy[3]; \
|
||||
(void) v; (void) vvv; (void) x; (void) y; (void) z; (void) idx; \
|
||||
(void) dx01; (void) dy01; (void) delt02; (void) deltzy; \
|
||||
(void) zstart; (void) start02; (void) ystart; (void) y01y12; \
|
||||
(void) i; (void) tmp; (void) tmp2; (void) tmp3; (void) ydiff; (void) fy
|
||||
|
||||
#define LINE_FLAT_VARS \
|
||||
int arstart, gbstart; \
|
||||
int deltarx, deltgbx, deltary, deltgby; \
|
||||
GLubyte *(col)[3]
|
||||
GLubyte *(col)[3]; \
|
||||
(void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
|
||||
(void) deltary; (void) deltgby; (void) col
|
||||
|
||||
#define LINE_GOURAUD_VARS \
|
||||
int arstart, gbstart; \
|
||||
int deltary, deltgby; \
|
||||
int ctmp, ctmp2, ctmp3, ctmp4; \
|
||||
GLubyte *(col)[3]
|
||||
GLubyte *(col)[3]; \
|
||||
(void) arstart; (void) gbstart; (void) deltary; (void) deltgby; \
|
||||
(void) ctmp; (void) ctmp2; (void) ctmp3; (void) ctmp4; (void) col
|
||||
|
||||
#define SORT_LINE_VERT() \
|
||||
do { \
|
||||
@@ -199,18 +207,29 @@ do { \
|
||||
int start02, end01, end12; \
|
||||
int ystart, y01y12; \
|
||||
int i, tmp, lr; \
|
||||
GLfloat ydiff, fy[3]
|
||||
GLfloat ydiff, fy[3]; \
|
||||
(void) v; (void) x; (void) y; (void) z; (void) idx; (void) dx01; \
|
||||
(void) dy01; (void) dx02; (void) dy02; (void) dx12; (void) dy12; \
|
||||
(void) delt01; (void) delt02; (void) delt12; (void) deltzx; \
|
||||
(void) deltzy; (void) zstart; (void) start02; (void) end01; \
|
||||
(void) end12; (void) ystart; (void) y01y12; (void) i; (void) tmp; \
|
||||
(void) lr; (void) ydiff; (void) fy
|
||||
|
||||
#define GOURAUD_VARS \
|
||||
int arstart, gbstart; \
|
||||
int deltarx, deltgbx, deltary, deltgby; \
|
||||
int ctmp, ctmp2, ctmp3, ctmp4; \
|
||||
GLubyte *(col)[3]
|
||||
GLubyte *(col)[3]; \
|
||||
(void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
|
||||
(void) deltary; (void) deltgby; (void) ctmp; (void) ctmp2; \
|
||||
(void) ctmp3; (void) ctmp4; (void) col
|
||||
|
||||
#define FLAT_VARS \
|
||||
int arstart, gbstart; \
|
||||
int deltarx, deltgbx, deltary, deltgby; \
|
||||
GLubyte *(col)[3]
|
||||
GLubyte *(col)[3]; \
|
||||
(void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
|
||||
(void) deltary; (void) deltgby; (void) col
|
||||
|
||||
#define TEX_VARS \
|
||||
int u0, u1, u2; \
|
||||
@@ -226,7 +245,15 @@ do { \
|
||||
int rbaseu, rbasev; \
|
||||
int dstart, ustart, wstart, vstart; \
|
||||
static int stmp = 0; \
|
||||
s3vTextureObjectPtr t
|
||||
s3vTextureObjectPtr t; \
|
||||
(void) u0; (void) u1; (void) u2; (void) ru0; (void) ru1; (void) ru2; \
|
||||
(void) v0; (void) v1; (void) v2; (void) rv0; (void) rv1; (void) rv2; \
|
||||
(void) w0; (void) w1; (void) w2; (void) rw0; (void) rw1; (void) rw2; \
|
||||
(void) baseu; (void) basev; (void) d0; (void) d1; (void) d2; \
|
||||
(void) deltdx; (void) deltvx; (void) deltux; (void) deltdy; \
|
||||
(void) deltuy; (void) deltwx; (void) deltwy; (void) rbaseu; \
|
||||
(void) rbasev; (void) dstart; (void) ustart; (void) wstart; \
|
||||
(void) vstart; (void) stmp; (void) t
|
||||
|
||||
#define SORT_VERT() \
|
||||
do { \
|
||||
@@ -376,15 +403,15 @@ do { \
|
||||
u0 = (v[idx[0]].texcoord[0][0] \
|
||||
* (GLfloat)(t->image[0].image->Width) * 256.0); \
|
||||
u1 = (v[idx[1]].texcoord[0][0] \
|
||||
* (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
|
||||
* (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
|
||||
u2 = (v[idx[2]].texcoord[0][0] \
|
||||
* (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
|
||||
* (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
|
||||
v0 = (v[idx[0]].texcoord[0][1] \
|
||||
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
|
||||
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
|
||||
v1 = (v[idx[1]].texcoord[0][1] \
|
||||
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
|
||||
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
|
||||
v2 = (v[idx[2]].texcoord[0][1] \
|
||||
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
|
||||
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
|
||||
\
|
||||
w0 = (v[idx[0]].win[3]); \
|
||||
w1 = (v[idx[1]].win[3]); \
|
||||
@@ -492,8 +519,8 @@ do { \
|
||||
rv1 = (((v1 - basev) * rw1)); \
|
||||
rv2 = (((v2 - basev) * rw2)); \
|
||||
\
|
||||
while (baseu < 0) { baseu += (t->globj->Image[0]->Width << 8); } \
|
||||
while (basev < 0) { basev += (t->globj->Image[0]->Height << 8); } \
|
||||
while (baseu < 0) { baseu += (t->globj->Image[0][0]->Width << 8); } \
|
||||
while (basev < 0) { basev += (t->globj->Image[0][0]->Height << 8); } \
|
||||
\
|
||||
if (!(baseu & 0xFF)) \
|
||||
{ baseu = (baseu >> 8); } \
|
||||
@@ -505,8 +532,8 @@ do { \
|
||||
else \
|
||||
{ basev = (basev >> 8) - 1; } \
|
||||
\
|
||||
rbaseu = (baseu) << (16 - t->globj->Image[0]->WidthLog2); \
|
||||
rbasev = (basev) << (16 - t->globj->Image[0]->WidthLog2); \
|
||||
rbaseu = (baseu) << (16 - t->globj->Image[0][0]->WidthLog2); \
|
||||
rbasev = (basev) << (16 - t->globj->Image[0][0]->WidthLog2); \
|
||||
deltuy = (((ru2 - ru0) / dy02)); \
|
||||
deltvy = (((rv2 - rv0) / dy02)); \
|
||||
rw0 *= (1024.0 * 512.0); \
|
||||
@@ -591,6 +618,7 @@ static void TAG(s3v_line)( s3vContextPtr vmesa,
|
||||
#endif
|
||||
#if (IND & S3V_RAST_CULL_BIT)
|
||||
GLfloat cull;
|
||||
(void) cull;
|
||||
#endif
|
||||
|
||||
DEBUG(("*** s3v_line: "));
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
|
||||
#include "glheader.h"
|
||||
#include "mtypes.h"
|
||||
#include "mem.h"
|
||||
#include "macros.h"
|
||||
#include "colormac.h"
|
||||
#include "mmath.h"
|
||||
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/t_context.h"
|
||||
@@ -26,8 +24,8 @@
|
||||
|
||||
static struct {
|
||||
void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
|
||||
interp_func interp;
|
||||
copy_pv_func copy_pv;
|
||||
tnl_interp_func interp;
|
||||
tnl_copy_pv_func copy_pv;
|
||||
GLboolean (*check_tex_sizes)( GLcontext *ctx );
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_stride_shift;
|
||||
@@ -61,6 +59,7 @@ static struct {
|
||||
#define GET_VIEWPORT_MAT() 0 /* vmesa->hw_viewport */
|
||||
#define GET_TEXSOURCE(n) n
|
||||
#define GET_VERTEX_FORMAT() 0
|
||||
#define GET_VERTEX_SIZE() S3V_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
|
||||
#define GET_VERTEX_STORE() S3V_CONTEXT(ctx)->verts
|
||||
#define GET_VERTEX_STRIDE_SHIFT() S3V_CONTEXT(ctx)->vertex_stride_shift
|
||||
#define INVALIDATE_STORED_VERTICES()
|
||||
@@ -71,8 +70,8 @@ static struct {
|
||||
#define HAVE_HW_DIVIDE 1
|
||||
#define HAVE_RGBA_COLOR 0 /* we're BGRA */
|
||||
#define HAVE_TINY_VERTICES 1
|
||||
#define HAVE_NOTEX_VERTICES 1
|
||||
#define HAVE_TEX0_VERTICES 1
|
||||
#define HAVE_NOTEX_VERTICES 0
|
||||
#define HAVE_TEX0_VERTICES 0
|
||||
#define HAVE_TEX1_VERTICES 0
|
||||
#define HAVE_TEX2_VERTICES 0
|
||||
#define HAVE_TEX3_VERTICES 0
|
||||
@@ -216,7 +215,6 @@ void s3vBuildVertices( GLcontext *ctx,
|
||||
GLubyte *v = ((GLubyte *)vmesa->verts +
|
||||
(start<<vmesa->vertex_stride_shift));
|
||||
GLuint stride = 1<<vmesa->vertex_stride_shift;
|
||||
GLuint ind = 0;
|
||||
|
||||
DEBUG(("*** s3vBuildVertices ***\n"));
|
||||
DEBUG(("vmesa->SetupNewInputs = 0x%x\n", vmesa->SetupNewInputs));
|
||||
@@ -284,7 +282,7 @@ void s3vChooseVertexState( GLcontext *ctx )
|
||||
*/
|
||||
|
||||
|
||||
if (ctx->Texture._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
_tnl_need_projected_coords( ctx, GL_FALSE );
|
||||
ind |= S3V_TEX0_BIT;
|
||||
} else {
|
||||
@@ -330,12 +328,12 @@ void s3vFreeVB( GLcontext *ctx )
|
||||
}
|
||||
|
||||
if (vmesa->UbyteSecondaryColor.Ptr) {
|
||||
ALIGN_FREE(vmesa->UbyteSecondaryColor.Ptr);
|
||||
ALIGN_FREE((void *)vmesa->UbyteSecondaryColor.Ptr);
|
||||
vmesa->UbyteSecondaryColor.Ptr = 0;
|
||||
}
|
||||
|
||||
if (vmesa->UbyteColor.Ptr) {
|
||||
ALIGN_FREE(vmesa->UbyteColor.Ptr);
|
||||
ALIGN_FREE((void *)vmesa->UbyteColor.Ptr);
|
||||
vmesa->UbyteColor.Ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "s3v_context.h"
|
||||
#include "s3v_vb.h"
|
||||
#include "context.h"
|
||||
#include "mmath.h"
|
||||
#include "matrix.h"
|
||||
#include "s3v_dri.h"
|
||||
|
||||
@@ -46,15 +45,14 @@ s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||
vmesa->glCtx->DriverCtx = NULL;
|
||||
_mesa_destroy_context(vmesa->glCtx);
|
||||
|
||||
Xfree(vmesa);
|
||||
_mesa_free(vmesa);
|
||||
driContextPriv->driverPrivate = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GLboolean
|
||||
s3vCreateBuffer( Display *dpy,
|
||||
__DRIscreenPrivate *driScrnPriv,
|
||||
s3vCreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
const __GLcontextModes *mesaVis,
|
||||
GLboolean isPixmap )
|
||||
@@ -82,7 +80,7 @@ s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
||||
}
|
||||
|
||||
static void
|
||||
s3vSwapBuffers(Display *dpy, void *drawablePrivate)
|
||||
s3vSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
|
||||
__DRIscreenPrivate *sPriv;
|
||||
@@ -99,14 +97,14 @@ s3vSwapBuffers(Display *dpy, void *drawablePrivate)
|
||||
|
||||
/* DMAFLUSH(); */
|
||||
|
||||
_mesa_swapbuffers( ctx );
|
||||
_mesa_notifySwapBuffers( ctx );
|
||||
|
||||
vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
/* driScrnPriv = vmesa->driScreen; */
|
||||
|
||||
/* if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */
|
||||
|
||||
/* _mesa_swapbuffers( ctx ); */
|
||||
/* _mesa_notifySwapBuffers( ctx ); */
|
||||
#if 1
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
@@ -174,6 +172,7 @@ s3vMakeCurrent(__DRIcontextPrivate *driContextPriv,
|
||||
|
||||
s3vContextPtr vmesa;
|
||||
__DRIdrawablePrivate *dPriv = driDrawPriv;
|
||||
vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
DEBUG(("s3vMakeCurrent\n"));
|
||||
|
||||
@@ -275,18 +274,6 @@ s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
s3vOpenFullScreen(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
s3vCloseFullScreen(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static struct __DriverAPIRec s3vAPI = {
|
||||
s3vInitDriver,
|
||||
@@ -298,12 +285,10 @@ static struct __DriverAPIRec s3vAPI = {
|
||||
s3vSwapBuffers,
|
||||
s3vMakeCurrent,
|
||||
s3vUnbindContext,
|
||||
s3vOpenFullScreen,
|
||||
s3vCloseFullScreen
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
@@ -319,6 +304,7 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
|
||||
DEBUG(("__driCreateScreen: psp = %p\n", psp));
|
||||
return (void *) psp;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __driRegisterExtensions(void)
|
||||
{
|
||||
|
||||
@@ -25,8 +25,7 @@ DRIVER_SOURCES = \
|
||||
savagetex.c \
|
||||
savagetris.c \
|
||||
savageioctl.c \
|
||||
savagespan.c \
|
||||
savagedma.c
|
||||
savagespan.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
|
||||
@@ -341,8 +341,8 @@ typedef enum
|
||||
TPS_256
|
||||
} TexPaletteSize;
|
||||
|
||||
#define MAX_MIPMAP_LOD_BIAS 255
|
||||
#define MIN_MIPMAP_LOD_BIAS -255
|
||||
#define MAX_MIPMAP_LOD_BIAS 255
|
||||
#define MIN_MIPMAP_LOD_BIAS -255
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -627,107 +627,6 @@ typedef union {
|
||||
#define SAVAGE_HW_NO_UV1 ((1<<6) | (1<<7))
|
||||
#define SAVAGE_HW_SKIPFLAGS 0x000000ff
|
||||
|
||||
#define SAVAGE_HW_TRIANGLE_TYPE (3UL<<25)
|
||||
#define SAVAGE_HW_TRIANGLE_CONT (1UL<<24)
|
||||
#define SAVAGE_HW_TRIANGLE_LIST (0<<25)
|
||||
#define SAVAGE_HW_TRIANGLE_STRIP (1<<25)
|
||||
#define SAVAGE_HW_TRIANGLE_FAN (2<<25)
|
||||
#define SAVAGE_HW_QUAD (3<<25)
|
||||
|
||||
#define __HW_TEXTURE_CHANGED 0x00002FE
|
||||
#define __HW_HAS_SCISSORS_CHANGED 0x00001800
|
||||
#define __HW_ALL_CHANGED 0x1FFFFFF
|
||||
/*Frank 2001/11/14 Wait commands*/
|
||||
#define WAIT_3D_IDLE 0xC0010000
|
||||
#define WAIT_3D_2D_IDLE 0xC0030000
|
||||
|
||||
#define SET_REGISTER(index, count) \
|
||||
((CMD_SetRegister << 27) | (0x6000000) | ((count) << 16) | (index))
|
||||
|
||||
/*frank 2001/11/20 */
|
||||
#define MAXLOOP 0xFFFFFF
|
||||
/*#define MAXFIFO 0x7F00*/
|
||||
#define MAXFIFO 0x1FF00
|
||||
|
||||
/* get eventtag from shadow status */
|
||||
/* here we use eventTag1 because eventTag0 is used by HWXvMC*/
|
||||
#define GET_EVENTTAG \
|
||||
(((*(volatile GLuint *)(imesa->MMIO_BASE+0x48c04)) & 0xffff0000L)>>16)
|
||||
|
||||
#define SHADOW_WAIT(imesa ) do \
|
||||
{ \
|
||||
int loop=0; \
|
||||
imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\
|
||||
if(imesa->shadowCounter == 0)\
|
||||
imesa->shadowCounter = MAX_SHADOWCOUNTER;\
|
||||
*(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\
|
||||
while(\
|
||||
(GET_EVENTTAG) != imesa->shadowCounter &&\
|
||||
(loop++ < MAXLOOP));\
|
||||
}while(0);
|
||||
|
||||
#define SHADOW_WAIT_IDLE(imesa ) do \
|
||||
{ \
|
||||
int loop=0; \
|
||||
imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\
|
||||
if(imesa->shadowCounter == 0)\
|
||||
imesa->shadowCounter = MAX_SHADOWCOUNTER;\
|
||||
/* *(volatile GLuint *)imesa->BCIBase = WAIT_3D_IDLE;\*/\
|
||||
*(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\
|
||||
while ( \
|
||||
(GET_EVENTTAG) != imesa->shadowCounter && \
|
||||
(loop++ < MAXLOOP)); \
|
||||
}while(0);
|
||||
|
||||
#if 0
|
||||
#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60))
|
||||
|
||||
#define PAGE_PENDING(result) do{\
|
||||
result=((ALT_STATUS_WORD0 & 0x08000000)?GL_TRUE:GL_FALSE);\
|
||||
}while(0)
|
||||
|
||||
#define WAIT_FOR_FIFO(count) do{\
|
||||
int loop = 0; \
|
||||
int slots = MAXFIFO-count; \
|
||||
while(((ALT_STATUS_WORD0 &0x001fffff)>slots)&&(loop++<MAXLOOP)); \
|
||||
}while(0)
|
||||
|
||||
|
||||
#define WAIT_IDLE_EMPTY do{\
|
||||
int loop = 0; \
|
||||
if (/*imesa->shadowStatus*/0)\
|
||||
{\
|
||||
SHADOW_WAIT_IDLE(imesa);\
|
||||
}\
|
||||
else\
|
||||
{ \
|
||||
while(((ALT_STATUS_WORD0 &0x00ffffff)!=0x00E00000L)&&(loop++<MAXLOOP));\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WAIT_IDLE do{\
|
||||
int loop = 0; \
|
||||
if (imesa->shadowStatus)\
|
||||
while((((*imesa->shadowPointer) & 0x0E000000L)!=0x0E000000L)&&(loop++<MAXLOOP));\
|
||||
else\
|
||||
while(((ALT_STATUS_WORD0 &0x00E00000)!=0x00E00000L)&&(loop++<MAXLOOP)); \
|
||||
}while(0)
|
||||
#endif /* 0 */
|
||||
|
||||
#define SAVAGE_DRAW_PRIMITIVE(count, typeandvertexSkip, isCont) \
|
||||
( ((count)<<16) | (typeandvertexSkip) | (isCont | (1<<31)));
|
||||
|
||||
static __inline volatile GLuint * SAVAGE_GET_BCI_POINTER(savageContextPtr imesa, GLuint count)
|
||||
{
|
||||
WAIT_FOR_FIFO(count);
|
||||
return (volatile GLuint *)(imesa->BCIBase);
|
||||
}
|
||||
|
||||
/*use this set bci cmd now!*/
|
||||
#define WRITE_CMD(buf,cmd,type) do {\
|
||||
*((type*)buf)=cmd;\
|
||||
buf++;\
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -41,11 +41,6 @@ typedef struct {
|
||||
} savageRegion, *savageRegionPtr;
|
||||
|
||||
typedef struct {
|
||||
savageRegion front;
|
||||
savageRegion back;
|
||||
savageRegion depth;
|
||||
savageRegion aperture;
|
||||
|
||||
int chipset;
|
||||
int width;
|
||||
int height;
|
||||
@@ -53,31 +48,34 @@ typedef struct {
|
||||
|
||||
int cpp; /* for front and back buffers */
|
||||
int zpp;
|
||||
|
||||
int agpMode;
|
||||
|
||||
unsigned int bufferSize;
|
||||
|
||||
#if 0
|
||||
int bitsPerPixel;
|
||||
#endif
|
||||
unsigned int frontFormat;
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int frontBitmapDesc;
|
||||
|
||||
unsigned int backOffset;
|
||||
unsigned int backBitmapDesc;
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthBitmapDesc;
|
||||
|
||||
unsigned int backPitch;
|
||||
unsigned int backPitchBits;
|
||||
unsigned int aperturePitch;
|
||||
|
||||
unsigned int textureOffset[SAVAGE_NR_TEX_HEAPS];
|
||||
unsigned int textureSize[SAVAGE_NR_TEX_HEAPS];
|
||||
unsigned int logTextureGranularity[SAVAGE_NR_TEX_HEAPS];
|
||||
drmAddress texVirtual[SAVAGE_NR_TEX_HEAPS];
|
||||
|
||||
__DRIscreenPrivate *driScrnPriv;
|
||||
drmBufMapPtr bufs;
|
||||
int use_copy_buf;
|
||||
unsigned int sarea_priv_offset;
|
||||
__DRIscreenPrivate *driScrnPriv;
|
||||
|
||||
savageRegion aperture;
|
||||
savageRegion agpTextures;
|
||||
|
||||
drmBufMapPtr bufs;
|
||||
|
||||
unsigned int sarea_priv_offset;
|
||||
|
||||
/* Configuration cache with default values for all contexts */
|
||||
driOptionCache optionCache;
|
||||
@@ -87,7 +85,6 @@ typedef struct {
|
||||
#include "savagecontext.h"
|
||||
|
||||
extern void savageGetLock( savageContextPtr imesa, GLuint flags );
|
||||
extern void savageEmitHwStateLocked( savageContextPtr imesa );
|
||||
extern void savageEmitScissorValues( savageContextPtr imesa, int box_nr, int emit );
|
||||
extern void savageEmitDrawingRectangle( savageContextPtr imesa );
|
||||
extern void savageXMesaSetBackClipRects( savageContextPtr imesa );
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
|
||||
#include "savage_dri.h"
|
||||
|
||||
#include "savagedma.h"
|
||||
|
||||
#include "xmlpool.h"
|
||||
|
||||
/* Configuration
|
||||
@@ -66,6 +64,7 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_SECTION_QUALITY
|
||||
DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
|
||||
DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
|
||||
DRI_CONF_FLOAT_DEPTH(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_MAX_TEXTURE_UNITS(2,1,2)
|
||||
@@ -74,7 +73,7 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_NO_RAST(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
static const GLuint __driNConfigOptions = 4;
|
||||
static const GLuint __driNConfigOptions = 5;
|
||||
|
||||
#ifdef USE_NEW_INTERFACE
|
||||
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
|
||||
@@ -85,6 +84,8 @@ static const struct dri_debug_control debug_control[] =
|
||||
{ "fall", DEBUG_FALLBACKS },
|
||||
{ "api", DEBUG_VERBOSE_API },
|
||||
{ "lru", DEBUG_VERBOSE_LRU },
|
||||
{ "verb", DEBUG_VERBOSE_MSG },
|
||||
{ "dma", DEBUG_DMA },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
#ifndef SAVAGE_DEBUG
|
||||
@@ -131,7 +132,6 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
|
||||
savageScreenPrivate *savageScreen;
|
||||
SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
|
||||
|
||||
|
||||
/* Allocate the private area */
|
||||
savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate));
|
||||
if (!savageScreen)
|
||||
@@ -146,23 +146,19 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
|
||||
savageScreen->mem=gDRIPriv->mem;
|
||||
savageScreen->cpp=gDRIPriv->cpp;
|
||||
savageScreen->zpp=gDRIPriv->zpp;
|
||||
savageScreen->frontPitch=gDRIPriv->frontPitch;
|
||||
savageScreen->frontOffset=gDRIPriv->frontOffset;
|
||||
savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc;
|
||||
|
||||
|
||||
savageScreen->agpMode=gDRIPriv->agpMode;
|
||||
|
||||
savageScreen->bufferSize=gDRIPriv->bufferSize;
|
||||
|
||||
if (gDRIPriv->cpp == 4)
|
||||
savageScreen->frontFormat = DV_PF_8888;
|
||||
else
|
||||
savageScreen->frontFormat = DV_PF_565;
|
||||
|
||||
savageScreen->frontOffset=gDRIPriv->frontOffset;
|
||||
savageScreen->backOffset = gDRIPriv->backOffset;
|
||||
savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc;
|
||||
savageScreen->depthOffset=gDRIPriv->depthOffset;
|
||||
savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc;
|
||||
#if 0
|
||||
savageScreen->backPitch = gDRIPriv->auxPitch;
|
||||
savageScreen->backPitchBits = gDRIPriv->auxPitchBits;
|
||||
#endif
|
||||
|
||||
savageScreen->textureOffset[SAVAGE_CARD_HEAP] =
|
||||
gDRIPriv->textureOffset;
|
||||
savageScreen->textureSize[SAVAGE_CARD_HEAP] =
|
||||
@@ -171,57 +167,32 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
|
||||
gDRIPriv->logTextureGranularity;
|
||||
|
||||
savageScreen->textureOffset[SAVAGE_AGP_HEAP] =
|
||||
gDRIPriv->agpTextures.handle;
|
||||
gDRIPriv->agpTextureHandle;
|
||||
savageScreen->textureSize[SAVAGE_AGP_HEAP] =
|
||||
gDRIPriv->agpTextures.size;
|
||||
gDRIPriv->agpTextureSize;
|
||||
savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] =
|
||||
gDRIPriv->logAgpTextureGranularity;
|
||||
|
||||
savageScreen->back.handle = gDRIPriv->backbuffer;
|
||||
savageScreen->back.size = gDRIPriv->backbufferSize;
|
||||
savageScreen->back.map =
|
||||
(drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset);
|
||||
|
||||
savageScreen->depth.handle = gDRIPriv->depthbuffer;
|
||||
savageScreen->depth.size = gDRIPriv->depthbufferSize;
|
||||
|
||||
savageScreen->depth.map =
|
||||
(drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset);
|
||||
|
||||
savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
|
||||
savageScreen->agpTextures.handle = gDRIPriv->agpTextureHandle;
|
||||
savageScreen->agpTextures.size = gDRIPriv->agpTextureSize;
|
||||
if (drmMap(sPriv->fd,
|
||||
savageScreen->agpTextures.handle,
|
||||
savageScreen->agpTextures.size,
|
||||
(drmAddress *)&(savageScreen->agpTextures.map)) != 0)
|
||||
{
|
||||
Xfree(savageScreen);
|
||||
sPriv->private = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
savageScreen->texVirtual[SAVAGE_CARD_HEAP] =
|
||||
(drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset);
|
||||
|
||||
if (drmMap(sPriv->fd,
|
||||
gDRIPriv->registers.handle,
|
||||
gDRIPriv->registers.size,
|
||||
(drmAddress *)&(gDRIPriv->registers.map)) != 0)
|
||||
{
|
||||
Xfree(savageScreen);
|
||||
sPriv->private = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (drmMap(sPriv->fd,
|
||||
gDRIPriv->agpTextures.handle,
|
||||
gDRIPriv->agpTextures.size,
|
||||
(drmAddress *)&(gDRIPriv->agpTextures.map)) != 0)
|
||||
{
|
||||
Xfree(savageScreen);
|
||||
sPriv->private = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* agp texture*/
|
||||
savageScreen->texVirtual[SAVAGE_AGP_HEAP] =
|
||||
(drmAddress)(gDRIPriv->agpTextures.map);
|
||||
(drmAddress)(savageScreen->agpTextures.map);
|
||||
|
||||
gDRIPriv->BCIcmdBuf.map = (drmAddress *)
|
||||
((unsigned int)gDRIPriv->registers.map+0x00010000);
|
||||
|
||||
savageScreen->aperture.handle = gDRIPriv->aperture.handle;
|
||||
savageScreen->aperture.size = gDRIPriv->aperture.size;
|
||||
savageScreen->aperture.handle = gDRIPriv->apertureHandle;
|
||||
savageScreen->aperture.size = gDRIPriv->apertureSize;
|
||||
savageScreen->aperturePitch = gDRIPriv->aperturePitch;
|
||||
if (drmMap(sPriv->fd,
|
||||
savageScreen->aperture.handle,
|
||||
savageScreen->aperture.size,
|
||||
@@ -230,8 +201,12 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
|
||||
Xfree(savageScreen);
|
||||
sPriv->private = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
savageScreen->bufs = drmMapBufs(sPriv->fd);
|
||||
|
||||
savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
|
||||
|
||||
/* parse information in __driConfigOptions */
|
||||
driParseOptionInfo (&savageScreen->optionCache,
|
||||
__driConfigOptions, __driNConfigOptions);
|
||||
@@ -251,6 +226,8 @@ savageDestroyScreen(__DRIscreenPrivate *sPriv)
|
||||
{
|
||||
savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
|
||||
|
||||
drmUnmapBufs(savageScreen->bufs);
|
||||
|
||||
/* free all option information */
|
||||
driDestroyOptionInfo (&savageScreen->optionCache);
|
||||
|
||||
@@ -295,7 +272,6 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
savageContextPtr imesa;
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
struct dd_function_table functions;
|
||||
SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
|
||||
savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
|
||||
drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+
|
||||
savageScreen->sarea_priv_offset);
|
||||
@@ -323,10 +299,19 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
}
|
||||
driContextPriv->driverPrivate = imesa;
|
||||
|
||||
imesa->cmdBuf.size = SAVAGE_CMDBUF_SIZE;
|
||||
imesa->cmdBuf.base = imesa->cmdBuf.write =
|
||||
malloc(SAVAGE_CMDBUF_SIZE * sizeof(drm_savage_cmd_header_t));
|
||||
if (!imesa->cmdBuf.base)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Parse configuration files */
|
||||
driParseConfigFiles (&imesa->optionCache, &savageScreen->optionCache,
|
||||
sPriv->myNum, "savage");
|
||||
|
||||
imesa->float_depth = driQueryOptionb(&imesa->optionCache, "float_depth") &&
|
||||
savageScreen->chipset >= S3_SAVAGE4;
|
||||
imesa->no_rast = driQueryOptionb(&imesa->optionCache, "no_rast");
|
||||
imesa->texture_depth = driQueryOptioni (&imesa->optionCache,
|
||||
"texture_depth");
|
||||
if (imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
|
||||
@@ -398,26 +383,14 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
|
||||
/* DMA buffer */
|
||||
|
||||
/*The shadow pointer*/
|
||||
imesa->shadowPointer =
|
||||
(volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ;
|
||||
/* here we use eventTag1 because eventTag0 is used by HWXvMC*/
|
||||
imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6);
|
||||
/* imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/
|
||||
imesa->shadowCounter = MAX_SHADOWCOUNTER;
|
||||
imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */
|
||||
|
||||
imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map;
|
||||
imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map;
|
||||
for(i=0;i<5;i++)
|
||||
{
|
||||
imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map +
|
||||
0x01000000 * i );
|
||||
}
|
||||
|
||||
imesa->aperturePitch = gDRIPriv->aperturePitch;
|
||||
|
||||
|
||||
imesa->aperturePitch = savageScreen->aperturePitch;
|
||||
|
||||
/* change texHeap initialize to support two kind of texture heap*/
|
||||
/* here is some parts of initialization, others in InitDriver() */
|
||||
|
||||
@@ -438,9 +411,19 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
|
||||
imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
|
||||
imesa->depth_scale = (imesa->savageScreen->zpp == 2) ?
|
||||
(1.0F/0x10000):(1.0F/0x1000000);
|
||||
(1.0F/0xffff):(1.0F/0xffffff);
|
||||
|
||||
imesa->vertex_dma_buffer = NULL;
|
||||
imesa->bufferSize = savageScreen->bufferSize;
|
||||
imesa->dmaVtxBuf.total = 0;
|
||||
imesa->dmaVtxBuf.used = 0;
|
||||
imesa->dmaVtxBuf.flushed = 0;
|
||||
|
||||
imesa->clientVtxBuf.total = 16384;
|
||||
imesa->clientVtxBuf.used = 0;
|
||||
imesa->clientVtxBuf.flushed = 0;
|
||||
imesa->clientVtxBuf.buf = (u_int32_t *)malloc(16384*4);
|
||||
|
||||
imesa->vtxBuf = &imesa->clientVtxBuf;
|
||||
|
||||
/* Uninitialized vertex format. Force setting the vertex state in
|
||||
* savageRenderStart.
|
||||
@@ -450,6 +433,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
/* Utah stuff
|
||||
*/
|
||||
imesa->new_state = ~0;
|
||||
imesa->new_gl_state = ~0;
|
||||
imesa->RenderIndex = ~0;
|
||||
imesa->dirty = ~0;
|
||||
imesa->lostContext = GL_TRUE;
|
||||
@@ -483,8 +467,6 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
|
||||
ctx->DriverCtx = (void *) imesa;
|
||||
imesa->glCtx = ctx;
|
||||
if (savageDMAInit(imesa) == GL_FALSE)
|
||||
return GL_FALSE;
|
||||
|
||||
#ifndef SAVAGE_DEBUG
|
||||
SAVAGE_DEBUG = driParseDebugString( getenv( "SAVAGE_DEBUG" ),
|
||||
@@ -501,9 +483,6 @@ savageCreateContext( const __GLcontextModes *mesaVis,
|
||||
|
||||
savageDDInitState( imesa );
|
||||
|
||||
if (driQueryOptionb(&imesa->optionCache, "no_rast"))
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE);
|
||||
|
||||
driContextPriv->driverPrivate = (void *) imesa;
|
||||
|
||||
return GL_TRUE;
|
||||
@@ -529,8 +508,10 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||
}
|
||||
foreach_s (t, next_t, &(imesa->SwappedOut))
|
||||
savageDestroyTexObj(imesa, t);
|
||||
/*free the dma buffer*/
|
||||
savageDMAClose(imesa);
|
||||
|
||||
free(imesa->cmdBuf.base);
|
||||
free(imesa->clientVtxBuf.buf);
|
||||
|
||||
_swsetup_DestroyContext(imesa->glCtx );
|
||||
_tnl_DestroyContext( imesa->glCtx );
|
||||
_ac_DestroyContext( imesa->glCtx );
|
||||
@@ -753,10 +734,13 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )
|
||||
* more broken than usual.
|
||||
*/
|
||||
if (sarea->ctxOwner != me) {
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_CTX |
|
||||
SAVAGE_UPLOAD_CLIPRECTS |
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_LOCAL |
|
||||
SAVAGE_UPLOAD_GLOBAL |
|
||||
SAVAGE_UPLOAD_FOGTBL |
|
||||
SAVAGE_UPLOAD_TEX0 |
|
||||
SAVAGE_UPLOAD_TEX1);
|
||||
SAVAGE_UPLOAD_TEX1 |
|
||||
SAVAGE_UPLOAD_TEXGLOBAL |
|
||||
SAVAGE_UPLOAD_CLIPRECTS);
|
||||
imesa->lostContext = GL_TRUE;
|
||||
sarea->ctxOwner = me;
|
||||
}
|
||||
@@ -794,8 +778,6 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )
|
||||
savageResetGlobalLRU( imesa , heap );
|
||||
}
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE;
|
||||
imesa->texAge[heap] = sarea->texAge[heap];
|
||||
}
|
||||
} /* end of for loop */
|
||||
@@ -948,10 +930,9 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
|
||||
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
static const __DRIversion ddx_expected = { 1, 0, 0 };
|
||||
static const __DRIversion ddx_expected = { 2, 0, 0 };
|
||||
static const __DRIversion dri_expected = { 4, 0, 0 };
|
||||
static const __DRIversion drm_expected = { 1, 0, 0 };
|
||||
|
||||
static const __DRIversion drm_expected = { 2, 0, 0 };
|
||||
|
||||
if ( ! driCheckDriDdxDrmVersions2( "Savage",
|
||||
dri_version, & dri_expected,
|
||||
|
||||
@@ -42,7 +42,6 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr;
|
||||
#include "tnl/t_vertex.h"
|
||||
|
||||
#include "savagetex.h"
|
||||
#include "savagedma.h"
|
||||
|
||||
#include "xmlconfig.h"
|
||||
|
||||
@@ -69,10 +68,26 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr;
|
||||
#define SAVAGE_NEW_TEXTURE 0x1
|
||||
#define SAVAGE_NEW_CULL 0x2
|
||||
|
||||
/* What needs to be changed for the current vertex dma buffer?
|
||||
* This will go away!
|
||||
*/
|
||||
#define SAVAGE_UPLOAD_LOCAL 0x1 /* DrawLocalCtrl (S4) or
|
||||
DrawCtrl and ZBufCtrl (S3D) */
|
||||
#define SAVAGE_UPLOAD_TEX0 0x2 /* texture unit 0 */
|
||||
#define SAVAGE_UPLOAD_TEX1 0x4 /* texture unit 1 (S4 only) */
|
||||
#define SAVAGE_UPLOAD_FOGTBL 0x8 /* fog table */
|
||||
#define SAVAGE_UPLOAD_GLOBAL 0x10 /* most global regs */
|
||||
#define SAVAGE_UPLOAD_TEXGLOBAL 0x20 /* TexBlendColor (S4 only) */
|
||||
#define SAVAGE_UPLOAD_CLIPRECTS 0x1000 /* FIXME: get rid of this */
|
||||
|
||||
/*define the max numer of vertex in vertex buf*/
|
||||
#define SAVAGE_MAX_VERTEXS 0x10000
|
||||
|
||||
/* Don't make it too big. We don't want to buffer up a whole frame
|
||||
* that would force the application to wait later. */
|
||||
#define SAVAGE_CMDBUF_SIZE 1024
|
||||
#define SAVAGE_MAX_VERTS_PENDING 1024
|
||||
|
||||
/* Use the templated vertex formats:
|
||||
*/
|
||||
#define TAG(x) savage##x
|
||||
@@ -113,6 +128,18 @@ typedef void (*savage_point_func)( savageContextPtr, savageVertex * );
|
||||
imesa->savageScreen->deviceID == CHIP_S3TRISTAR64CDDR )
|
||||
|
||||
|
||||
struct savage_vtxbuf_t {
|
||||
GLuint total, used, flushed; /* in 32 bit units */
|
||||
GLuint idx; /* for DMA buffers */
|
||||
u_int32_t *buf;
|
||||
};
|
||||
|
||||
struct savage_cmdbuf_t {
|
||||
GLuint size; /* size in qwords */
|
||||
drm_savage_cmd_header_t *base; /* initial state starts here */
|
||||
drm_savage_cmd_header_t *start; /* drawing/state commands start here */
|
||||
drm_savage_cmd_header_t *write; /* append stuff here */
|
||||
};
|
||||
|
||||
|
||||
struct savage_context_t {
|
||||
@@ -141,12 +168,14 @@ struct savage_context_t {
|
||||
/* Manage our own state */
|
||||
GLuint new_state;
|
||||
GLuint new_gl_state;
|
||||
GLboolean ptexHack;
|
||||
|
||||
GLuint BCIBase;
|
||||
GLuint MMIO_BASE;
|
||||
/* Command buffer */
|
||||
struct savage_cmdbuf_t cmdBuf;
|
||||
|
||||
/* DMA command buffer */
|
||||
DMABuffer_t DMABuf;
|
||||
/* Vertex buffers */
|
||||
struct savage_vtxbuf_t dmaVtxBuf, clientVtxBuf;
|
||||
struct savage_vtxbuf_t *vtxBuf;
|
||||
|
||||
/* aperture base */
|
||||
GLuint apertureBase[5];
|
||||
@@ -178,7 +207,9 @@ struct savage_context_t {
|
||||
GLenum raster_primitive;
|
||||
GLenum render_primitive;
|
||||
|
||||
GLuint DrawPrimitiveCmd;
|
||||
GLuint skip;
|
||||
GLubyte HwPrim;
|
||||
GLuint HwVertexSize;
|
||||
|
||||
/* Fallback rasterization functions
|
||||
*/
|
||||
@@ -192,8 +223,9 @@ struct savage_context_t {
|
||||
GLuint ClearColor;
|
||||
GLfloat depth_scale;
|
||||
GLfloat hw_viewport[16];
|
||||
/* DRI stuff */
|
||||
drmBufPtr vertex_dma_buffer;
|
||||
/* DRI stuff */
|
||||
GLuint bufferSize;
|
||||
GLuint vertsPending;
|
||||
|
||||
GLframebuffer *glBuffer;
|
||||
|
||||
@@ -223,8 +255,8 @@ struct savage_context_t {
|
||||
GLuint backup_streamFIFO;
|
||||
GLuint NotFirstFrame;
|
||||
|
||||
GLboolean inSwap;
|
||||
GLuint lastSwap;
|
||||
GLuint secondLastSwap;
|
||||
GLuint ctxAge;
|
||||
GLuint dirtyAge;
|
||||
GLuint any_contend; /* throttle me harder */
|
||||
@@ -233,7 +265,7 @@ struct savage_context_t {
|
||||
GLboolean scissorChanged;
|
||||
drm_clip_rect_t draw_rect;
|
||||
drm_clip_rect_t scissor_rect;
|
||||
drm_clip_rect_t tmp_boxes[2][SAVAGE_NR_SAREA_CLIPRECTS];
|
||||
|
||||
/*Texture aging and DMA based aging*/
|
||||
unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
|
||||
|
||||
@@ -257,16 +289,12 @@ struct savage_context_t {
|
||||
|
||||
GLboolean hw_stencil;
|
||||
|
||||
/*shadow pointer*/
|
||||
volatile GLuint *shadowPointer;
|
||||
volatile GLuint *eventTag1;
|
||||
GLuint shadowCounter;
|
||||
GLboolean shadowStatus;
|
||||
|
||||
/* Configuration cache
|
||||
*/
|
||||
driOptionCache optionCache;
|
||||
int texture_depth;
|
||||
GLint texture_depth;
|
||||
GLboolean no_rast;
|
||||
GLboolean float_depth;
|
||||
};
|
||||
|
||||
#define SAVAGE_CONTEXT(ctx) ((savageContextPtr)(ctx->DriverCtx))
|
||||
@@ -281,6 +309,8 @@ extern int SAVAGE_DEBUG;
|
||||
#define DEBUG_FALLBACKS 0x001
|
||||
#define DEBUG_VERBOSE_API 0x002
|
||||
#define DEBUG_VERBOSE_LRU 0x004
|
||||
#define DEBUG_VERBOSE_MSG 0x008
|
||||
#define DEBUG_DMA 0x010
|
||||
|
||||
#define TARGET_FRONT 0x0
|
||||
#define TARGET_BACK 0x1
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include "savagecontext.h"
|
||||
#include "extensions.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define DRIVER_DATE "20050101"
|
||||
|
||||
/***************************************
|
||||
* Mesa's Driver Functions
|
||||
@@ -46,11 +50,33 @@
|
||||
|
||||
static const GLubyte *savageDDGetString( GLcontext *ctx, GLenum name )
|
||||
{
|
||||
static char *cardNames[S3_LAST] = {
|
||||
"Unknown",
|
||||
"Savage3D",
|
||||
"Savage/MX/IX",
|
||||
"Savage4",
|
||||
"ProSavage",
|
||||
"Twister",
|
||||
"ProSavageDDR",
|
||||
"SuperSavage",
|
||||
"Savage2000"
|
||||
};
|
||||
static char buffer[128];
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
savageScreenPrivate *screen = imesa->savageScreen;
|
||||
enum S3CHIPTAGS chipset = screen->chipset;
|
||||
unsigned offset;
|
||||
|
||||
if (chipset < S3_SAVAGE3D || chipset >= S3_LAST)
|
||||
chipset = S3_UNKNOWN; /* should not happen */
|
||||
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *)"S3 Graphics Inc.";
|
||||
case GL_RENDERER:
|
||||
return (GLubyte *)"Mesa DRI SAVAGE Linux_1.1.18";
|
||||
offset = driGetRendererString( buffer, cardNames[chipset], DRIVER_DATE,
|
||||
screen->agpMode );
|
||||
return (GLubyte *)buffer;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -30,20 +30,7 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Commit does not depend on whether we use real DMA or fake it via the BCI */
|
||||
void savageDMACommit (savageContextPtr imesa, void *endPtr) {
|
||||
DMABufferPtr dmaBuff = &imesa->DMABuf;
|
||||
GLuint end = (GLuint)endPtr;
|
||||
|
||||
/* make sure that enough space was allocated */
|
||||
assert (end <= dmaBuff->allocEnd);
|
||||
|
||||
dmaBuff->allocEnd = dmaBuff->end = end;
|
||||
|
||||
/* TODO: check commands, either here or in flush */
|
||||
}
|
||||
|
||||
#if SAVAGE_CMD_DMA
|
||||
#if 0
|
||||
/* flag =
|
||||
0 return -1 if no available page
|
||||
1 wait until a page be available */
|
||||
@@ -219,139 +206,4 @@ int savageDMAClose (savageContextPtr imesa)
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
#else
|
||||
/* Allocate space in faked DMA buffer */
|
||||
void *savageDMAAlloc (savageContextPtr imesa, GLuint size) {
|
||||
DMABufferPtr dmaBuff = &imesa->DMABuf;
|
||||
|
||||
/* make sure that everything has been filled in and committed */
|
||||
assert (dmaBuff->end == dmaBuff->allocEnd);
|
||||
|
||||
size *= sizeof (u_int32_t); /* size in bytes */
|
||||
if (dmaBuff->end + size >= dmaBuff->buf->linear + DMA_PAGE_SIZE) {
|
||||
/* need kick off */
|
||||
savageDMAFlush (imesa);
|
||||
}
|
||||
dmaBuff->allocEnd = dmaBuff->end + size;
|
||||
return (void *)dmaBuff->end;
|
||||
}
|
||||
|
||||
/* Flush DMA buffer via BCI (faked DMA) */
|
||||
void savageDMAFlush(savageContextPtr imesa) {
|
||||
volatile u_int32_t* BCIbase;
|
||||
DMABufferPtr dmaBuff = &imesa->DMABuf;
|
||||
u_int32_t *entry;
|
||||
|
||||
/* make sure that everything has been filled in and committed */
|
||||
assert (dmaBuff->allocEnd == dmaBuff->end);
|
||||
|
||||
if (dmaBuff->start == dmaBuff->end) /* no command? */
|
||||
return;
|
||||
|
||||
/* get bci base */
|
||||
BCIbase = (volatile u_int32_t *)SAVAGE_GET_BCI_POINTER(
|
||||
imesa, (dmaBuff->end - dmaBuff->start) / sizeof (u_int32_t));
|
||||
|
||||
for (entry = (u_int32_t *)dmaBuff->start;
|
||||
entry < (u_int32_t *)dmaBuff->end; ++entry)
|
||||
*BCIbase = *entry;
|
||||
|
||||
dmaBuff->end = dmaBuff->allocEnd = dmaBuff->start;
|
||||
}
|
||||
|
||||
/* Init faked DMA */
|
||||
int savageDMAInit (savageContextPtr imesa) {
|
||||
DMABufferPtr dmaBuff = &imesa->DMABuf;
|
||||
drm_savage_alloc_cont_mem_t * req;
|
||||
|
||||
req = (drm_savage_alloc_cont_mem_t *)
|
||||
malloc (sizeof(drm_savage_alloc_cont_mem_t));
|
||||
if (!req)
|
||||
return GL_FALSE;
|
||||
|
||||
req->linear = (GLuint)malloc (DMA_PAGE_SIZE);
|
||||
if (!req->linear) {
|
||||
free (req);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
dmaBuff->buf = req;
|
||||
|
||||
dmaBuff->start = dmaBuff->end = dmaBuff->allocEnd = req->linear;
|
||||
dmaBuff->usingPage = 0;
|
||||
dmaBuff->kickFlag = GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Close faked DMA */
|
||||
int savageDMAClose (savageContextPtr imesa) {
|
||||
DMABufferPtr dmaBuff = &imesa->DMABuf;
|
||||
drm_savage_alloc_cont_mem_t * req = dmaBuff->buf;
|
||||
|
||||
free ((void *)req->linear);
|
||||
free (req);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Faked vertex buffers
|
||||
*
|
||||
* This is a dirty hack, knowing that it will go away soon when real
|
||||
* vertex DMA is implemented and eventually moved to the DRM.
|
||||
*/
|
||||
|
||||
static u_int32_t vertex_data[16384]; /* 64KB */
|
||||
static drmBuf vertex_buffer = {
|
||||
0, /* idx */
|
||||
65536, /* total = 64KB */
|
||||
0, /* used */
|
||||
(drmAddress)vertex_data /* address */
|
||||
};
|
||||
|
||||
void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer) {
|
||||
GLuint vertexStride = imesa->vertex_size; /* stride in dwords */
|
||||
GLuint vertexSize = imesa->vertex_size; /* the real vertex size in dwords */
|
||||
GLuint nVertices = buffer->used / (vertexStride*4);
|
||||
u_int32_t *data = (u_int32_t*)buffer->address;
|
||||
u_int32_t vertexFormat = imesa->DrawPrimitiveCmd & SAVAGE_HW_SKIPFLAGS;
|
||||
GLuint i, j, left;
|
||||
|
||||
/* we have the monopoly on vertex buffers ;-) */
|
||||
assert (buffer == &vertex_buffer);
|
||||
assert (buffer->used % (vertexStride*4) == 0); /* whole vertices */
|
||||
assert (nVertices % 3 == 0); /* triangle lists */
|
||||
|
||||
/* Flush (pseodo) DMA before accessing the BCI directly. */
|
||||
savageDMAFlush(imesa);
|
||||
|
||||
left = nVertices;
|
||||
while (left != 0) {
|
||||
/* Can emit up to 255 vertices (85 triangles) with one command. */
|
||||
GLuint count = left > 255 ? 255 : left;
|
||||
/* Don't go through another buffering mechanism, copy to BCI
|
||||
* directly. */
|
||||
volatile u_int32_t *vb = SAVAGE_GET_BCI_POINTER(imesa,
|
||||
count*vertexSize + 1);
|
||||
|
||||
WRITE_CMD (vb, SAVAGE_DRAW_PRIMITIVE(
|
||||
count, SAVAGE_HW_TRIANGLE_LIST | vertexFormat, 0),
|
||||
u_int32_t);
|
||||
for (i = 0; i < count; ++i) {
|
||||
for (j = 0; j < vertexSize; ++j)
|
||||
WRITE_CMD (vb, data[j], u_int32_t);
|
||||
data += vertexStride;
|
||||
}
|
||||
left -= count;
|
||||
}
|
||||
|
||||
/* clear the vertex buffer for the next set of vertices */
|
||||
vertex_buffer.used = 0;
|
||||
}
|
||||
|
||||
drmBufPtr savageFakeGetBuffer (savageContextPtr imesa) {
|
||||
assert (vertex_buffer.used == 0); /* has been flushed */
|
||||
return &vertex_buffer;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,4 @@ void savageDMAFlush (savageContextPtr imesa);
|
||||
int savageDMAInit (savageContextPtr imesa);
|
||||
int savageDMAClose (savageContextPtr);
|
||||
|
||||
/* faked implementation of vertex buffers */
|
||||
void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer);
|
||||
drmBufPtr savageFakeGetBuffer (savageContextPtr imesa);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,16 +37,87 @@
|
||||
#include "savagecontext.h"
|
||||
#include "savageioctl.h"
|
||||
#include "savage_bci.h"
|
||||
#include "savagedma.h"
|
||||
#include "savagestate.h"
|
||||
#include "savagespan.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
extern GLuint bcicount;
|
||||
#define DEPTH_SCALE_16 ((1<<16)-1)
|
||||
#define DEPTH_SCALE_24 ((1<<24)-1)
|
||||
|
||||
|
||||
void savageGetDMABuffer( savageContextPtr imesa )
|
||||
{
|
||||
int idx = 0;
|
||||
int size = 0;
|
||||
drmDMAReq dma;
|
||||
int retcode;
|
||||
drmBufPtr buf;
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "Getting dma buffer\n");
|
||||
|
||||
dma.context = imesa->hHWContext;
|
||||
dma.send_count = 0;
|
||||
dma.send_list = NULL;
|
||||
dma.send_sizes = NULL;
|
||||
dma.flags = 0;
|
||||
dma.request_count = 1;
|
||||
dma.request_size = imesa->bufferSize;
|
||||
dma.request_list = &idx;
|
||||
dma.request_sizes = &size;
|
||||
dma.granted_count = 0;
|
||||
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
|
||||
dma.context, dma.request_count,
|
||||
dma.request_size);
|
||||
|
||||
while (1) {
|
||||
retcode = drmDMA(imesa->driFd, &dma);
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
|
||||
retcode,
|
||||
dma.request_sizes[0],
|
||||
dma.request_list[0],
|
||||
dma.granted_count);
|
||||
|
||||
if (retcode == 0 &&
|
||||
dma.request_sizes[0] &&
|
||||
dma.granted_count)
|
||||
break;
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "\n\nflush");
|
||||
}
|
||||
|
||||
buf = &(imesa->savageScreen->bufs->list[idx]);
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr,
|
||||
"drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
|
||||
"dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",
|
||||
dma.request_sizes[0], dma.request_list[0],
|
||||
buf->idx, buf->total,
|
||||
buf->used, buf->address);
|
||||
|
||||
imesa->dmaVtxBuf.total = buf->total / 4;
|
||||
imesa->dmaVtxBuf.used = 0;
|
||||
imesa->dmaVtxBuf.flushed = 0;
|
||||
imesa->dmaVtxBuf.idx = buf->idx;
|
||||
imesa->dmaVtxBuf.buf = (u_int32_t *)buf->address;
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "finished getbuffer\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Still keeping this around because it demonstrates page flipping and
|
||||
* automatic z-clear. */
|
||||
static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
@@ -113,7 +184,7 @@ static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear)
|
||||
imesa->regs.s4.zBufCtrl.ni.frameID =
|
||||
~imesa->regs.s4.zBufCtrl.ni.frameID;
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -157,8 +228,6 @@ static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear)
|
||||
savageDMAFlush (imesa);
|
||||
}
|
||||
|
||||
struct timeb a,b;
|
||||
|
||||
static void savage_BCI_swap(savageContextPtr imesa)
|
||||
{
|
||||
int nbox = imesa->sarea->nbox;
|
||||
@@ -186,7 +255,7 @@ static void savage_BCI_swap(savageContextPtr imesa)
|
||||
imesa->readMap = (char *)imesa->apertureBase[imesa->toggle];
|
||||
|
||||
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
bciptr = SAVAGE_GET_BCI_POINTER(imesa,3);
|
||||
*(bciptr) = 0x960100B0;
|
||||
*(bciptr) = (imesa->savageScreen->frontOffset);
|
||||
@@ -220,97 +289,120 @@ static void savage_BCI_swap(savageContextPtr imesa)
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static GLboolean intersect_rect( drm_clip_rect_t *out,
|
||||
const drm_clip_rect_t *a,
|
||||
const drm_clip_rect_t *b )
|
||||
{
|
||||
*out = *a;
|
||||
if (b->x1 > out->x1) out->x1 = b->x1;
|
||||
if (b->y1 > out->y1) out->y1 = b->y1;
|
||||
if (b->x2 < out->x2) out->x2 = b->x2;
|
||||
if (b->y2 < out->y2) out->y2 = b->y2;
|
||||
|
||||
return ((out->x1 < out->x2) && (out->y1 < out->y2));
|
||||
}
|
||||
|
||||
|
||||
static GLuint savageIntersectClipRects(drm_clip_rect_t *dest,
|
||||
const drm_clip_rect_t *src,
|
||||
GLuint nsrc,
|
||||
const drm_clip_rect_t *clip)
|
||||
{
|
||||
GLuint i, ndest;
|
||||
|
||||
for (i = 0, ndest = 0; i < nsrc; ++i, ++src) {
|
||||
if (intersect_rect(dest, src, clip)) {
|
||||
dest++;
|
||||
ndest++;
|
||||
}
|
||||
}
|
||||
|
||||
return ndest;
|
||||
}
|
||||
|
||||
|
||||
static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
GLint cx, GLint cy, GLint cw, GLint ch )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
|
||||
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
|
||||
drm_savage_clear_t clear;
|
||||
int i;
|
||||
GLuint colorMask, depthMask, clearColor, clearDepth, flags;
|
||||
|
||||
clear.flags = 0;
|
||||
clear.clear_color = imesa->ClearColor;
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if(imesa->savageScreen->zpp == 2)
|
||||
clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16);
|
||||
else
|
||||
clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24);
|
||||
clearColor = imesa->ClearColor;
|
||||
if (imesa->float_depth) {
|
||||
if (imesa->savageScreen->zpp == 2)
|
||||
clearDepth = savageEncodeFloat16(1.0 - ctx->Depth.Clear);
|
||||
else
|
||||
clearDepth = savageEncodeFloat24(1.0 - ctx->Depth.Clear);
|
||||
} else {
|
||||
if (imesa->savageScreen->zpp == 2)
|
||||
clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_16);
|
||||
else
|
||||
clearDepth = (GLuint) ((1.0 - ctx->Depth.Clear) * DEPTH_SCALE_24);
|
||||
}
|
||||
|
||||
FLUSH_BATCH( imesa );
|
||||
colorMask = *((GLuint *) &ctx->Color.ColorMask);
|
||||
depthMask = 0;
|
||||
|
||||
if ((mask & DD_FRONT_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ){
|
||||
clear.flags |= SAVAGE_FRONT;
|
||||
flags = 0;
|
||||
|
||||
if (mask & DD_FRONT_LEFT_BIT) {
|
||||
flags |= SAVAGE_FRONT;
|
||||
mask &= ~DD_FRONT_LEFT_BIT;
|
||||
}
|
||||
|
||||
if ((mask & DD_BACK_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ) {
|
||||
clear.flags |= SAVAGE_BACK;
|
||||
if (mask & DD_BACK_LEFT_BIT) {
|
||||
flags |= SAVAGE_BACK;
|
||||
mask &= ~DD_BACK_LEFT_BIT;
|
||||
}
|
||||
|
||||
if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) {
|
||||
clear.flags |= SAVAGE_DEPTH;
|
||||
flags |= SAVAGE_DEPTH;
|
||||
depthMask |=
|
||||
(imesa->savageScreen->zpp == 2) ? 0xffffffff : 0x00ffffff;
|
||||
mask &= ~DD_DEPTH_BIT;
|
||||
}
|
||||
|
||||
if((mask & DD_STENCIL_BIT) && imesa->hw_stencil)
|
||||
{
|
||||
clear.flags |= SAVAGE_STENCIL;
|
||||
mask &= ~DD_STENCIL_BIT;
|
||||
flags |= SAVAGE_DEPTH;
|
||||
depthMask |= 0xff000000;
|
||||
mask &= ~DD_STENCIL_BIT;
|
||||
}
|
||||
|
||||
if (clear.flags) {
|
||||
LOCK_HARDWARE( imesa );
|
||||
savageFlushVertices(imesa);
|
||||
|
||||
/* flip top to bottom */
|
||||
cy = dPriv->h-cy-ch;
|
||||
cx += imesa->drawX;
|
||||
cy += imesa->drawY;
|
||||
|
||||
for (i = 0 ; i < imesa->numClipRects ; ) {
|
||||
int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, imesa->numClipRects);
|
||||
drm_clip_rect_t *box = imesa->pClipRects;
|
||||
drm_clip_rect_t *b = imesa->sarea->boxes;
|
||||
int n = 0;
|
||||
|
||||
if (!all) {
|
||||
for ( ; i < nr ; i++) {
|
||||
GLint x = box[i].x1;
|
||||
GLint y = box[i].y1;
|
||||
GLint w = box[i].x2 - x;
|
||||
GLint h = box[i].y2 - y;
|
||||
|
||||
if (x < cx) w -= cx - x, x = cx;
|
||||
if (y < cy) h -= cy - y, y = cy;
|
||||
if (x + w > cx + cw) w = cx + cw - x;
|
||||
if (y + h > cy + ch) h = cy + ch - y;
|
||||
if (w <= 0) continue;
|
||||
if (h <= 0) continue;
|
||||
|
||||
b->x1 = x;
|
||||
b->y1 = y;
|
||||
b->x2 = x + w;
|
||||
b->y2 = y + h;
|
||||
b++;
|
||||
n++;
|
||||
}
|
||||
} else {
|
||||
for ( ; i < nr ; i++) {
|
||||
*b++ = *(drm_clip_rect_t *)&box[i];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
imesa->sarea->nbox = n;
|
||||
|
||||
savage_BCI_clear(ctx,&clear);
|
||||
if (flags) {
|
||||
GLboolean depthCleared = GL_FALSE;
|
||||
if (flags & (SAVAGE_FRONT|SAVAGE_BACK)) {
|
||||
drm_savage_cmd_header_t *cmd;
|
||||
cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
|
||||
cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
|
||||
if ((flags & SAVAGE_DEPTH) &&
|
||||
clearDepth == clearColor && depthMask == colorMask) {
|
||||
cmd[0].clear0.flags = flags;
|
||||
depthCleared = GL_TRUE;
|
||||
} else
|
||||
cmd[0].clear0.flags = flags & (SAVAGE_FRONT|SAVAGE_BACK);
|
||||
cmd[1].clear1.mask = colorMask;
|
||||
cmd[1].clear1.value = clearColor;
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE( imesa );
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS|SAVAGE_UPLOAD_CTX;
|
||||
if ((flags & SAVAGE_DEPTH) && !depthCleared) {
|
||||
drm_savage_cmd_header_t *cmd;
|
||||
cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
|
||||
cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
|
||||
cmd[0].clear0.flags = SAVAGE_DEPTH;
|
||||
cmd[1].clear1.mask = depthMask;
|
||||
cmd[1].clear1.value = clearDepth;
|
||||
}
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
|
||||
}
|
||||
|
||||
if (mask)
|
||||
@@ -318,7 +410,11 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This is necessary as to prevent annyoing stuttering effects with
|
||||
* some games, though it does reduce the frame rate (glxgears)
|
||||
* slightly. I believe this is due to texture uploads which do not go
|
||||
* through the Savage command pipeline yet. */
|
||||
#define SYNC_FRAMES 1
|
||||
|
||||
/*
|
||||
* Copy the back buffer to the front buffer.
|
||||
@@ -326,11 +422,9 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
void savageSwapBuffers( __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
savageContextPtr imesa;
|
||||
drm_clip_rect_t *pbox;
|
||||
int nbox;
|
||||
int i;
|
||||
|
||||
GLboolean pending;
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n================================\n", __FUNCTION__);
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
@@ -342,38 +436,30 @@ void savageSwapBuffers( __DRIdrawablePrivate *dPriv )
|
||||
|
||||
FLUSH_BATCH(imesa);
|
||||
|
||||
LOCK_HARDWARE( imesa );
|
||||
WAIT_IDLE_EMPTY;
|
||||
PAGE_PENDING(pending);
|
||||
#if SYNC_FRAMES
|
||||
imesa->lastSwap = savageEmitEvent( imesa, 0 );
|
||||
#endif
|
||||
if (imesa->lastSwap != 0)
|
||||
savageWaitEvent( imesa, imesa->lastSwap );
|
||||
|
||||
if(!pending)
|
||||
{
|
||||
pbox = dPriv->pClipRects;
|
||||
nbox = dPriv->numClipRects;
|
||||
|
||||
for (i = 0 ; i < nbox ; )
|
||||
{
|
||||
int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
|
||||
drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
|
||||
|
||||
imesa->sarea->nbox = nr - i;
|
||||
|
||||
for ( ; i < nr ; i++)
|
||||
*b++ = pbox[i];
|
||||
savage_BCI_swap(imesa) ;
|
||||
drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, 0);
|
||||
cmd->cmd.cmd = SAVAGE_CMD_SWAP;
|
||||
imesa->inSwap = GL_TRUE; /* ignore scissors in savageFlushCmdBuf */
|
||||
savageFlushCmdBuf(imesa, GL_FALSE);
|
||||
imesa->inSwap = GL_FALSE;
|
||||
}
|
||||
}
|
||||
UNLOCK_HARDWARE( imesa );
|
||||
|
||||
|
||||
#if !SYNC_FRAMES
|
||||
imesa->lastSwap = savageEmitEvent( imesa, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This waits for *everybody* to finish rendering -- overkill.
|
||||
*/
|
||||
void savageDmaFinish( savageContextPtr imesa )
|
||||
{
|
||||
savageDMAFlush(imesa);
|
||||
WAIT_IDLE_EMPTY;
|
||||
savageWaitEvent( imesa, savageEmitEventLocked( imesa, SAVAGE_WAIT_3D ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -393,152 +479,189 @@ void savageWaitAge( savageContextPtr imesa, int age )
|
||||
}
|
||||
|
||||
|
||||
|
||||
void savageFlushVerticesLocked( savageContextPtr imesa )
|
||||
unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags )
|
||||
{
|
||||
drmBufPtr buffer = imesa->vertex_dma_buffer;
|
||||
drm_savage_event_emit_t event;
|
||||
int ret;
|
||||
event.count = 0;
|
||||
event.flags = flags;
|
||||
ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_EMIT,
|
||||
&event, sizeof(event) );
|
||||
if (ret) {
|
||||
fprintf (stderr, "emit event returned %d\n", ret);
|
||||
exit (1);
|
||||
}
|
||||
return event.count;
|
||||
}
|
||||
unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags )
|
||||
{
|
||||
unsigned int ret;
|
||||
LOCK_HARDWARE( imesa );
|
||||
ret = savageEmitEventLocked( imesa, flags );
|
||||
UNLOCK_HARDWARE( imesa );
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
imesa->vertex_dma_buffer = NULL;
|
||||
|
||||
/* Lot's of stuff to do here. For now there is a fake DMA implementation
|
||||
* in savagedma.c that emits drawing commands. Cliprects are not handled
|
||||
* yet. */
|
||||
if (buffer->used) {
|
||||
/* State must be updated "per primitive" because hardware
|
||||
* culling must be disabled for unfilled primitives, points
|
||||
* and lines. */
|
||||
savageEmitHwStateLocked (imesa);
|
||||
savageFakeVertices (imesa, buffer);
|
||||
void savageWaitEvent( savageContextPtr imesa, unsigned int count )
|
||||
{
|
||||
drm_savage_event_wait_t event;
|
||||
int ret;
|
||||
event.count = count;
|
||||
event.flags = 0;
|
||||
ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_WAIT,
|
||||
&event, sizeof(event) );
|
||||
if (ret) {
|
||||
fprintf (stderr, "wait event returned %d\n", ret);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void savageFlushVertices( savageContextPtr imesa )
|
||||
void savageFlushVertices( savageContextPtr imesa )
|
||||
{
|
||||
struct savage_vtxbuf_t *buffer = imesa->vtxBuf;
|
||||
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (!buffer->total)
|
||||
return;
|
||||
|
||||
if (buffer->used > buffer->flushed) {
|
||||
drm_savage_cmd_header_t *cmd;
|
||||
/* State must be updated "per primitive" because hardware
|
||||
* culling must be disabled for unfilled primitives, points
|
||||
* and lines. */
|
||||
savageEmitChangedState (imesa);
|
||||
cmd = savageAllocCmdBuf(imesa, 0);
|
||||
cmd->prim.cmd = buffer == &imesa->dmaVtxBuf ?
|
||||
SAVAGE_CMD_DMA_PRIM : SAVAGE_CMD_VB_PRIM;
|
||||
cmd->prim.prim = imesa->HwPrim;
|
||||
cmd->prim.skip = imesa->skip;
|
||||
cmd->prim.start = buffer->flushed / imesa->HwVertexSize;
|
||||
cmd->prim.count = buffer->used / imesa->HwVertexSize - cmd->prim.start;
|
||||
buffer->flushed = buffer->used;
|
||||
/* Make sure we don't buffer too many vertices without
|
||||
* telling the hardware. */
|
||||
imesa->vertsPending += cmd->prim.count;
|
||||
if (imesa->vertsPending > SAVAGE_MAX_VERTS_PENDING) {
|
||||
savageFlushCmdBuf(imesa, GL_FALSE);
|
||||
imesa->vertsPending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
|
||||
drm_savage_cmdbuf_t cmdbuf;
|
||||
drm_savage_cmd_header_t *start;
|
||||
int ret;
|
||||
|
||||
/* If we lost the context we must restore the initial state (at
|
||||
* the start of the command buffer). */
|
||||
if (imesa->lostContext) {
|
||||
start = imesa->cmdBuf.base;
|
||||
imesa->lostContext = GL_FALSE;
|
||||
} else
|
||||
start = imesa->cmdBuf.start;
|
||||
|
||||
if (!imesa->dmaVtxBuf.total)
|
||||
discard = GL_FALSE;
|
||||
|
||||
if ((SAVAGE_DEBUG & DEBUG_DMA) && discard)
|
||||
fprintf (stderr, "Discarding DMA buffer, used=%u\n",
|
||||
imesa->dmaVtxBuf.used);
|
||||
|
||||
cmdbuf.dma_idx = imesa->dmaVtxBuf.idx;
|
||||
cmdbuf.discard = discard;
|
||||
cmdbuf.vb_addr = imesa->clientVtxBuf.buf;
|
||||
cmdbuf.vb_size = imesa->clientVtxBuf.total*4;
|
||||
cmdbuf.vb_stride = imesa->HwVertexSize;
|
||||
cmdbuf.cmd_addr = start;
|
||||
cmdbuf.size = (imesa->cmdBuf.write - start);
|
||||
if (!imesa->inSwap && imesa->glCtx->Scissor.Enabled) {
|
||||
drm_clip_rect_t *box = dPriv->pClipRects, *ibox;
|
||||
GLuint nbox = dPriv->numClipRects, nibox;
|
||||
ibox = malloc(dPriv->numClipRects*sizeof(drm_clip_rect_t));
|
||||
if (!ibox) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
exit(1);
|
||||
}
|
||||
nibox = savageIntersectClipRects(ibox, box, nbox, &imesa->scissor_rect);
|
||||
cmdbuf.nbox = nibox;
|
||||
cmdbuf.box_addr = ibox;
|
||||
} else {
|
||||
cmdbuf.nbox = dPriv->numClipRects;
|
||||
cmdbuf.box_addr = dPriv->pClipRects;
|
||||
}
|
||||
|
||||
ret = drmCommandWrite( imesa->driFd, DRM_SAVAGE_BCI_CMDBUF,
|
||||
&cmdbuf, sizeof(cmdbuf) );
|
||||
if (ret) {
|
||||
fprintf (stderr, "cmdbuf ioctl returned %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (cmdbuf.box_addr != dPriv->pClipRects) {
|
||||
free(cmdbuf.box_addr);
|
||||
}
|
||||
|
||||
if (discard) {
|
||||
imesa->dmaVtxBuf.total = 0;
|
||||
imesa->dmaVtxBuf.used = 0;
|
||||
imesa->dmaVtxBuf.flushed = 0;
|
||||
}
|
||||
imesa->clientVtxBuf.used = 0;
|
||||
imesa->clientVtxBuf.flushed = 0;
|
||||
|
||||
imesa->cmdBuf.write = imesa->cmdBuf.base;
|
||||
|
||||
/* Save the current state at the start of the command buffer. That
|
||||
* state will only be emitted, if the context was lost since the
|
||||
* last command buffer. */
|
||||
savageEmitOldState(imesa);
|
||||
imesa->cmdBuf.start = imesa->cmdBuf.write;
|
||||
}
|
||||
|
||||
|
||||
void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard )
|
||||
{
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n", __FUNCTION__);
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushVerticesLocked (imesa);
|
||||
savageFlushCmdBufLocked (imesa, discard);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
}
|
||||
|
||||
|
||||
int savage_check_copy(int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void savageDDFlush( GLcontext *ctx )
|
||||
{
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n", __FUNCTION__);
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
savageFlushVertices (imesa);
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushVerticesLocked (imesa);
|
||||
savageDMAFlush (imesa);
|
||||
savageFlushCmdBufLocked(imesa, GL_FALSE);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
}
|
||||
|
||||
static void savageDDFinish( GLcontext *ctx )
|
||||
{
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "%s\n", __FUNCTION__);
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
savageFlushVertices (imesa);
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushVerticesLocked (imesa);
|
||||
savageFlushCmdBufLocked(imesa, GL_FALSE);
|
||||
savageDmaFinish (imesa);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
}
|
||||
|
||||
#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60))
|
||||
#define STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c00))
|
||||
#define MAXFIFO_S4 0x7F00
|
||||
#define MAXFIFO_S3D 0x7F00
|
||||
|
||||
static GLboolean savagePagePending_s4( savageContextPtr imesa ) {
|
||||
return (ALT_STATUS_WORD0 & 0x08000000) ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
static GLboolean savagePagePending_s3d( savageContextPtr imesa ) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
static void savageWaitForFIFO_s4( savageContextPtr imesa, unsigned count ) {
|
||||
int loop = 0;
|
||||
int slots = MAXFIFO_S4-count;
|
||||
while((ALT_STATUS_WORD0 & 0x001fffff) > slots && loop++ < MAXLOOP);
|
||||
}
|
||||
static void savageWaitForFIFO_s3d( savageContextPtr imesa, unsigned count ) {
|
||||
int loop = 0;
|
||||
int slots = MAXFIFO_S3D-count;
|
||||
while((STATUS_WORD0 & 0x0001ffff) > slots && loop++ < MAXLOOP);
|
||||
}
|
||||
static void savageWaitIdleEmpty_s4( savageContextPtr imesa ) {
|
||||
int loop = 0;
|
||||
while((ALT_STATUS_WORD0 & 0x00ffffff) != 0x00E00000L && loop++ < MAXLOOP);
|
||||
}
|
||||
static void savageWaitIdleEmpty_s3d( savageContextPtr imesa ) {
|
||||
int loop = 0;
|
||||
while((STATUS_WORD0 & 0x000fffff) != 0x000E0000L && loop++ < MAXLOOP);
|
||||
}
|
||||
|
||||
GLboolean (*savagePagePending)( savageContextPtr imesa ) = NULL;
|
||||
void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ) = NULL;
|
||||
void (*savageWaitIdleEmpty)( savageContextPtr imesa ) = NULL;
|
||||
|
||||
|
||||
void savageDDInitIoctlFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.Clear = savageDDClear;
|
||||
ctx->Driver.Flush = savageDDFlush;
|
||||
ctx->Driver.Finish = savageDDFinish;
|
||||
if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) {
|
||||
savagePagePending = savagePagePending_s4;
|
||||
savageWaitForFIFO = savageWaitForFIFO_s4;
|
||||
savageWaitIdleEmpty = savageWaitIdleEmpty_s4;
|
||||
} else {
|
||||
savagePagePending = savagePagePending_s3d;
|
||||
savageWaitForFIFO = savageWaitForFIFO_s3d;
|
||||
savageWaitIdleEmpty = savageWaitIdleEmpty_s3d;
|
||||
}
|
||||
}
|
||||
|
||||
#if SAVAGE_CMD_DMA
|
||||
/* Alloc a continuous memory */
|
||||
/* return: 0 error when kernel alloc pages(can try a half memory size)
|
||||
>0 sucess
|
||||
<0 Other error*/
|
||||
int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req)
|
||||
{
|
||||
int ret;
|
||||
if (req ==NULL)
|
||||
return 0;
|
||||
|
||||
if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_ALLOC_CONTINUOUS_MEM, req)) <=0)
|
||||
return ret;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* get the physics address*/
|
||||
GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer)
|
||||
{
|
||||
|
||||
drm_savage_get_physcis_address_t req;
|
||||
int ret;
|
||||
|
||||
req.v_address = (GLuint )pointer;
|
||||
ret = ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS,&req);
|
||||
|
||||
return req.p_address;
|
||||
}
|
||||
|
||||
/* free the buffer got by savageAllocDMABuffe*/
|
||||
int savageFreeDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req)
|
||||
{
|
||||
GLuint ret;
|
||||
if (req ==NULL)
|
||||
return 0;
|
||||
|
||||
if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_FREE_CONTINUOUS_MEM, req)) <=0)
|
||||
return ret;
|
||||
return 1;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,17 +27,22 @@
|
||||
#define SAVAGE_IOCTL_H
|
||||
|
||||
#include "savagecontext.h"
|
||||
#include "savagedma.h"
|
||||
|
||||
void savageGetGeneralDmaBufferLocked( savageContextPtr mmesa );
|
||||
|
||||
void savageFlushVertices( savageContextPtr mmesa );
|
||||
void savageFlushVerticesLocked( savageContextPtr mmesa );
|
||||
|
||||
void savageFlushGeneralLocked( savageContextPtr imesa );
|
||||
void savageWaitAgeLocked( savageContextPtr imesa, int age );
|
||||
void savageWaitAge( savageContextPtr imesa, int age );
|
||||
|
||||
unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags );
|
||||
unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags );
|
||||
void savageWaitEvent( savageContextPtr imesa, unsigned int event);
|
||||
|
||||
void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard );
|
||||
void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard );
|
||||
|
||||
void savageDmaFinish( savageContextPtr imesa );
|
||||
|
||||
void savageRegetLockQuiescent( savageContextPtr imesa );
|
||||
@@ -46,54 +51,69 @@ void savageDDInitIoctlFuncs( GLcontext *ctx );
|
||||
|
||||
void savageSwapBuffers( __DRIdrawablePrivate *dPriv );
|
||||
|
||||
int savage_check_copy(int fd);
|
||||
|
||||
extern GLboolean (*savagePagePending)( savageContextPtr imesa );
|
||||
extern void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count );
|
||||
extern void (*savageWaitIdleEmpty)( savageContextPtr imesa );
|
||||
|
||||
#define PAGE_PENDING(result) do { \
|
||||
result = savagePagePending(imesa); \
|
||||
} while (0)
|
||||
#define WAIT_FOR_FIFO(count) do { \
|
||||
savageWaitForFIFO(imesa, count); \
|
||||
} while (0)
|
||||
#define WAIT_IDLE_EMPTY do { \
|
||||
savageWaitIdleEmpty(imesa); \
|
||||
savageWaitEvent(imesa, \
|
||||
savageEmitEvent(imesa, SAVAGE_WAIT_3D|SAVAGE_WAIT_2D)); \
|
||||
} while (0)
|
||||
|
||||
#if SAVAGE_CMD_DMA
|
||||
int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req);
|
||||
GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer);
|
||||
int savageFreeDMABuffer(savageContextPtr, drm_savage_alloc_cont_mem_t*);
|
||||
#endif
|
||||
|
||||
#define FLUSH_BATCH(imesa) do { \
|
||||
if (imesa->vertex_dma_buffer) savageFlushVertices(imesa); \
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) \
|
||||
fprintf (stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
|
||||
savageFlushVertices(imesa); \
|
||||
savageFlushCmdBuf(imesa, GL_FALSE); \
|
||||
} while (0)
|
||||
|
||||
extern void savageGetDMABuffer( savageContextPtr imesa );
|
||||
|
||||
static __inline
|
||||
u_int32_t *savageAllocDmaLow( savageContextPtr imesa, GLuint bytes )
|
||||
u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )
|
||||
{
|
||||
struct savage_vtxbuf_t *buffer = imesa->vtxBuf;
|
||||
u_int32_t *head;
|
||||
|
||||
if (!imesa->vertex_dma_buffer) {
|
||||
LOCK_HARDWARE(imesa);
|
||||
imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
} else if (imesa->vertex_dma_buffer->used + bytes >
|
||||
imesa->vertex_dma_buffer->total) {
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushVerticesLocked( imesa );
|
||||
imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
if (buffer == &imesa->dmaVtxBuf) {
|
||||
if (!buffer->total) {
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageGetDMABuffer(imesa);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
} else if (buffer->used + words > buffer->total) {
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "... flushing DMA buffer in %s\n",
|
||||
__FUNCTION__);
|
||||
savageFlushVertices( imesa );
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushCmdBufLocked(imesa, GL_TRUE); /* discard DMA buffer */
|
||||
savageGetDMABuffer(imesa);
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
}
|
||||
} else if (buffer->used + words > buffer->total) {
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "... flushing client vertex buffer in %s\n",
|
||||
__FUNCTION__);
|
||||
savageFlushVertices( imesa );
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushCmdBufLocked(imesa, GL_FALSE); /* free clientVtxBuf */
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
}
|
||||
|
||||
head = (u_int32_t *)((u_int8_t *)imesa->vertex_dma_buffer->address +
|
||||
imesa->vertex_dma_buffer->used);
|
||||
head = &buffer->buf[buffer->used];
|
||||
|
||||
imesa->vertex_dma_buffer->used += bytes;
|
||||
buffer->used += words;
|
||||
return head;
|
||||
}
|
||||
|
||||
static __inline
|
||||
drm_savage_cmd_header_t *savageAllocCmdBuf( savageContextPtr imesa, GLuint bytes )
|
||||
{
|
||||
drm_savage_cmd_header_t *ret;
|
||||
GLuint qwords = ((bytes + 7) >> 3) + 1; /* round up */
|
||||
assert (qwords < imesa->cmdBuf.size);
|
||||
if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size) {
|
||||
savageFlushCmdBuf(imesa, GL_FALSE);
|
||||
}
|
||||
ret = (drm_savage_cmd_header_t *)imesa->cmdBuf.write;
|
||||
imesa->cmdBuf.write += qwords;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define DBG 0
|
||||
|
||||
#define LOCAL_VARS \
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
|
||||
__DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \
|
||||
savageScreenPrivate *savageScreen = imesa->savageScreen; \
|
||||
GLuint cpp = savageScreen->cpp; \
|
||||
@@ -48,6 +49,7 @@
|
||||
(void) read_buf; (void) buf; (void) p
|
||||
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
|
||||
__DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \
|
||||
savageScreenPrivate *savageScreen = imesa->savageScreen; \
|
||||
GLuint zpp = savageScreen->zpp; \
|
||||
@@ -77,8 +79,7 @@
|
||||
|
||||
#define Y_FLIP(_y) (height - _y - 1)
|
||||
|
||||
#define HW_LOCK() savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
|
||||
WAIT_IDLE_EMPTY;\
|
||||
#define HW_LOCK()
|
||||
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
@@ -95,11 +96,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if 0
|
||||
#define HW_UNLOCK() \
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
#endif
|
||||
#define HW_UNLOCK() { }
|
||||
#define HW_UNLOCK()
|
||||
|
||||
|
||||
/* 16 bit, 565 rgb color spanline and pixel functions
|
||||
@@ -161,58 +158,91 @@ do { \
|
||||
|
||||
|
||||
|
||||
/* 16 bit depthbuffer functions.
|
||||
/* 16 bit integer depthbuffer functions
|
||||
* Depth range is reversed. See also savageCalcViewport.
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
do{ \
|
||||
*(GLushort *)(buf + (_x<<1) + _y*pitch) = d; \
|
||||
}while(0)
|
||||
|
||||
*(GLushort *)(buf + ((_x)<<1) + (_y)*pitch) = 0xFFFF - d
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
do{ \
|
||||
d = *(GLushort *)(buf + (_x<<1) + _y*pitch); \
|
||||
}while(0)
|
||||
|
||||
/* d = 0xffff; */
|
||||
|
||||
d = 0xFFFF - *(GLushort *)(buf + ((_x)<<1) + (_y)*pitch)
|
||||
|
||||
#define TAG(x) savage##x##_16
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 8-bit stencil /24-bit depth depthbuffer functions.
|
||||
|
||||
/* 16 bit float depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) { \
|
||||
GLuint tmp = *(GLuint *)(buf + (_x<<2) + _y*pitch); \
|
||||
tmp &= 0xFF000000; \
|
||||
tmp |= d; \
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
*(GLushort *)(buf + ((_x)<<1) + (_y)*pitch) = \
|
||||
savageEncodeFloat16( 1.0 - (GLfloat)d/65535.0 )
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = 65535 - \
|
||||
savageDecodeFloat16( *(GLushort *)(buf + ((_x)<<1) + (_y)*pitch) ) * \
|
||||
65535.0
|
||||
|
||||
#define TAG(x) savage##x##_16f
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 8-bit stencil /24-bit integer depth depthbuffer functions.
|
||||
* Depth range is reversed. See also savageCalcViewport.
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) do { \
|
||||
GLuint tmp = *(GLuint *)(buf + ((_x)<<2) + (_y)*pitch); \
|
||||
tmp &= 0xFF000000; \
|
||||
tmp |= 0x00FFFFFF - d; \
|
||||
*(GLuint *)(buf + (_x<<2) + _y*pitch) = tmp; \
|
||||
}
|
||||
} while(0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + (_x<<2) + _y*pitch) & 0x00FFFFFF;
|
||||
|
||||
/* d = 0x00ffffff; */
|
||||
d = 0x00FFFFFF - (*(GLuint *)(buf + ((_x)<<2) + (_y)*pitch) & 0x00FFFFFF)
|
||||
|
||||
#define TAG(x) savage##x##_8_24
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
#define WRITE_STENCIL( _x, _y, d ) { \
|
||||
GLuint tmp = *(GLuint *)(buf + (_x<<2) + _y*pitch); \
|
||||
tmp &= 0x00FFFFFF; \
|
||||
tmp |= (((GLuint)d)<<24) & 0xFF000000; \
|
||||
*(GLuint *)(buf + (_x<<2) + _y*pitch) = tmp; \
|
||||
}
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
d = (GLstencil)((*(GLuint *)(buf + (_x<<2) + _y*pitch) & 0xFF000000) >> 24);
|
||||
|
||||
|
||||
|
||||
|
||||
/* 24 bit float depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) do { \
|
||||
GLuint tmp = *(GLuint *)(buf + ((_x)<<2) + (_y)*pitch); \
|
||||
tmp &= 0xFF000000; \
|
||||
tmp |= savageEncodeFloat24( 1.0 - (GLfloat)d/16777215.0 ); \
|
||||
*(GLuint *)(buf + (_x<<2) + _y*pitch) = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = 16777215 - savageDecodeFloat24( \
|
||||
*(GLuint *)(buf + ((_x)<<2) + (_y)*pitch) & 0x00FFFFFF) \
|
||||
* 16777215.0
|
||||
|
||||
#define TAG(x) savage##x##_8_24f
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
#define WRITE_STENCIL( _x, _y, d ) do { \
|
||||
GLuint tmp = *(GLuint *)(buf + ((_x)<<2) + (_y)*pitch); \
|
||||
tmp &= 0x00FFFFFF; \
|
||||
tmp |= (((GLuint)d)<<24) & 0xFF000000; \
|
||||
*(GLuint *)(buf + ((_x)<<2) + (_y)*pitch) = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
d = (GLstencil)((*(GLuint *)(buf + ((_x)<<2) + (_y)*pitch) & 0xFF000000) >> 24)
|
||||
|
||||
#define TAG(x) savage##x##_8_24
|
||||
#include "stenciltmp.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function is called to specify which buffer to read and write
|
||||
@@ -241,6 +271,58 @@ static void savageDDSetBuffer(GLcontext *ctx, GLframebuffer *buffer,
|
||||
? imesa->driDrawable : imesa->driReadable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers around _swrast_Copy/Draw/ReadPixels that make sure all
|
||||
* primitives are flushed and the hardware is idle before accessing
|
||||
* the frame buffer.
|
||||
*/
|
||||
static void
|
||||
savageCopyPixels( GLcontext *ctx,
|
||||
GLint srcx, GLint srcy, GLsizei width, GLsizei height,
|
||||
GLint destx, GLint desty,
|
||||
GLenum type )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
FLUSH_BATCH(imesa);
|
||||
WAIT_IDLE_EMPTY;
|
||||
_swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
|
||||
}
|
||||
static void
|
||||
savageDrawPixels( GLcontext *ctx,
|
||||
GLint x, GLint y,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
const GLvoid *pixels )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
FLUSH_BATCH(imesa);
|
||||
WAIT_IDLE_EMPTY;
|
||||
_swrast_DrawPixels(ctx, x, y, width, height, format, type, packing, pixels);
|
||||
}
|
||||
static void
|
||||
savageReadPixels( GLcontext *ctx,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
GLvoid *pixels )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
FLUSH_BATCH(imesa);
|
||||
WAIT_IDLE_EMPTY;
|
||||
_swrast_ReadPixels(ctx, x, y, width, height, format, type, packing, pixels);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the hardware is idle when span-rendering.
|
||||
*/
|
||||
static void savageSpanRenderStart( GLcontext *ctx )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
FLUSH_BATCH(imesa);
|
||||
WAIT_IDLE_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
void savageDDInitSpanFuncs( GLcontext *ctx )
|
||||
{
|
||||
@@ -274,18 +356,36 @@ void savageDDInitSpanFuncs( GLcontext *ctx )
|
||||
|
||||
switch (imesa->savageScreen->zpp)
|
||||
{
|
||||
case 2:
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_16;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_16;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_16;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_16;
|
||||
case 2:
|
||||
if (imesa->float_depth) {
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_16f;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_16f;
|
||||
swdd->WriteMonoDepthSpan = savageWriteMonoDepthSpan_16f;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_16f;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_16f;
|
||||
} else {
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_16;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_16;
|
||||
swdd->WriteMonoDepthSpan = savageWriteMonoDepthSpan_16;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_16;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_16;
|
||||
}
|
||||
|
||||
break;
|
||||
case 4:
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_8_24;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_8_24;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_8_24;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_8_24;
|
||||
if (imesa->float_depth) {
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_8_24f;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_8_24f;
|
||||
swdd->WriteMonoDepthSpan = savageWriteMonoDepthSpan_8_24f;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_8_24f;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_8_24f;
|
||||
} else {
|
||||
swdd->ReadDepthSpan = savageReadDepthSpan_8_24;
|
||||
swdd->WriteDepthSpan = savageWriteDepthSpan_8_24;
|
||||
swdd->WriteMonoDepthSpan = savageWriteMonoDepthSpan_8_24;
|
||||
swdd->ReadDepthPixels = savageReadDepthPixels_8_24;
|
||||
swdd->WriteDepthPixels = savageWriteDepthPixels_8_24;
|
||||
}
|
||||
swdd->ReadStencilSpan = savageReadStencilSpan_8_24;
|
||||
swdd->WriteStencilSpan = savageWriteStencilSpan_8_24;
|
||||
swdd->ReadStencilPixels = savageReadStencilPixels_8_24;
|
||||
@@ -301,11 +401,13 @@ void savageDDInitSpanFuncs( GLcontext *ctx )
|
||||
swdd->ReadCI32Span =NULL;
|
||||
swdd->ReadCI32Pixels =NULL;
|
||||
|
||||
swdd->SpanRenderStart = savageSpanRenderStart;
|
||||
|
||||
/* 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;
|
||||
ctx->Driver.CopyPixels = savageCopyPixels;
|
||||
ctx->Driver.DrawPixels = savageDrawPixels;
|
||||
ctx->Driver.ReadPixels = savageReadPixels;
|
||||
}
|
||||
|
||||
@@ -27,4 +27,102 @@
|
||||
|
||||
extern void savageDDInitSpanFuncs( GLcontext *ctx );
|
||||
|
||||
/*
|
||||
* Savage 16-bit float depth format with zExpOffset=16:
|
||||
* 4 bit unsigned exponent, 12 bit mantissa
|
||||
*
|
||||
* The meaning of the mantissa is different from IEEE floatint point
|
||||
* formats. The same number can't be encoded with different exponents.
|
||||
* So no bits are wasted.
|
||||
*
|
||||
* exponent | range encoded by mantissa | accuracy or mantissa
|
||||
* ---------+---------------------------+---------------------
|
||||
* 15 | 2^-1 .. 1 | 2^-13
|
||||
* 14 | 2^-2 .. 2^-1 | 2^-14
|
||||
* 13 | 2^-3 .. 2^-2 | 2^-15
|
||||
* ... | ... |
|
||||
* 2 | 2^-14 .. 2^-13 | 2^-27
|
||||
* 1 | 2^-15 .. 2^-14 | 2^-27
|
||||
* 0 | 2^-16 .. 2^-15 | 2^-28
|
||||
*
|
||||
* Note that there is no encoding for numbers < 2^-16.
|
||||
*/
|
||||
static __inline GLuint savageEncodeFloat16( GLdouble x )
|
||||
{
|
||||
GLint r = (GLint)(x * 0x10000000);
|
||||
GLint exp = 0;
|
||||
if (r < 0x1000)
|
||||
return 0;
|
||||
while (r - 0x1000 > 0x0fff) {
|
||||
r >>= 1;
|
||||
exp++;
|
||||
}
|
||||
return exp > 0xf ? 0xffff : (r - 0x1000) | (exp << 12);
|
||||
}
|
||||
static __inline GLdouble savageDecodeFloat16( GLuint x )
|
||||
{
|
||||
static const GLdouble pow2[16] = {
|
||||
1.0/(1<<28), 1.0/(1<<27), 1.0/(1<<26), 1.0/(1<<25),
|
||||
1.0/(1<<24), 1.0/(1<<23), 1.0/(1<<22), 1.0/(1<<21),
|
||||
1.0/(1<<20), 1.0/(1<<19), 1.0/(1<<18), 1.0/(1<<17),
|
||||
1.0/(1<<16), 1.0/(1<<15), 1.0/(1<<14), 1.0/(1<<13)
|
||||
};
|
||||
static const GLdouble bias[16] = {
|
||||
1.0/(1<<16), 1.0/(1<<15), 1.0/(1<<14), 1.0/(1<<13),
|
||||
1.0/(1<<12), 1.0/(1<<11), 1.0/(1<<10), 1.0/(1<< 9),
|
||||
1.0/(1<< 8), 1.0/(1<< 7), 1.0/(1<< 6), 1.0/(1<< 5),
|
||||
1.0/(1<< 4), 1.0/(1<< 3), 1.0/(1<< 2), 1.0/(1<< 1)
|
||||
};
|
||||
GLuint mant = x & 0x0fff;
|
||||
GLuint exp = (x >> 12) & 0xf;
|
||||
return bias[exp] + pow2[exp]*mant;
|
||||
}
|
||||
|
||||
/*
|
||||
* Savage 24-bit float depth format with zExpOffset=32:
|
||||
* 5 bit unsigned exponent, 19 bit mantissa
|
||||
*
|
||||
* Details analogous to the 16-bit format.
|
||||
*/
|
||||
static __inline GLuint savageEncodeFloat24( GLdouble x )
|
||||
{
|
||||
int64_t r = (int64_t)(x * ((int64_t)1 << (19+32)));
|
||||
GLint exp = 0;
|
||||
if (r < 0x80000)
|
||||
return 0;
|
||||
while (r - 0x80000 > 0x7ffff) {
|
||||
r >>= 1;
|
||||
exp++;
|
||||
}
|
||||
return exp > 0x1f ? 0xffffff : (r - 0x80000) | (exp << 19);
|
||||
}
|
||||
#define _1 (int64_t)1
|
||||
static __inline GLdouble savageDecodeFloat24( GLuint x )
|
||||
{
|
||||
static const GLdouble pow2[32] = {
|
||||
1.0/(_1<<51), 1.0/(_1<<50), 1.0/(_1<<49), 1.0/(_1<<48),
|
||||
1.0/(_1<<47), 1.0/(_1<<46), 1.0/(_1<<45), 1.0/(_1<<44),
|
||||
1.0/(_1<<43), 1.0/(_1<<42), 1.0/(_1<<41), 1.0/(_1<<40),
|
||||
1.0/(_1<<39), 1.0/(_1<<38), 1.0/(_1<<37), 1.0/(_1<<36),
|
||||
1.0/(_1<<35), 1.0/(_1<<34), 1.0/(_1<<33), 1.0/(_1<<32),
|
||||
1.0/(_1<<31), 1.0/(_1<<30), 1.0/(_1<<29), 1.0/(_1<<28),
|
||||
1.0/(_1<<27), 1.0/(_1<<26), 1.0/(_1<<25), 1.0/(_1<<24),
|
||||
1.0/(_1<<23), 1.0/(_1<<22), 1.0/(_1<<21), 1.0/(_1<<20)
|
||||
};
|
||||
static const GLdouble bias[32] = {
|
||||
1.0/(_1<<32), 1.0/(_1<<31), 1.0/(_1<<30), 1.0/(_1<<29),
|
||||
1.0/(_1<<28), 1.0/(_1<<27), 1.0/(_1<<26), 1.0/(_1<<25),
|
||||
1.0/(_1<<24), 1.0/(_1<<23), 1.0/(_1<<22), 1.0/(_1<<21),
|
||||
1.0/(_1<<20), 1.0/(_1<<19), 1.0/(_1<<18), 1.0/(_1<<17),
|
||||
1.0/(_1<<16), 1.0/(_1<<15), 1.0/(_1<<14), 1.0/(_1<<13),
|
||||
1.0/(_1<<12), 1.0/(_1<<11), 1.0/(_1<<10), 1.0/(_1<< 9),
|
||||
1.0/(_1<< 8), 1.0/(_1<< 7), 1.0/(_1<< 6), 1.0/(_1<< 5),
|
||||
1.0/(_1<< 4), 1.0/(_1<< 3), 1.0/(_1<< 2), 1.0/(_1<< 1)
|
||||
};
|
||||
GLuint mant = x & 0x7ffff;
|
||||
GLuint exp = (x >> 19) & 0x1f;
|
||||
return bias[exp] + pow2[exp]*mant;
|
||||
}
|
||||
#undef _1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,16 +69,10 @@ static __inline__ GLuint savagePackColor(GLuint format,
|
||||
|
||||
static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
/* This can be done in BlendFunc*/
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageBlendFunc_s4(ctx);
|
||||
}
|
||||
static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
/* This can be done in BlendFunc*/
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageBlendFunc_s3d(ctx);
|
||||
}
|
||||
|
||||
@@ -103,6 +97,9 @@ static void savageDDBlendEquationSeparate(GLcontext *ctx,
|
||||
static void savageBlendFunc_s4(GLcontext *ctx)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
|
||||
u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui;
|
||||
u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui;
|
||||
|
||||
/* set up draw control register (including blending, alpha
|
||||
* test, and shading model)
|
||||
@@ -266,11 +263,17 @@ static void savageBlendFunc_s4(GLcontext *ctx)
|
||||
/*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
|
||||
~drawLocalCtrl.ni.wrZafterAlphaTst;*/
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui ||
|
||||
drawCtrl1 != imesa->regs.s4.drawCtrl1.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
static void savageBlendFunc_s3d(GLcontext *ctx)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
|
||||
u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
|
||||
|
||||
/* set up draw control register (including blending, alpha
|
||||
* test, dithering, and shading model)
|
||||
@@ -432,7 +435,9 @@ static void savageBlendFunc_s3d(GLcontext *ctx)
|
||||
imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst =
|
||||
imesa->regs.s3d.drawCtrl.ni.alphaTestEn;
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
|
||||
zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
|
||||
static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB,
|
||||
@@ -456,21 +461,23 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
ZCmpFunc zmode;
|
||||
#define depthIndex 0
|
||||
u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
|
||||
u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
|
||||
u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */
|
||||
|
||||
/* set up z-buffer control register (global)
|
||||
* set up z-buffer offset register (global)
|
||||
* set up z read/write watermarks register (global)
|
||||
*/
|
||||
|
||||
switch(func) {
|
||||
switch(func) { /* reversed (see savageCalcViewport) */
|
||||
case GL_NEVER: zmode = CF_Never; break;
|
||||
case GL_ALWAYS: zmode = CF_Always; break;
|
||||
case GL_LESS: zmode = CF_Less; break;
|
||||
case GL_LEQUAL: zmode = CF_LessEqual; break;
|
||||
case GL_LESS: zmode = CF_Greater; break;
|
||||
case GL_LEQUAL: zmode = CF_GreaterEqual; break;
|
||||
case GL_EQUAL: zmode = CF_Equal; break;
|
||||
case GL_GREATER: zmode = CF_Greater; break;
|
||||
case GL_GEQUAL: zmode = CF_GreaterEqual; break;
|
||||
case GL_GREATER: zmode = CF_Less; break;
|
||||
case GL_GEQUAL: zmode = CF_LessEqual; break;
|
||||
case GL_NOTEQUAL: zmode = CF_NotEqual; break;
|
||||
default:return;
|
||||
}
|
||||
@@ -513,27 +520,33 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
|
||||
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
|
||||
imesa->regs.s4.zWatermarks.ni.wLow = 8;
|
||||
}
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
|
||||
zWatermarks != imesa->regs.s4.zWatermarks.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
ZCmpFunc zmode;
|
||||
#define depthIndex 0
|
||||
u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
|
||||
u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
|
||||
u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */
|
||||
|
||||
/* set up z-buffer control register (global)
|
||||
* set up z-buffer offset register (global)
|
||||
* set up z read/write watermarks register (global)
|
||||
*/
|
||||
switch(func) {
|
||||
switch(func) { /* reversed (see savageCalcViewport) */
|
||||
case GL_NEVER: zmode = CF_Never; break;
|
||||
case GL_ALWAYS: zmode = CF_Always; break;
|
||||
case GL_LESS: zmode = CF_Less; break;
|
||||
case GL_LEQUAL: zmode = CF_LessEqual; break;
|
||||
case GL_LESS: zmode = CF_Greater; break;
|
||||
case GL_LEQUAL: zmode = CF_GreaterEqual; break;
|
||||
case GL_EQUAL: zmode = CF_Equal; break;
|
||||
case GL_GREATER: zmode = CF_Greater; break;
|
||||
case GL_GEQUAL: zmode = CF_GreaterEqual; break;
|
||||
case GL_GREATER: zmode = CF_Less; break;
|
||||
case GL_GEQUAL: zmode = CF_LessEqual; break;
|
||||
case GL_NOTEQUAL: zmode = CF_NotEqual; break;
|
||||
default:return;
|
||||
}
|
||||
@@ -565,14 +578,18 @@ static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
|
||||
imesa->regs.s3d.zWatermarks.ni.wLow = 8;
|
||||
}
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
|
||||
zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
if (zWatermarks != imesa->regs.s3d.zWatermarks.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
|
||||
static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (flag)
|
||||
{
|
||||
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
|
||||
@@ -582,12 +599,15 @@ static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
|
||||
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
|
||||
}
|
||||
savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
|
||||
|
||||
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (flag)
|
||||
{
|
||||
imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
|
||||
@@ -597,6 +617,9 @@ static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
|
||||
imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
|
||||
}
|
||||
savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
|
||||
|
||||
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -629,6 +652,7 @@ static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,
|
||||
static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui;
|
||||
|
||||
/*
|
||||
* _DrawDestMask is easier to cope with than <mode>.
|
||||
@@ -641,7 +665,6 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
|
||||
imesa->readMap = (char *)imesa->apertureBase[TARGET_FRONT];
|
||||
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
|
||||
imesa->NotFirstFrame = GL_FALSE;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX;
|
||||
savageXMesaSetFrontClipRects( imesa );
|
||||
FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
||||
break;
|
||||
@@ -651,7 +674,6 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
|
||||
imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
|
||||
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
|
||||
imesa->NotFirstFrame = GL_FALSE;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX;
|
||||
savageXMesaSetBackClipRects( imesa );
|
||||
FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
||||
break;
|
||||
@@ -664,6 +686,9 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
|
||||
* gets called.
|
||||
*/
|
||||
_swrast_DrawBuffer(ctx, mode);
|
||||
|
||||
if (destCtrl != imesa->regs.s4.destCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
|
||||
static void savageDDReadBuffer(GLcontext *ctx, GLenum mode )
|
||||
@@ -691,14 +716,22 @@ static void savageCalcViewport( GLcontext *ctx )
|
||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||
GLfloat *m = imesa->hw_viewport;
|
||||
|
||||
/* See also mga_translate_vertex.
|
||||
*/
|
||||
m[MAT_SX] = v[MAT_SX];
|
||||
m[MAT_TX] = v[MAT_TX] + imesa->drawX + SUBPIXEL_X;
|
||||
m[MAT_SY] = - v[MAT_SY];
|
||||
m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y;
|
||||
m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale;
|
||||
m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale;
|
||||
/* Depth range is reversed (far: 0, near: 1) so that float depth
|
||||
* compensates for loss of accuracy of far coordinates. */
|
||||
if (imesa->float_depth && imesa->savageScreen->zpp == 2) {
|
||||
/* The Savage 16-bit floating point depth format can't encode
|
||||
* numbers < 2^-16. Make sure all depth values stay greater
|
||||
* than that. */
|
||||
m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale * (65535.0/65536.0);
|
||||
m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale * (65535.0/65536.0);
|
||||
} else {
|
||||
m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale;
|
||||
m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale;
|
||||
}
|
||||
|
||||
imesa->SetupNewInputs = ~0;
|
||||
}
|
||||
@@ -800,12 +833,12 @@ static void savageUpdateCull( GLcontext *ctx )
|
||||
if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
|
||||
if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) {
|
||||
imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
} else {
|
||||
if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) {
|
||||
imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
}
|
||||
#endif /* end #if HW_CULL */
|
||||
@@ -846,7 +879,7 @@ static void savageDDColorMask_s4(GLcontext *ctx,
|
||||
{
|
||||
imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
/* TODO: need a software fallback */
|
||||
}
|
||||
static void savageDDColorMask_s3d(GLcontext *ctx,
|
||||
@@ -873,7 +906,7 @@ static void savageDDColorMask_s3d(GLcontext *ctx,
|
||||
{
|
||||
imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
/* TODO: need a software fallback */
|
||||
}
|
||||
|
||||
@@ -886,6 +919,7 @@ static void savageDDColorMask_s3d(GLcontext *ctx,
|
||||
*/
|
||||
static void savageUpdateSpecular_s4(GLcontext *ctx) {
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
|
||||
|
||||
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
|
||||
ctx->Light.Enabled) {
|
||||
@@ -895,10 +929,13 @@ static void savageUpdateSpecular_s4(GLcontext *ctx) {
|
||||
imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE;
|
||||
/*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
static void savageUpdateSpecular_s3d(GLcontext *ctx) {
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
|
||||
|
||||
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
|
||||
ctx->Light.Enabled) {
|
||||
@@ -908,7 +945,9 @@ static void savageUpdateSpecular_s3d(GLcontext *ctx) {
|
||||
imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE;
|
||||
/*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
|
||||
static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname,
|
||||
@@ -925,6 +964,7 @@ static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname,
|
||||
static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
|
||||
|
||||
if (mod == GL_SMOOTH)
|
||||
{
|
||||
@@ -934,11 +974,14 @@ static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
|
||||
{
|
||||
imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
|
||||
|
||||
if (mod == GL_SMOOTH)
|
||||
{
|
||||
@@ -948,7 +991,9 @@ static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
|
||||
{
|
||||
imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -962,6 +1007,7 @@ static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
GLuint fogClr;
|
||||
u_int32_t fogCtrl = imesa->regs.s4.fogCtrl.ui;
|
||||
|
||||
/*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
|
||||
if (ctx->Fog.Enabled)
|
||||
@@ -981,17 +1027,19 @@ static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
|
||||
imesa->regs.s4.fogCtrl.ni.fogEn = 0;
|
||||
imesa->regs.s4.fogCtrl.ni.fogMode = 0;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
|
||||
if (fogCtrl != imesa->regs.s4.fogCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
|
||||
|
||||
static void savageStencilFunc(GLcontext *);
|
||||
|
||||
static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
|
||||
GLuint mask)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
SCmpFunc a=0;
|
||||
u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
|
||||
u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
|
||||
|
||||
imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0];
|
||||
imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0];
|
||||
@@ -1012,22 +1060,26 @@ static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
|
||||
|
||||
imesa->regs.s4.stencilCtrl.ni.cmpFunc = a;
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
|
||||
stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
|
||||
static void savageDDStencilMask(GLcontext *ctx, GLuint mask)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
|
||||
imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (imesa->regs.s4.stencilCtrl.ni.writeMask != ctx->Stencil.WriteMask[0]) {
|
||||
imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
|
||||
GLenum zpass)
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
|
||||
|
||||
switch (ctx->Stencil.FailFunc[0])
|
||||
{
|
||||
@@ -1114,7 +1166,8 @@ static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
|
||||
break;
|
||||
}
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,11 +1181,9 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
switch(cap) {
|
||||
case GL_ALPHA_TEST:
|
||||
/* we should consider the disable case*/
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageBlendFunc_s4(ctx);
|
||||
break;
|
||||
case GL_BLEND:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
/*Can't find Enable bit in the 3D registers.*/
|
||||
/* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
|
||||
*/
|
||||
@@ -1146,7 +1197,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
savageBlendFunc_s4(ctx);
|
||||
break;
|
||||
case GL_DEPTH_TEST:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
@@ -1154,7 +1204,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
|
||||
break;
|
||||
case GL_STENCIL_TEST:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (!imesa->hw_stencil)
|
||||
FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
|
||||
else {
|
||||
@@ -1167,11 +1216,10 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
|
||||
imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL;
|
||||
}
|
||||
break;
|
||||
case GL_FOG:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageDDFogfv(ctx,0,0);
|
||||
break;
|
||||
case GL_CULL_FACE:
|
||||
@@ -1188,7 +1236,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
#endif
|
||||
break;
|
||||
case GL_DITHER:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (state)
|
||||
{
|
||||
if ( ctx->Color.DitherFlag )
|
||||
@@ -1200,6 +1247,7 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
{
|
||||
imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
|
||||
break;
|
||||
|
||||
case GL_LIGHTING:
|
||||
@@ -1223,11 +1271,9 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
switch(cap) {
|
||||
case GL_ALPHA_TEST:
|
||||
/* we should consider the disable case*/
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageBlendFunc_s3d(ctx);
|
||||
break;
|
||||
case GL_BLEND:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
/*Can't find Enable bit in the 3D registers.*/
|
||||
/* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
|
||||
*/
|
||||
@@ -1241,7 +1287,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
savageBlendFunc_s3d(ctx);
|
||||
break;
|
||||
case GL_DEPTH_TEST:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
@@ -1252,7 +1297,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
|
||||
break;
|
||||
case GL_FOG:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
savageDDFogfv(ctx,0,0);
|
||||
break;
|
||||
case GL_CULL_FACE:
|
||||
@@ -1269,7 +1313,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
#endif
|
||||
break;
|
||||
case GL_DITHER:
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
if (state)
|
||||
{
|
||||
if ( ctx->Color.DitherFlag )
|
||||
@@ -1281,6 +1324,7 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
{
|
||||
imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
|
||||
}
|
||||
imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
|
||||
break;
|
||||
|
||||
case GL_LIGHTING:
|
||||
@@ -1303,8 +1347,7 @@ void savageDDUpdateHwState( GLcontext *ctx )
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
|
||||
if (imesa->new_state) {
|
||||
FLUSH_BATCH(imesa);
|
||||
|
||||
savageFlushVertices(imesa);
|
||||
if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
|
||||
savageUpdateTextureState( ctx );
|
||||
}
|
||||
@@ -1368,20 +1411,20 @@ void savageEmitDrawingRectangle( savageContextPtr imesa )
|
||||
imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/
|
||||
|
||||
savageCalcViewport (imesa->glCtx);
|
||||
|
||||
imesa->dirty |= SAVAGE_UPLOAD_BUFFERS;
|
||||
}
|
||||
|
||||
|
||||
static void savageDDPrintDirty( const char *msg, GLuint state )
|
||||
{
|
||||
fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n",
|
||||
fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
|
||||
msg,
|
||||
(unsigned int) state,
|
||||
(state & SAVAGE_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "",
|
||||
(state & SAVAGE_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "",
|
||||
(state & SAVAGE_UPLOAD_CTX) ? "upload-ctx, " : "",
|
||||
(state & SAVAGE_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
|
||||
(state & SAVAGE_UPLOAD_LOCAL) ? "upload-local, " : "",
|
||||
(state & SAVAGE_UPLOAD_TEX0) ? "upload-tex0, " : "",
|
||||
(state & SAVAGE_UPLOAD_TEX1) ? "upload-tex1, " : "",
|
||||
(state & SAVAGE_UPLOAD_FOGTBL) ? "upload-fogtbl, " : "",
|
||||
(state & SAVAGE_UPLOAD_GLOBAL) ? "upload-global, " : "",
|
||||
(state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : "",
|
||||
(state & SAVAGE_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : ""
|
||||
);
|
||||
}
|
||||
@@ -1400,18 +1443,32 @@ static GLboolean savageGlobalRegChanged (savageContextPtr imesa,
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
static void savageEmitOldRegs (savageContextPtr imesa,
|
||||
GLuint first, GLuint last, GLboolean global) {
|
||||
GLuint n = last-first+1;
|
||||
drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
|
||||
cmd->state.cmd = SAVAGE_CMD_STATE;
|
||||
cmd->state.global = global;
|
||||
cmd->state.count = n;
|
||||
cmd->state.start = first;
|
||||
memcpy(cmd+1, &imesa->oldRegs.ui[first-SAVAGE_FIRST_REG], n*4);
|
||||
}
|
||||
static void savageEmitContiguousRegs (savageContextPtr imesa,
|
||||
GLuint first, GLuint last) {
|
||||
GLuint i;
|
||||
u_int32_t *pBCIBase;
|
||||
pBCIBase = savageDMAAlloc (imesa, last - first + 2);
|
||||
WRITE_CMD (pBCIBase, SET_REGISTER(first, last - first + 1), u_int32_t);
|
||||
|
||||
for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
|
||||
WRITE_CMD (pBCIBase, imesa->regs.ui[i], u_int32_t);
|
||||
GLuint n = last-first+1;
|
||||
drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
|
||||
cmd->state.cmd = SAVAGE_CMD_STATE;
|
||||
cmd->state.global = savageGlobalRegChanged(imesa, first, last);
|
||||
cmd->state.count = n;
|
||||
cmd->state.start = first;
|
||||
memcpy(cmd+1, &imesa->regs.ui[first-SAVAGE_FIRST_REG], n*4);
|
||||
/* savageAllocCmdBuf may need to flush the cmd buffer and backup
|
||||
* the current hardware state. It should see the "old" (current)
|
||||
* state that has actually been emitted to the hardware. Therefore
|
||||
* this update is done *after* savageAllocCmdBuf. */
|
||||
for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i)
|
||||
imesa->oldRegs.ui[i] = imesa->regs.ui[i];
|
||||
}
|
||||
savageDMACommit (imesa, pBCIBase);
|
||||
}
|
||||
static void savageEmitChangedRegs (savageContextPtr imesa,
|
||||
GLuint first, GLuint last) {
|
||||
@@ -1445,8 +1502,6 @@ static void savageEmitChangedRegChunk (savageContextPtr imesa,
|
||||
}
|
||||
static void savageUpdateRegister_s4(savageContextPtr imesa)
|
||||
{
|
||||
u_int32_t *pBCIBase;
|
||||
|
||||
/*
|
||||
* Scissors updates drawctrl0 and drawctrl 1
|
||||
*/
|
||||
@@ -1470,23 +1525,12 @@ static void savageUpdateRegister_s4(savageContextPtr imesa)
|
||||
|
||||
/* the savage4 uses the contiguous range of BCI registers 0x1e-0x39
|
||||
* 0x1e-0x27 are local, no need to check them for global changes */
|
||||
if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x28, 0x39)) {
|
||||
pBCIBase = savageDMAAlloc (imesa, 1);
|
||||
WRITE_CMD (pBCIBase, WAIT_3D_IDLE, u_int32_t);
|
||||
savageDMACommit (imesa, pBCIBase);
|
||||
}
|
||||
if (imesa->lostContext)
|
||||
savageEmitContiguousRegs (imesa, 0x1e, 0x39);
|
||||
else
|
||||
savageEmitChangedRegs (imesa, 0x1e, 0x39);
|
||||
savageEmitContiguousRegs (imesa, 0x1e, 0x39);
|
||||
|
||||
imesa->dirty=0;
|
||||
imesa->lostContext = GL_FALSE;
|
||||
}
|
||||
static void savageUpdateRegister_s3d(savageContextPtr imesa)
|
||||
{
|
||||
u_int32_t *pBCIBase;
|
||||
|
||||
if (imesa->scissorChanged)
|
||||
{
|
||||
if(imesa->scissor)
|
||||
@@ -1519,63 +1563,55 @@ static void savageUpdateRegister_s3d(savageContextPtr imesa)
|
||||
imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
|
||||
|
||||
/* the savage3d uses two contiguous ranges of BCI registers:
|
||||
* 0x18-0x1c and 0x20-0x38. The first range is local. */
|
||||
if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x20, 0x38)) {
|
||||
pBCIBase = savageDMAAlloc (imesa, 1);
|
||||
WRITE_CMD (pBCIBase, WAIT_3D_IDLE, u_int32_t);
|
||||
savageDMACommit (imesa, pBCIBase);
|
||||
}
|
||||
* 0x18-0x1c and 0x20-0x38. Some texture registers need to be
|
||||
* emitted in one chunk or we get some funky rendering errors. */
|
||||
/* FIXME: watermark registers aren't programmed correctly ATM */
|
||||
if (imesa->lostContext) {
|
||||
savageEmitContiguousRegs (imesa, 0x18, 0x1c);
|
||||
savageEmitContiguousRegs (imesa, 0x20, 0x36);
|
||||
} else {
|
||||
/* On the Savage IX texture registers (at least some of them)
|
||||
* have to be emitted as one chunk. */
|
||||
savageEmitChangedRegs (imesa, 0x18, 0x19);
|
||||
savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
|
||||
savageEmitChangedRegs (imesa, 0x20, 0x36);
|
||||
}
|
||||
savageEmitChangedRegs (imesa, 0x18, 0x19);
|
||||
savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
|
||||
savageEmitChangedRegs (imesa, 0x20, 0x36);
|
||||
|
||||
imesa->dirty=0;
|
||||
imesa->lostContext = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void savageEmitOldState( savageContextPtr imesa )
|
||||
{
|
||||
assert(imesa->cmdBuf.write == imesa->cmdBuf.base);
|
||||
if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
|
||||
savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE);
|
||||
} else {
|
||||
savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE);
|
||||
savageEmitOldRegs (imesa, 0x20, 0x36, GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Push the state into the sarea and/or texture memory.
|
||||
*/
|
||||
void savageEmitHwStateLocked( savageContextPtr imesa )
|
||||
void savageEmitChangedState( savageContextPtr imesa )
|
||||
{
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
|
||||
savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );
|
||||
|
||||
if (imesa->dirty & ~SAVAGE_UPLOAD_CLIPRECTS)
|
||||
{
|
||||
if (imesa->dirty & (SAVAGE_UPLOAD_CTX | SAVAGE_UPLOAD_TEX0 | \
|
||||
SAVAGE_UPLOAD_TEX1 | SAVAGE_UPLOAD_BUFFERS))
|
||||
if (imesa->dirty & (SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL |
|
||||
SAVAGE_UPLOAD_TEX0 | SAVAGE_UPLOAD_TEX1 |
|
||||
SAVAGE_UPLOAD_FOGTBL | SAVAGE_UPLOAD_TEXGLOBAL))
|
||||
{
|
||||
|
||||
/*SAVAGE_STATE_COPY(imesa);*/
|
||||
/* update state to hw*/
|
||||
if (imesa->driDrawable &&imesa->driDrawable->numClipRects ==0 )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
|
||||
fprintf (stderr, "... emitting state\n");
|
||||
if (imesa->savageScreen->chipset >= S3_SAVAGE4)
|
||||
savageUpdateRegister_s4(imesa);
|
||||
else
|
||||
savageUpdateRegister_s3d(imesa);
|
||||
}
|
||||
|
||||
imesa->sarea->dirty |= (imesa->dirty &
|
||||
~(SAVAGE_UPLOAD_TEX1|SAVAGE_UPLOAD_TEX0));
|
||||
imesa->dirty &= SAVAGE_UPLOAD_CLIPRECTS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void savageDDInitState_s4( savageContextPtr imesa )
|
||||
{
|
||||
#if 1
|
||||
@@ -1584,7 +1620,14 @@ static void savageDDInitState_s4( savageContextPtr imesa )
|
||||
|
||||
imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Less;
|
||||
imesa->regs.s4.zBufCtrl.ni.wToZEn = GL_TRUE;
|
||||
/*imesa->regs.s4.ZBufCtrl.ni.floatZEn = GL_TRUE;*/
|
||||
if (imesa->float_depth) {
|
||||
imesa->regs.s4.zBufCtrl.ni.zExpOffset =
|
||||
imesa->savageScreen->zpp == 2 ? 16 : 32;
|
||||
imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_TRUE;
|
||||
} else {
|
||||
imesa->regs.s4.zBufCtrl.ni.zExpOffset = 0;
|
||||
imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_FALSE;
|
||||
}
|
||||
imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
|
||||
imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
|
||||
imesa->regs.s4.drawCtrl0.ui = 0;
|
||||
@@ -1719,7 +1762,6 @@ static void savageDDInitState_s3d( savageContextPtr imesa )
|
||||
}
|
||||
void savageDDInitState( savageContextPtr imesa ) {
|
||||
memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t));
|
||||
memset (imesa->oldRegs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t));
|
||||
memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(u_int32_t));
|
||||
if (imesa->savageScreen->chipset >= S3_SAVAGE4)
|
||||
savageDDInitState_s4 (imesa);
|
||||
@@ -1789,6 +1831,13 @@ void savageDDInitState( savageContextPtr imesa ) {
|
||||
imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t));
|
||||
|
||||
/* Emit the initial state to the (empty) command buffer. */
|
||||
assert (imesa->cmdBuf.write == imesa->cmdBuf.base);
|
||||
savageEmitOldState(imesa);
|
||||
imesa->cmdBuf.start = imesa->cmdBuf.write;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,43 +28,13 @@
|
||||
|
||||
#include "savagecontext.h"
|
||||
|
||||
void savageEmitOldState( savageContextPtr imesa );
|
||||
void savageEmitChangedState( savageContextPtr imesa );
|
||||
|
||||
extern void savageDDUpdateHwState( GLcontext *ctx );
|
||||
extern void savageDDInitState( savageContextPtr imesa );
|
||||
extern void savageDDInitStateFuncs( GLcontext *ctx );
|
||||
extern void savageDDRenderStart(GLcontext *ctx);
|
||||
extern void savageDDRenderEnd(GLcontext *ctx);
|
||||
|
||||
/*frank 2001/11/13 add macro for sarea state copy*/
|
||||
#if 0
|
||||
#define SAVAGE_STATE_COPY(ctx) { \
|
||||
ctx->sarea->setup[0]=ctx->Registers.DrawLocalCtrl.ui; \
|
||||
ctx->sarea->setup[1]=ctx->Registers.TexPalAddr.ui; \
|
||||
ctx->sarea->setup[2]=ctx->Registers.TexCtrl[0].ui; \
|
||||
ctx->sarea->setup[3]=ctx->Registers.TexCtrl[1].ui; \
|
||||
ctx->sarea->setup[4]=ctx->Registers.TexAddr[0].ui; \
|
||||
ctx->sarea->setup[5]=ctx->Registers.TexAddr[1].ui; \
|
||||
ctx->sarea->setup[6]=ctx->Registers.TexBlendCtrl[0].ui; \
|
||||
ctx->sarea->setup[7]=ctx->Registers.TexBlendCtrl[1].ui; \
|
||||
ctx->sarea->setup[8]=ctx->Registers.TexXprClr.ui; \
|
||||
ctx->sarea->setup[9]=ctx->Registers.TexDescr.ui; \
|
||||
ctx->sarea->setup[10]=ctx->Registers.FogTable.ni.ulEntry[0]; \
|
||||
ctx->sarea->setup[11]=ctx->Registers.FogTable.ni.ulEntry[1]; \
|
||||
ctx->sarea->setup[12]=ctx->Registers.FogTable.ni.ulEntry[2]; \
|
||||
ctx->sarea->setup[13]=ctx->Registers.FogTable.ni.ulEntry[3]; \
|
||||
ctx->sarea->setup[14]=ctx->Registers.FogTable.ni.ulEntry[4]; \
|
||||
ctx->sarea->setup[15]=ctx->Registers.FogTable.ni.ulEntry[5]; \
|
||||
ctx->sarea->setup[16]=ctx->Registers.FogTable.ni.ulEntry[6]; \
|
||||
ctx->sarea->setup[17]=ctx->Registers.FogTable.ni.ulEntry[7]; \
|
||||
ctx->sarea->setup[18]=ctx->Registers.FogCtrl.ui; \
|
||||
ctx->sarea->setup[19]=ctx->Registers.StencilCtrl.ui; \
|
||||
ctx->sarea->setup[20]=ctx->Registers.ZBufCtrl.ui; \
|
||||
ctx->sarea->setup[21]=ctx->Registers.ZBufOffset.ui; \
|
||||
ctx->sarea->setup[22]=ctx->Registers.DestCtrl.ui; \
|
||||
ctx->sarea->setup[23]=ctx->Registers.DrawCtrl0.ui; \
|
||||
ctx->sarea->setup[24]=ctx->Registers.DrawCtrl1.ui; \
|
||||
ctx->sarea->setup[25]=ctx->Registers.ZWatermarks.ui; \
|
||||
ctx->sarea->setup[26]=ctx->Registers.DestTexWatermarks.ui; \
|
||||
ctx->sarea->setup[27]=ctx->Registers.TexBlendColor.ui; \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -606,7 +606,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
drm_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
|
||||
|
||||
for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) {
|
||||
@@ -628,7 +628,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap)
|
||||
|
||||
void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap )
|
||||
{
|
||||
drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
drm_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
int sz = 1 << imesa->savageScreen->logTextureGranularity[heap];
|
||||
int i;
|
||||
|
||||
@@ -661,7 +661,7 @@ static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t
|
||||
int logsz = imesa->savageScreen->logTextureGranularity[heap];
|
||||
int start = t->MemBlock->ofs >> logsz;
|
||||
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
|
||||
drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
drm_tex_region_t *list = imesa->sarea->texList[heap];
|
||||
|
||||
imesa->texAge[heap] = ++imesa->sarea->texAge[heap];
|
||||
|
||||
@@ -787,16 +787,19 @@ int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t )
|
||||
ofs = t->MemBlock->ofs;
|
||||
t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs;
|
||||
t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs);
|
||||
imesa->dirty |= SAVAGE_UPLOAD_CTX;
|
||||
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */
|
||||
}
|
||||
|
||||
/* Let the world know we've used this memory recently.
|
||||
*/
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageUpdateTexLRU( imesa, t );
|
||||
UNLOCK_HARDWARE(imesa);
|
||||
|
||||
if (t->dirty_images) {
|
||||
savageFlushVertices (imesa);
|
||||
LOCK_HARDWARE(imesa);
|
||||
savageFlushVerticesLocked (imesa);
|
||||
savageFlushCmdBufLocked (imesa, GL_FALSE);
|
||||
savageDmaFinish (imesa);
|
||||
if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU)
|
||||
fprintf(stderr, "*");
|
||||
@@ -839,9 +842,9 @@ static void savageUpdateTex0State_s4( GLcontext *ctx )
|
||||
}
|
||||
|
||||
tObj = ctx->Texture.Unit[0]._Current;
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT ||
|
||||
tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 1D or 3D texturing enabled, or texture border - fallback */
|
||||
if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
|
||||
|| tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 3D texturing enabled, or texture border - fallback */
|
||||
FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
|
||||
return;
|
||||
}
|
||||
@@ -1109,9 +1112,9 @@ static void savageUpdateTex1State_s4( GLcontext *ctx )
|
||||
|
||||
tObj = ctx->Texture.Unit[1]._Current;
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled != TEXTURE_2D_BIT ||
|
||||
tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 1D or 3D texturing enabled, or texture border - fallback */
|
||||
if ((ctx->Texture.Unit[1]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
|
||||
|| tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 3D texturing enabled, or texture border - fallback */
|
||||
FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
|
||||
return;
|
||||
}
|
||||
@@ -1302,9 +1305,9 @@ static void savageUpdateTexState_s3d( GLcontext *ctx )
|
||||
}
|
||||
|
||||
tObj = ctx->Texture.Unit[0]._Current;
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT ||
|
||||
tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 1D or 3D texturing enabled, or texture border - fallback */
|
||||
if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
|
||||
|| tObj->Image[0][tObj->BaseLevel]->Border > 0) {
|
||||
/* 3D texturing enabled, or texture border - fallback */
|
||||
FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
|
||||
return;
|
||||
}
|
||||
@@ -1436,8 +1439,7 @@ static void savageUpdateTextureState_s4( GLcontext *ctx )
|
||||
imesa->CurrentTexObj[1] = 0;
|
||||
savageUpdateTex0State_s4( ctx );
|
||||
savageUpdateTex1State_s4( ctx );
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_CTX |
|
||||
SAVAGE_UPLOAD_TEX0 |
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_TEX0 |
|
||||
SAVAGE_UPLOAD_TEX1);
|
||||
}
|
||||
static void savageUpdateTextureState_s3d( GLcontext *ctx )
|
||||
@@ -1446,8 +1448,7 @@ static void savageUpdateTextureState_s3d( GLcontext *ctx )
|
||||
if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;
|
||||
imesa->CurrentTexObj[0] = 0;
|
||||
savageUpdateTexState_s3d( ctx );
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_CTX |
|
||||
SAVAGE_UPLOAD_TEX0);
|
||||
imesa->dirty |= (SAVAGE_UPLOAD_TEX0);
|
||||
}
|
||||
void savageUpdateTextureState( GLcontext *ctx)
|
||||
{
|
||||
@@ -1495,6 +1496,60 @@ static void savageTexEnv( GLcontext *ctx, GLenum target,
|
||||
}
|
||||
}
|
||||
|
||||
static void savageTexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData;
|
||||
if (t) {
|
||||
savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t );
|
||||
} else {
|
||||
t = savageAllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
_mesa_store_teximage1d( ctx, target, level, internalFormat,
|
||||
width, border, format, type,
|
||||
pixels, packing, texObj, texImage );
|
||||
t->dirty_images |= (1 << level);
|
||||
SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
|
||||
}
|
||||
|
||||
static void savageTexSubImage1D( GLcontext *ctx,
|
||||
GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLsizei width,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData;
|
||||
assert( t ); /* this _should_ be true */
|
||||
if (t) {
|
||||
savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t );
|
||||
} else {
|
||||
t = savageAllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
|
||||
format, type, pixels, packing, texObj,
|
||||
texImage);
|
||||
t->dirty_images |= (1 << level);
|
||||
SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
|
||||
}
|
||||
|
||||
static void savageTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint height, GLint border,
|
||||
@@ -1538,7 +1593,7 @@ static void savageTexSubImage2D( GLcontext *ctx,
|
||||
} else {
|
||||
t = savageAllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1556,7 +1611,7 @@ static void savageTexParameter( GLcontext *ctx, GLenum target,
|
||||
savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData;
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
|
||||
if (!t || target != GL_TEXTURE_2D)
|
||||
if (!t || (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D))
|
||||
return;
|
||||
|
||||
switch (pname) {
|
||||
@@ -1586,7 +1641,8 @@ static void savageBindTexture( GLcontext *ctx, GLenum target,
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
|
||||
|
||||
assert( (target != GL_TEXTURE_2D) || (tObj->DriverData != NULL) );
|
||||
assert( (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) ||
|
||||
(tObj->DriverData != NULL) );
|
||||
|
||||
imesa->new_state |= SAVAGE_NEW_TEXTURE;
|
||||
}
|
||||
@@ -1638,6 +1694,8 @@ void savageDDInitTextureFuncs( struct dd_function_table *functions )
|
||||
{
|
||||
functions->TexEnv = savageTexEnv;
|
||||
functions->ChooseTextureFormat = savageChooseTextureFormat;
|
||||
functions->TexImage1D = savageTexImage1D;
|
||||
functions->TexSubImage1D = savageTexSubImage1D;
|
||||
functions->TexImage2D = savageTexImage2D;
|
||||
functions->TexSubImage2D = savageTexSubImage2D;
|
||||
functions->BindTexture = savageBindTexture;
|
||||
|
||||
@@ -77,14 +77,14 @@ static GLenum reduced_prim[GL_POLYGON+1] = {
|
||||
***********************************************************************/
|
||||
|
||||
#if defined (USE_X86_ASM)
|
||||
#define EMIT_VERT( j, vb, vertex_size, start, v ) \
|
||||
do { int __tmp; \
|
||||
vb += start; \
|
||||
__asm__ __volatile__( "rep ; movsl" \
|
||||
: "=%c" (j), "=D" (vb), "=S" (__tmp) \
|
||||
: "0" (vertex_size-start), \
|
||||
"D" ((long)vb), \
|
||||
"S" ((long)&v->ui[start])); \
|
||||
#define EMIT_VERT( j, vb, vertex_size, start, v ) \
|
||||
do { int __tmp; \
|
||||
vb += start; \
|
||||
__asm__ __volatile__( "rep ; movsl" \
|
||||
: "=%c" (j), "=D" (vb), "=S" (__tmp) \
|
||||
: "0" (vertex_size-start), \
|
||||
"D" ((long)vb), \
|
||||
"S" ((long)&(v)->ui[start])); \
|
||||
} while (0)
|
||||
#else
|
||||
#define EMIT_VERT( j, vb, vertex_size, start, v ) \
|
||||
@@ -99,8 +99,8 @@ static void __inline__ savage_draw_triangle (savageContextPtr imesa,
|
||||
savageVertexPtr v0,
|
||||
savageVertexPtr v1,
|
||||
savageVertexPtr v2) {
|
||||
GLuint vertsize = imesa->vertex_size;
|
||||
u_int32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize);
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize);
|
||||
GLuint j;
|
||||
|
||||
EMIT_VERT (j, vb, vertsize, 0, v0);
|
||||
@@ -113,8 +113,8 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa,
|
||||
savageVertexPtr v1,
|
||||
savageVertexPtr v2,
|
||||
savageVertexPtr v3) {
|
||||
GLuint vertsize = imesa->vertex_size;
|
||||
u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize);
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
|
||||
GLuint j;
|
||||
|
||||
EMIT_VERT (j, vb, vertsize, 0, v0);
|
||||
@@ -127,8 +127,8 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa,
|
||||
|
||||
static __inline__ void savage_draw_point (savageContextPtr imesa,
|
||||
savageVertexPtr tmp) {
|
||||
GLuint vertsize = imesa->vertex_size;
|
||||
u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize);
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
|
||||
const GLfloat x = tmp->v.x;
|
||||
const GLfloat y = tmp->v.y;
|
||||
const GLfloat sz = imesa->glCtx->Point._Size * .5;
|
||||
@@ -162,8 +162,8 @@ static __inline__ void savage_draw_point (savageContextPtr imesa,
|
||||
static __inline__ void savage_draw_line (savageContextPtr imesa,
|
||||
savageVertexPtr v0,
|
||||
savageVertexPtr v1 ) {
|
||||
GLuint vertsize = imesa->vertex_size;
|
||||
u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize);
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
|
||||
GLfloat width = imesa->glCtx->Line._Width;
|
||||
GLfloat dx, dy, ix, iy;
|
||||
GLuint j;
|
||||
@@ -200,6 +200,117 @@ static __inline__ void savage_draw_line (savageContextPtr imesa,
|
||||
*(float *)&vb[1] = v1->v.y + iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, v1);
|
||||
}
|
||||
|
||||
/* Fallback drawing functions for the ptex hack. Code duplication
|
||||
* (especially lines and points) isn't beautiful, but I didn't feel
|
||||
* like inventing yet another template. :-/
|
||||
*/
|
||||
#define PTEX_VERTEX( j, tmp, vertex_size, start, v) \
|
||||
do { \
|
||||
GLfloat rhw = 1.0 / v->f[vertex_size]; \
|
||||
for ( j = start ; j < vertex_size ; j++ ) \
|
||||
tmp.f[j] = v->f[j]; \
|
||||
tmp.f[3] *= v->f[vertex_size]; \
|
||||
tmp.f[vertex_size-2] *= rhw; \
|
||||
tmp.f[vertex_size-1] *= rhw; \
|
||||
} while (0)
|
||||
|
||||
static void __inline__ savage_ptex_tri (savageContextPtr imesa,
|
||||
savageVertexPtr v0,
|
||||
savageVertexPtr v1,
|
||||
savageVertexPtr v2) {
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize);
|
||||
savageVertex tmp;
|
||||
GLuint j;
|
||||
|
||||
PTEX_VERTEX (j, tmp, vertsize, 0, v0); EMIT_VERT (j, vb, vertsize, 0, &tmp);
|
||||
PTEX_VERTEX (j, tmp, vertsize, 0, v1); EMIT_VERT (j, vb, vertsize, 0, &tmp);
|
||||
PTEX_VERTEX (j, tmp, vertsize, 0, v2); EMIT_VERT (j, vb, vertsize, 0, &tmp);
|
||||
}
|
||||
|
||||
static __inline__ void savage_ptex_line (savageContextPtr imesa,
|
||||
savageVertexPtr v0,
|
||||
savageVertexPtr v1 ) {
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
|
||||
GLfloat width = imesa->glCtx->Line._Width;
|
||||
GLfloat dx, dy, ix, iy;
|
||||
savageVertex tmp0, tmp1;
|
||||
GLuint j;
|
||||
|
||||
PTEX_VERTEX (j, tmp0, vertsize, 2, v0);
|
||||
PTEX_VERTEX (j, tmp1, vertsize, 2, v1);
|
||||
|
||||
dx = v0->v.x - v1->v.x;
|
||||
dy = v0->v.y - v1->v.y;
|
||||
|
||||
ix = width * .5; iy = 0;
|
||||
if (dx * dx > dy * dy) {
|
||||
iy = ix; ix = 0;
|
||||
}
|
||||
|
||||
*(float *)&vb[0] = v0->v.x - ix;
|
||||
*(float *)&vb[1] = v0->v.y - iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp0);
|
||||
|
||||
*(float *)&vb[0] = v1->v.x + ix;
|
||||
*(float *)&vb[1] = v1->v.y + iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp1);
|
||||
|
||||
*(float *)&vb[0] = v0->v.x + ix;
|
||||
*(float *)&vb[1] = v0->v.y + iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp0);
|
||||
|
||||
*(float *)&vb[0] = v0->v.x - ix;
|
||||
*(float *)&vb[1] = v0->v.y - iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp0);
|
||||
|
||||
*(float *)&vb[0] = v1->v.x - ix;
|
||||
*(float *)&vb[1] = v1->v.y - iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp1);
|
||||
|
||||
*(float *)&vb[0] = v1->v.x + ix;
|
||||
*(float *)&vb[1] = v1->v.y + iy;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp1);
|
||||
}
|
||||
|
||||
static __inline__ void savage_ptex_point (savageContextPtr imesa,
|
||||
savageVertexPtr v0) {
|
||||
GLuint vertsize = imesa->HwVertexSize;
|
||||
u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
|
||||
const GLfloat x = v0->v.x;
|
||||
const GLfloat y = v0->v.y;
|
||||
const GLfloat sz = imesa->glCtx->Point._Size * .5;
|
||||
savageVertex tmp;
|
||||
GLuint j;
|
||||
|
||||
PTEX_VERTEX (j, tmp, vertsize, 2, v0);
|
||||
|
||||
*(float *)&vb[0] = x - sz;
|
||||
*(float *)&vb[1] = y - sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
|
||||
*(float *)&vb[0] = x + sz;
|
||||
*(float *)&vb[1] = y - sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
|
||||
*(float *)&vb[0] = x + sz;
|
||||
*(float *)&vb[1] = y + sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
|
||||
*(float *)&vb[0] = x + sz;
|
||||
*(float *)&vb[1] = y + sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
|
||||
*(float *)&vb[0] = x - sz;
|
||||
*(float *)&vb[1] = y + sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
|
||||
*(float *)&vb[0] = x - sz;
|
||||
*(float *)&vb[1] = y - sz;
|
||||
EMIT_VERT (j, vb, vertsize, 2, &tmp);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Macros for t_dd_tritmp.h to draw basic primitives *
|
||||
@@ -317,9 +428,9 @@ do { \
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
|
||||
GLuint color[n], spec[n]; \
|
||||
GLuint coloroffset = \
|
||||
((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_W) ? 3 : 4); \
|
||||
((imesa->skip & SAVAGE_SKIP_W) ? 3 : 4); \
|
||||
GLboolean specoffset = \
|
||||
((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_CS) ? 0 : coloroffset+1);\
|
||||
((imesa->skip & SAVAGE_SKIP_C1) ? 0 : coloroffset+1); \
|
||||
(void) color; (void) spec; (void) coloroffset; (void) specoffset;
|
||||
|
||||
/***********************************************************************
|
||||
@@ -591,6 +702,18 @@ static void savageChooseRenderState(GLcontext *ctx)
|
||||
GLuint flags = ctx->_TriangleCaps;
|
||||
GLuint index = 0;
|
||||
|
||||
/* Hook in fallback functions for the ptex hack. Do this first, so
|
||||
* that a real fallback will overwrite them with the respective
|
||||
* savage_fallback_... function.
|
||||
*/
|
||||
if (imesa->ptexHack) {
|
||||
/* Do textures make sense with points? */
|
||||
imesa->draw_point = savage_ptex_point;
|
||||
imesa->draw_line = savage_ptex_line;
|
||||
imesa->draw_tri = savage_ptex_tri;
|
||||
index |= SAVAGE_FALLBACK_BIT;
|
||||
}
|
||||
|
||||
if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
|
||||
imesa->draw_point = savage_draw_point;
|
||||
imesa->draw_line = savage_draw_line;
|
||||
@@ -604,7 +727,7 @@ static void savageChooseRenderState(GLcontext *ctx)
|
||||
|
||||
/* Hook in fallbacks for specific primitives.
|
||||
*/
|
||||
if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) {
|
||||
if (flags & ANY_FALLBACK_FLAGS) {
|
||||
if (flags & POINT_FALLBACK) imesa->draw_point = savage_fallback_point;
|
||||
if (flags & LINE_FALLBACK) imesa->draw_line = savage_fallback_line;
|
||||
if (flags & TRI_FALLBACK) imesa->draw_tri = savage_fallback_tri;
|
||||
@@ -633,6 +756,16 @@ static void savageChooseRenderState(GLcontext *ctx)
|
||||
|
||||
imesa->RenderIndex = index;
|
||||
}
|
||||
|
||||
if (imesa->savageScreen->chipset < S3_SAVAGE4 && (flags & DD_FLATSHADE)) {
|
||||
if (imesa->HwPrim != SAVAGE_PRIM_TRILIST_201)
|
||||
savageFlushVertices(imesa);
|
||||
imesa->HwPrim = SAVAGE_PRIM_TRILIST_201;
|
||||
} else {
|
||||
if (imesa->HwPrim != SAVAGE_PRIM_TRILIST)
|
||||
savageFlushVertices(imesa);
|
||||
imesa->HwPrim = SAVAGE_PRIM_TRILIST;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -643,6 +776,9 @@ static void savageRunPipeline( GLcontext *ctx )
|
||||
{
|
||||
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
|
||||
|
||||
if (imesa->no_rast)
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE);
|
||||
|
||||
if (imesa->new_state)
|
||||
savageDDUpdateHwState( ctx );
|
||||
|
||||
@@ -654,6 +790,9 @@ static void savageRunPipeline( GLcontext *ctx )
|
||||
}
|
||||
|
||||
_tnl_run_pipeline( ctx );
|
||||
|
||||
if (imesa->no_rast)
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_FALSE);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -706,6 +845,28 @@ static void savageRenderPrimitive( GLcontext *ctx, GLenum prim )
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if projective texture coordinates are used and if we can fake
|
||||
* them. Fallback to swrast we can't. Returns GL_TRUE if projective
|
||||
* texture coordinates must be faked, GL_FALSE otherwise.
|
||||
*/
|
||||
static GLboolean savageCheckPTexHack( GLcontext *ctx )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint index = tnl->render_inputs;
|
||||
|
||||
if (index & _TNL_BIT_TEX(0) && VB->TexCoordPtr[0]->size == 4) {
|
||||
if ((index & _TNL_BITS_TEX_ANY) == _TNL_BIT_TEX(0))
|
||||
return GL_TRUE; /* apply ptex hack */
|
||||
else
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
|
||||
}
|
||||
if ((index & _TNL_BIT_TEX(1)) && VB->TexCoordPtr[1]->size == 4)
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
|
||||
|
||||
return GL_FALSE; /* don't apply ptex hack */
|
||||
}
|
||||
|
||||
|
||||
#define EMIT_ATTR( ATTR, STYLE, INDEX, SKIP ) \
|
||||
do { \
|
||||
@@ -713,7 +874,7 @@ do { \
|
||||
imesa->vertex_attrs[imesa->vertex_attr_count].format = (STYLE); \
|
||||
imesa->vertex_attr_count++; \
|
||||
setupIndex |= (INDEX); \
|
||||
drawCmd &= ~(SKIP); \
|
||||
skip &= ~(SKIP); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_PAD( N ) \
|
||||
@@ -724,17 +885,19 @@ do { \
|
||||
imesa->vertex_attr_count++; \
|
||||
} while (0)
|
||||
|
||||
#define SAVAGE_EMIT_XYZ 0x0001
|
||||
#define SAVAGE_EMIT_W 0x0002
|
||||
#define SAVAGE_EMIT_C0 0x0004
|
||||
#define SAVAGE_EMIT_C1 0x0008
|
||||
#define SAVAGE_EMIT_FOG 0x0010
|
||||
#define SAVAGE_EMIT_S0 0x0020
|
||||
#define SAVAGE_EMIT_T0 0x0040
|
||||
#define SAVAGE_EMIT_ST0 0x0060
|
||||
#define SAVAGE_EMIT_S1 0x0080
|
||||
#define SAVAGE_EMIT_T1 0x0100
|
||||
#define SAVAGE_EMIT_ST1 0x0180
|
||||
#define SAVAGE_EMIT_XYZ 0x0001
|
||||
#define SAVAGE_EMIT_W 0x0002
|
||||
#define SAVAGE_EMIT_C0 0x0004
|
||||
#define SAVAGE_EMIT_C1 0x0008
|
||||
#define SAVAGE_EMIT_FOG 0x0010
|
||||
#define SAVAGE_EMIT_S0 0x0020
|
||||
#define SAVAGE_EMIT_T0 0x0040
|
||||
#define SAVAGE_EMIT_Q0 0x0080
|
||||
#define SAVAGE_EMIT_ST0 0x0060
|
||||
#define SAVAGE_EMIT_STQ0 0x00e0
|
||||
#define SAVAGE_EMIT_S1 0x0100
|
||||
#define SAVAGE_EMIT_T1 0x0200
|
||||
#define SAVAGE_EMIT_ST1 0x0300
|
||||
|
||||
|
||||
static void savageRenderStart( GLcontext *ctx )
|
||||
@@ -744,81 +907,171 @@ static void savageRenderStart( GLcontext *ctx )
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint index = tnl->render_inputs;
|
||||
GLuint setupIndex = SAVAGE_EMIT_XYZ;
|
||||
GLuint drawCmd = SAVAGE_HW_SKIPFLAGS;
|
||||
if (imesa->savageScreen->chipset < S3_SAVAGE4)
|
||||
drawCmd &= ~SAVAGE_HW_NO_UV1;
|
||||
drawCmd &= ~SAVAGE_HW_NO_Z; /* all mesa vertices have a z coordinate */
|
||||
GLubyte skip;
|
||||
GLboolean ptexHack;
|
||||
|
||||
/* Check if we need to apply the ptex hack. Choose a new render
|
||||
* state if necessary. (Note: this can't be done in
|
||||
* savageRunPipeline, since the number of vertex coordinates can
|
||||
* change in the pipeline. texmat or texgen or both?) */
|
||||
ptexHack = savageCheckPTexHack( ctx );
|
||||
if (ptexHack != imesa->ptexHack) {
|
||||
imesa->ptexHack = ptexHack;
|
||||
savageChooseRenderState (ctx);
|
||||
}
|
||||
/* Handle fallback cases identified in savageCheckPTexHack. */
|
||||
if (SAVAGE_CONTEXT(ctx)->Fallback) {
|
||||
tnl->Driver.Render.Start(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Important:
|
||||
*/
|
||||
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
|
||||
imesa->vertex_attr_count = 0;
|
||||
|
||||
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
|
||||
* build up a hardware vertex.
|
||||
*/
|
||||
if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) {
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_HW_NO_W );
|
||||
}
|
||||
else {
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
|
||||
}
|
||||
if (imesa->savageScreen->chipset < S3_SAVAGE4) {
|
||||
skip = SAVAGE_SKIP_ALL_S3D;
|
||||
skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */
|
||||
|
||||
/* t_context.c always includes a diffuse color */
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_HW_NO_CD );
|
||||
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
|
||||
* build up a hardware vertex.
|
||||
*/
|
||||
if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) {
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );
|
||||
}
|
||||
else {
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
|
||||
EMIT_PAD( 4 );
|
||||
skip &= ~SAVAGE_SKIP_W;
|
||||
}
|
||||
|
||||
/* t_context.c always includes a diffuse color */
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
|
||||
|
||||
if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
|
||||
if ((index & _TNL_BIT_COLOR1))
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_HW_NO_CS );
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
|
||||
else
|
||||
EMIT_PAD( 3 );
|
||||
if ((index & _TNL_BIT_FOG))
|
||||
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_HW_NO_CS );
|
||||
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
|
||||
else
|
||||
EMIT_PAD( 1 );
|
||||
}
|
||||
skip &= ~SAVAGE_SKIP_C1;
|
||||
|
||||
if (index & _TNL_BIT_TEX(0)) {
|
||||
if (VB->TexCoordPtr[0]->size > 2) {
|
||||
/* projective textures are not supported by the hardware */
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
|
||||
}
|
||||
if (VB->TexCoordPtr[0]->size == 2)
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_HW_NO_UV0 );
|
||||
if (index & _TNL_BIT_TEX(0)) {
|
||||
if (ptexHack)
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
|
||||
else if (VB->TexCoordPtr[0]->size == 4)
|
||||
assert (0); /* should be caught by savageCheckPTexHack */
|
||||
else if (VB->TexCoordPtr[0]->size >= 2)
|
||||
/* The chromium menu emits some 3D tex coords even though no
|
||||
* 3D texture is enabled. Ignore the 3rd coordinate. */
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
|
||||
else if (VB->TexCoordPtr[0]->size == 1) {
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
|
||||
EMIT_PAD( 4 );
|
||||
} else
|
||||
EMIT_PAD( 8 );
|
||||
} else
|
||||
EMIT_PAD( 8 );
|
||||
skip &= ~SAVAGE_SKIP_ST0;
|
||||
} else {
|
||||
skip = SAVAGE_SKIP_ALL_S4;
|
||||
skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */
|
||||
|
||||
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
|
||||
* build up a hardware vertex.
|
||||
*/
|
||||
if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE))
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );
|
||||
else
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_HW_NO_U0 );
|
||||
}
|
||||
if (index & _TNL_BIT_TEX(1)) {
|
||||
if (VB->TexCoordPtr[1]->size > 2) {
|
||||
/* projective textures are not supported by the hardware */
|
||||
FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
|
||||
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
|
||||
|
||||
/* t_context.c always includes a diffuse color */
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
|
||||
|
||||
if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
|
||||
if ((index & _TNL_BIT_COLOR1))
|
||||
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
|
||||
else
|
||||
EMIT_PAD( 3 );
|
||||
if ((index & _TNL_BIT_FOG))
|
||||
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
|
||||
else
|
||||
EMIT_PAD( 1 );
|
||||
}
|
||||
|
||||
if (index & _TNL_BIT_TEX(0)) {
|
||||
if (ptexHack)
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
|
||||
else if (VB->TexCoordPtr[0]->size == 4)
|
||||
assert (0); /* should be caught by savageCheckPTexHack */
|
||||
else if (VB->TexCoordPtr[0]->size >= 2)
|
||||
/* The chromium menu emits some 3D tex coords even though no
|
||||
* 3D texture is enabled. Ignore the 3rd coordinate. */
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
|
||||
else
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
|
||||
}
|
||||
if (index & _TNL_BIT_TEX(1)) {
|
||||
if (VB->TexCoordPtr[1]->size == 4)
|
||||
/* projective textures are not supported by the hardware */
|
||||
assert (0); /* should be caught by savageCheckPTexHack */
|
||||
else if (VB->TexCoordPtr[1]->size >= 2)
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_SKIP_ST1 );
|
||||
else
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_SKIP_S1 );
|
||||
}
|
||||
if (VB->TexCoordPtr[1]->size == 2)
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_HW_NO_UV1 );
|
||||
else
|
||||
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_HW_NO_U1 );
|
||||
}
|
||||
|
||||
/* Need to change the vertex emit code if the SetupIndex changed or
|
||||
* is set for the first time (indicated by vertex_size == 0). */
|
||||
if (setupIndex != imesa->SetupIndex || imesa->vertex_size == 0) {
|
||||
imesa->vertex_size =
|
||||
GLuint hwVertexSize;
|
||||
imesa->vertex_size =
|
||||
_tnl_install_attrs( ctx,
|
||||
imesa->vertex_attrs,
|
||||
imesa->vertex_attr_count,
|
||||
imesa->hw_viewport, 0 );
|
||||
imesa->vertex_size >>= 2;
|
||||
imesa->SetupIndex = setupIndex;
|
||||
imesa->skip = skip;
|
||||
|
||||
imesa->DrawPrimitiveCmd = drawCmd;
|
||||
hwVertexSize = imesa->vertex_size;
|
||||
if (setupIndex & SAVAGE_EMIT_Q0) {
|
||||
/* The vertex setup code emits homogenous texture
|
||||
* coordinates. They are converted to normal 2D coords by
|
||||
* savage_ptex_tri/line/point. Now we have two different
|
||||
* vertex sizes. Functions that emit vertices to the hardware
|
||||
* need to use HwVertexSize, anything that manipulates the
|
||||
* vertices generated by t_vertex uses vertex_size. */
|
||||
hwVertexSize--;
|
||||
assert (imesa->ptexHack);
|
||||
} else
|
||||
assert (!imesa->ptexHack);
|
||||
|
||||
if (hwVertexSize != imesa->HwVertexSize) {
|
||||
/* Changing the vertex size: flush vertex and command buffer and
|
||||
* discard the DMA buffer, if we were using one. */
|
||||
savageFlushVertices(imesa);
|
||||
savageFlushCmdBuf(imesa, GL_TRUE);
|
||||
if (hwVertexSize == 8) {
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf (stderr, "Using DMA, skip=0x%02x\n", skip);
|
||||
/* we can use vertex dma */
|
||||
imesa->vtxBuf = &imesa->dmaVtxBuf;
|
||||
} else {
|
||||
if (SAVAGE_DEBUG & DEBUG_DMA)
|
||||
fprintf (stderr, "Not using DMA, skip=0x%02x\n", skip);
|
||||
imesa->vtxBuf = &imesa->clientVtxBuf;
|
||||
}
|
||||
imesa->HwVertexSize = hwVertexSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SAVAGE_CONTEXT(ctx)->Fallback) {
|
||||
/* Update hardware state and get the lock */
|
||||
savageDDRenderStart( ctx );
|
||||
} else {
|
||||
tnl->Driver.Render.Start(ctx);
|
||||
}
|
||||
/* Update hardware state and get the lock */
|
||||
savageDDRenderStart( ctx );
|
||||
}
|
||||
|
||||
static void savageRenderFinish( GLcontext *ctx )
|
||||
@@ -867,7 +1120,6 @@ void savageFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
|
||||
imesa->Fallback |= bit;
|
||||
if (oldfallback == 0) {
|
||||
/* the first fallback */
|
||||
FLUSH_BATCH( imesa );
|
||||
_swsetup_Wakeup( ctx );
|
||||
imesa->RenderIndex = ~0;
|
||||
}
|
||||
@@ -959,7 +1211,9 @@ static GLboolean run_texnorm_stage( GLcontext *ctx,
|
||||
return GL_TRUE;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
|
||||
if (!(stage->inputs & stage->changed_inputs & VERT_BIT_TEX(i)))
|
||||
if (!(stage->inputs & stage->changed_inputs & VERT_BIT_TEX(i)) ||
|
||||
VB->TexCoordPtr[i]->size == 4)
|
||||
/* Never try to normalize homogenous tex coords! */
|
||||
continue;
|
||||
|
||||
GLuint reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled;
|
||||
@@ -973,37 +1227,17 @@ static GLboolean run_texnorm_stage( GLcontext *ctx,
|
||||
GLint j;
|
||||
|
||||
if (normalizeS && normalizeT) {
|
||||
/* determine extreme values in S and T */
|
||||
GLfloat minS = in[0], maxS = in[0], minT = in[1], maxT = in[1];
|
||||
GLfloat correctionS, correctionT;
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
for (j = 1; j < VB->Count; ++j) {
|
||||
if (in[0] < minS) minS = in[0];
|
||||
else if (in[0] > maxS) maxS = in[0];
|
||||
if (in[1] < minT) minT = in[1];
|
||||
else if (in[1] > maxT) maxT = in[1];
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
}
|
||||
correctionS = -floor((minS + maxS) * 0.5 + 0.5);
|
||||
correctionT = -floor((minT + maxT) * 0.5 + 0.5);
|
||||
in = (GLfloat *)VB->TexCoordPtr[i]->data;
|
||||
/* take first texcoords as rough estimate of mean value */
|
||||
GLfloat correctionS = -floor(in[0]+0.5);
|
||||
GLfloat correctionT = -floor(in[1]+0.5);
|
||||
for (j = 0; j < VB->Count; ++j) {
|
||||
out[j][0] = in[0] + correctionS;
|
||||
out[j][1] = in[1] + correctionT;
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
}
|
||||
} else if (normalizeS) {
|
||||
/* determine extreme values in S */
|
||||
GLfloat minS = in[0], maxS = in[0];
|
||||
GLfloat correctionS;
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
for (j = 1; j < VB->Count; ++j) {
|
||||
if (in[0] < minS) minS = in[0];
|
||||
else if (in[0] > maxS) maxS = in[0];
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
}
|
||||
correctionS = -floor((minS + maxS) * 0.5 + 0.5);
|
||||
in = (GLfloat *)VB->TexCoordPtr[i]->data;
|
||||
/* take first texcoords as rough estimate of mean value */
|
||||
GLfloat correctionS = -floor(in[0]+0.5);
|
||||
if (reallyEnabled & TEXTURE_2D_BIT) {
|
||||
for (j = 0; j < VB->Count; ++j) {
|
||||
out[j][0] = in[0] + correctionS;
|
||||
@@ -1017,17 +1251,8 @@ static GLboolean run_texnorm_stage( GLcontext *ctx,
|
||||
}
|
||||
}
|
||||
} else if (normalizeT) {
|
||||
/* determine extreme values in T */
|
||||
GLfloat minT = in[1], maxT = in[1];
|
||||
GLfloat correctionT;
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
for (j = 1; j < VB->Count; ++j) {
|
||||
if (in[1] < minT) minT = in[1];
|
||||
else if (in[1] > maxT) maxT = in[1];
|
||||
in = (GLfloat *)((GLubyte *)in + instride);
|
||||
}
|
||||
correctionT = -floor((minT + maxT) * 0.5 + 0.5);
|
||||
in = (GLfloat *)VB->TexCoordPtr[i]->data;
|
||||
/* take first texcoords as rough estimate of mean value */
|
||||
GLfloat correctionT = -floor(in[1]+0.5);
|
||||
for (j = 0; j < VB->Count; ++j) {
|
||||
out[j][0] = in[0];
|
||||
out[j][1] = in[1] + correctionT;
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
|
||||
/* Totals 2 Mbytes which equals 2^16 32-byte vertices divided among up
|
||||
* to 32 clients. */
|
||||
#define SAVAGE_NUM_BUFFERS 32
|
||||
#define SAVAGE_BUFFER_SIZE (1 << 16) /* 64k */
|
||||
|
||||
#define SAVAGE_DEFAULT_AGP_MODE 1
|
||||
#define SAVAGE_MAX_AGP_MODE 4
|
||||
|
||||
@@ -68,14 +73,17 @@ typedef struct _server{
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int frontbufferSize;
|
||||
unsigned int frontBitmapDesc;
|
||||
|
||||
unsigned int backOffset;
|
||||
unsigned int backPitch;
|
||||
unsigned int backbufferSize;
|
||||
unsigned int backBitmapDesc;
|
||||
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthPitch;
|
||||
unsigned int depthbufferSize;
|
||||
unsigned int depthBitmapDesc;
|
||||
|
||||
unsigned int textureOffset;
|
||||
int textureSize;
|
||||
@@ -89,12 +97,7 @@ typedef struct _server{
|
||||
drmRegion status;
|
||||
|
||||
/* AGP mappings */
|
||||
#if 0
|
||||
drmRegion warp;
|
||||
drmRegion primary;
|
||||
drmRegion buffers;
|
||||
#endif
|
||||
|
||||
drmRegion agpTextures;
|
||||
int logAgpTextureGranularity;
|
||||
|
||||
@@ -114,71 +117,41 @@ typedef struct {
|
||||
int cpp;
|
||||
int zpp;
|
||||
|
||||
int agpMode;
|
||||
int agpMode; /* 0 for PCI cards */
|
||||
|
||||
unsigned int sarea_priv_offset;
|
||||
|
||||
unsigned int bufferSize; /* size of DMA buffers */
|
||||
|
||||
drm_handle_t frontbuffer;
|
||||
unsigned int frontbufferSize;
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int frontBitmapDesc; /*Bitmap Descriptior*/
|
||||
unsigned int IsfrontTiled;
|
||||
|
||||
drm_handle_t backbuffer;
|
||||
unsigned int backbufferSize;
|
||||
unsigned int backOffset;
|
||||
unsigned int backPitch;
|
||||
unsigned int backBitmapDesc; /*Bitmap Descriptior*/
|
||||
|
||||
drm_handle_t depthbuffer;
|
||||
unsigned int depthbufferSize;
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthPitch;
|
||||
unsigned int depthBitmapDesc; /*Bitmap Descriptior*/
|
||||
|
||||
|
||||
|
||||
drm_handle_t textures;
|
||||
drm_handle_t xvmcSurfHandle;
|
||||
unsigned int textureOffset;
|
||||
unsigned int textureSize;
|
||||
int logTextureGranularity;
|
||||
|
||||
/* Allow calculation of setup dma addresses.
|
||||
*/
|
||||
unsigned int agpBufferOffset;
|
||||
|
||||
unsigned int agpTextureOffset;
|
||||
unsigned int agpTextureSize;
|
||||
drmRegion agpTextures;
|
||||
int logAgpTextureGranularity;
|
||||
|
||||
/* unsigned int mAccess;*/
|
||||
|
||||
drmRegion aperture;
|
||||
/* Linear aperture */
|
||||
drm_handle_t apertureHandle;
|
||||
unsigned int apertureSize;
|
||||
unsigned int aperturePitch; /* in byte */
|
||||
|
||||
/* Status page (probably not needed, but no harm, read-only) */
|
||||
drm_handle_t statusHandle;
|
||||
unsigned int statusSize;
|
||||
|
||||
drmRegion registers;
|
||||
drmRegion BCIcmdBuf;
|
||||
drmRegion status;
|
||||
/* AGP textures */
|
||||
drm_handle_t agpTextureHandle;
|
||||
unsigned int agpTextureSize;
|
||||
int logAgpTextureGranularity;
|
||||
|
||||
#if 0
|
||||
drmRegion primary;
|
||||
drmRegion buffers;
|
||||
#endif
|
||||
/*For shadow status*/
|
||||
unsigned long sareaPhysAddr;
|
||||
|
||||
unsigned int sarea_priv_offset;
|
||||
int shadowStatus;
|
||||
/* Not sure about this one */
|
||||
drm_handle_t xvmcSurfHandle; /* ? */
|
||||
} SAVAGEDRIRec, *SAVAGEDRIPtr;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -334,8 +334,7 @@ static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
|
||||
m->depthBits = deep
|
||||
? (depth ? 24 : 0)
|
||||
: (depth ? 0 : depth_bits);
|
||||
m->visualType = i ? GLX_TRUE_COLOR
|
||||
: GLX_DIRECT_COLOR;
|
||||
m->visualType = vis[i];
|
||||
m->renderType = GLX_RGBA_BIT;
|
||||
m->drawableType = GLX_WINDOW_BIT;
|
||||
m->rgbMode = GL_TRUE;
|
||||
|
||||
36
src/mesa/drivers/dri/trident/Makefile
Normal file
36
src/mesa/drivers/dri/trident/Makefile
Normal file
@@ -0,0 +1,36 @@
|
||||
# src/mesa/drivers/dri/trident/Makefile
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = trident_dri.so
|
||||
|
||||
# Not yet
|
||||
# MINIGLX_SOURCES = server/trident_dri.c
|
||||
|
||||
COMMON_SOURCES = \
|
||||
../../common/driverfuncs.c \
|
||||
../common/mm.c \
|
||||
../common/utils.c \
|
||||
../common/texmem.c \
|
||||
../common/vblank.c \
|
||||
../common/xmlconfig.c \
|
||||
../common/dri_util.c \
|
||||
../common/glcontextmodes.c
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
trident_context.c \
|
||||
trident_state.c \
|
||||
trident_vb.c \
|
||||
trident_dd.c \
|
||||
trident_tris.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
symlinks:
|
||||
@@ -37,17 +37,18 @@
|
||||
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "mem.h"
|
||||
#include "matrix.h"
|
||||
#include "extensions.h"
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#include "x86/common_x86_asm.h"
|
||||
#endif
|
||||
#include "simple_list.h"
|
||||
#include "mem.h"
|
||||
#include "mm.h"
|
||||
|
||||
static const struct gl_pipeline_stage *trident_pipeline[] = {
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "dri_util.h"
|
||||
|
||||
static const struct tnl_pipeline_stage *trident_pipeline[] = {
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
@@ -58,7 +59,7 @@ static const struct gl_pipeline_stage *trident_pipeline[] = {
|
||||
};
|
||||
|
||||
|
||||
GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
GLboolean tridentCreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
@@ -66,6 +67,7 @@ GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
tridentContextPtr tmesa;
|
||||
tridentScreenPtr tridentscrn;
|
||||
struct dd_function_table functions;
|
||||
#if 0
|
||||
drm_trident_sarea_t *saPriv=(drm_trident_sarea_t *)(((char*)sPriv->pSAREA)+
|
||||
sizeof(XF86DRISAREARec));
|
||||
@@ -80,20 +82,22 @@ GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
else
|
||||
shareCtx = NULL;
|
||||
|
||||
tmesa->glCtx = _mesa_create_context(glVisual, shareCtx, tmesa, GL_TRUE);
|
||||
_mesa_init_driver_functions(&functions);
|
||||
|
||||
tmesa->glCtx =
|
||||
_mesa_create_context(glVisual, shareCtx, &functions, (void *)tmesa);
|
||||
|
||||
if (!tmesa->glCtx) {
|
||||
FREE(tmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
tmesa->display = dpy;
|
||||
|
||||
tmesa->driContext = driContextPriv;
|
||||
tmesa->driScreen = sPriv;
|
||||
tmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
|
||||
|
||||
tmesa->hHWContext = driContextPriv->hHWContext;
|
||||
tmesa->driHwLock = &sPriv->pSAREA->lock;
|
||||
tmesa->driHwLock = (drmLock *)&sPriv->pSAREA->lock;
|
||||
tmesa->driFd = sPriv->fd;
|
||||
#if 0
|
||||
tmesa->sarea = saPriv;
|
||||
@@ -159,11 +163,11 @@ GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
|
||||
tridentDDInitTriFuncs( ctx );
|
||||
tridentDDInitState( tmesa );
|
||||
|
||||
driContextPriv->driverPrivate = (void *)tmesa;
|
||||
driContextPriv->driverPrivate = (void *)tmesa;
|
||||
|
||||
UNLOCK_HARDWARE(tmesa);
|
||||
|
||||
return GL_TRUE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -181,15 +185,14 @@ tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||
tmesa->glCtx->DriverCtx = NULL;
|
||||
_mesa_destroy_context(tmesa->glCtx);
|
||||
|
||||
Xfree(tmesa);
|
||||
_mesa_free(tmesa);
|
||||
driContextPriv->driverPrivate = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GLboolean
|
||||
tridentCreateBuffer( Display *dpy,
|
||||
__DRIscreenPrivate *driScrnPriv,
|
||||
tridentCreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
const __GLcontextModes *mesaVis,
|
||||
GLboolean isPixmap )
|
||||
@@ -217,10 +220,9 @@ tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
||||
}
|
||||
|
||||
static void
|
||||
tridentSwapBuffers(Display *dpy, void *drawablePrivate)
|
||||
tridentSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
|
||||
(void) dpy;
|
||||
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
tridentContextPtr tmesa;
|
||||
@@ -228,7 +230,7 @@ tridentSwapBuffers(Display *dpy, void *drawablePrivate)
|
||||
tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
ctx = tmesa->glCtx;
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
_mesa_swapbuffers( ctx ); /* flush pending rendering comands */
|
||||
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
|
||||
tridentCopyBuffer( dPriv );
|
||||
}
|
||||
}
|
||||
@@ -284,24 +286,11 @@ tridentUnbindContext( __DRIcontextPrivate *driContextPriv )
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
tridentOpenFullScreen(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
tridentCloseFullScreen(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
tridentScreenPtr tridentCreateScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
TRIDENTDRIPtr tDRIPriv = (TRIDENTDRIPtr)sPriv->pDevPriv;
|
||||
tridentScreenPtr tridentScreen;
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
/* Check the DRI version */
|
||||
@@ -360,7 +349,7 @@ printf("offset 0x%x 0x%x\n",tridentScreen->backOffset,tridentScreen->depthOffset
|
||||
FREE(tridentScreen);
|
||||
return GL_FALSE;
|
||||
}
|
||||
printf("MAPPED at 0x%x\n",tridentScreen->mmio.map);
|
||||
printf("MAPPED at %p\n", tridentScreen->mmio.map);
|
||||
|
||||
return tridentScreen;
|
||||
}
|
||||
@@ -396,23 +385,49 @@ static struct __DriverAPIRec tridentAPI = {
|
||||
tridentSwapBuffers,
|
||||
tridentMakeCurrent,
|
||||
tridentUnbindContext,
|
||||
tridentOpenFullScreen,
|
||||
tridentCloseFullScreen
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
* Return: pointer to a __DRIscreenPrivate.
|
||||
*/
|
||||
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
|
||||
int numConfigs, __GLXvisualConfig *config)
|
||||
#ifndef USE_NEW_INTERFACE
|
||||
#error trident_dri.so is new-interface only.
|
||||
#else
|
||||
|
||||
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
|
||||
|
||||
PUBLIC void *__driCreateNewScreen( __DRInativeDisplay *dpy, int scrn,
|
||||
__DRIscreen *psc,
|
||||
const __GLcontextModes * modes,
|
||||
const __DRIversion * ddx_version,
|
||||
const __DRIversion * dri_version,
|
||||
const __DRIversion * drm_version,
|
||||
const __DRIframebuffer * frame_buffer,
|
||||
drmAddress pSAREA, int fd,
|
||||
int internal_api_version,
|
||||
__GLcontextModes ** driver_modes )
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tridentAPI);
|
||||
return (void *) psp;
|
||||
__DRIscreenPrivate *psp;
|
||||
/* XXX version checks */
|
||||
|
||||
psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
|
||||
ddx_version, dri_version, drm_version,
|
||||
frame_buffer, pSAREA, fd,
|
||||
internal_api_version, &tridentAPI);
|
||||
|
||||
if ( psp != NULL ) {
|
||||
create_context_modes = (PFNGLXCREATECONTEXTMODES)
|
||||
glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
|
||||
#if 0
|
||||
if ( create_context_modes != NULL ) {
|
||||
TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv;
|
||||
*driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8,
|
||||
GL_TRUE );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (void *) psp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __driRegisterExtensions(void)
|
||||
{
|
||||
/* No extensions */
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#ifndef _TRIDENT_CONTEXT_H_
|
||||
#define _TRIDENT_CONTEXT_H_
|
||||
|
||||
#include "compiler.h"
|
||||
#include "dri_util.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
@@ -54,6 +53,23 @@
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
/* these require that base be dword-aligned */
|
||||
static inline void MMIO_OUT32(unsigned char *base, unsigned int offset,
|
||||
unsigned int val)
|
||||
{
|
||||
unsigned int *addr = (unsigned int *)(base + offset);
|
||||
*addr = val;
|
||||
}
|
||||
|
||||
static inline unsigned int MMIO_IN32(unsigned char *base, unsigned int offset)
|
||||
{
|
||||
unsigned int *addr = (unsigned int *)(base + offset);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
#define MMIO_OUT8(base, offset, val) *((base) + (offset)) = (val)
|
||||
#define MMIO_IN8(base, offset) *((base) + (offset))
|
||||
|
||||
struct trident_context;
|
||||
typedef struct trident_context tridentContextRec;
|
||||
typedef struct trident_context *tridentContextPtr;
|
||||
@@ -74,7 +90,7 @@ typedef void (*trident_point_func)( tridentContextPtr,
|
||||
const tridentVertex * );
|
||||
|
||||
typedef struct {
|
||||
drmHandle handle; /* Handle to the DRM region */
|
||||
drm_handle_t handle; /* Handle to the DRM region */
|
||||
drmSize size; /* Size of the DRM region */
|
||||
unsigned char *map; /* Mapping of the DRM region */
|
||||
} tridentRegionRec, *tridentRegionPtr;
|
||||
@@ -123,11 +139,9 @@ struct trident_context {
|
||||
|
||||
/* Mirrors of some DRI state
|
||||
*/
|
||||
Display *display; /* X server display */
|
||||
|
||||
int lastStamp; /* mirror driDrawable->lastStamp */
|
||||
|
||||
drmContext hHWContext;
|
||||
drm_context_t hHWContext;
|
||||
drmLock *driHwLock;
|
||||
int driFd;
|
||||
|
||||
@@ -141,10 +155,10 @@ struct trident_context {
|
||||
GLint readOffset, readPitch;
|
||||
|
||||
GLuint numClipRects; /* Cliprects for the draw buffer */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
drm_clip_rect_t *pClipRects;
|
||||
|
||||
GLint scissor;
|
||||
XF86DRIClipRectRec ScissorRect; /* Current software scissor */
|
||||
drm_clip_rect_t ScissorRect; /* Current software scissor */
|
||||
|
||||
GLuint Fallback;
|
||||
GLuint RenderIndex;
|
||||
@@ -199,10 +213,19 @@ void tridentInitHW( tridentContextPtr tmesa );
|
||||
void tridentDDInitStateFuncs( GLcontext *ctx );
|
||||
void tridentDDInitTextureFuncs( GLcontext *ctx );
|
||||
void tridentDDInitTriFuncs( GLcontext *ctx );
|
||||
|
||||
extern void tridentBuildVertices( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint newinputs );
|
||||
extern void tridentInitVB( GLcontext *ctx );
|
||||
extern void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv );
|
||||
extern void tridentFallback( tridentContextPtr tmesa, GLuint bit,
|
||||
GLboolean mode );
|
||||
extern void tridentCheckTexSizes( GLcontext *ctx );
|
||||
extern void tridentChooseVertexState( GLcontext *ctx );
|
||||
extern void tridentDDUpdateHWState( GLcontext *ctx );
|
||||
extern void tridentUploadHwStateLocked( tridentContextPtr tmesa );
|
||||
|
||||
#define TRIDENT_CONTEXT(ctx) ((tridentContextPtr)(ctx->DriverCtx))
|
||||
|
||||
|
||||
@@ -27,14 +27,13 @@
|
||||
#include "trident_context.h"
|
||||
#include "trident_lock.h"
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#include "x86/common_x86_asm.h"
|
||||
#endif
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "context.h"
|
||||
|
||||
#define TRIDENT_DATE "20020318"
|
||||
|
||||
#define TRIDENT_DATE "20041223"
|
||||
|
||||
/* Return the width and height of the current color buffer.
|
||||
*/
|
||||
|
||||
28
src/mesa/drivers/dri/trident/trident_dri.h
Normal file
28
src/mesa/drivers/dri/trident/trident_dri.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _TRIDENT_DRI_
|
||||
#define _TRIDENT_DRI_
|
||||
|
||||
#include "xf86drm.h"
|
||||
|
||||
typedef struct {
|
||||
drm_handle_t regs;
|
||||
drmSize regsSize;
|
||||
drmAddress regsMap;
|
||||
int deviceID;
|
||||
int width;
|
||||
int height;
|
||||
int mem;
|
||||
int frontOffset;
|
||||
int frontPitch;
|
||||
int backOffset;
|
||||
int backPitch;
|
||||
int depthOffset;
|
||||
int depthPitch;
|
||||
int cpp;
|
||||
#if 0
|
||||
int textureOffset;
|
||||
int textureSize;
|
||||
#endif
|
||||
unsigned int sarea_priv_offset;
|
||||
} TRIDENTDRIRec, *TRIDENTDRIPtr;
|
||||
|
||||
#endif
|
||||
11
src/mesa/drivers/dri/trident/trident_lock.h
Normal file
11
src/mesa/drivers/dri/trident/trident_lock.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* XXX tridentGetLock doesn't exist... */
|
||||
|
||||
#define LOCK_HARDWARE(tmesa) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DRM_CAS(tmesa->driHwLock, tmesa->hHWContext, \
|
||||
DRM_LOCK_HELD | tmesa->hHWContext, __ret); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_HARDWARE(tmesa) \
|
||||
DRM_UNLOCK(tmesa->driFd, tmesa->driHwLock, tmesa->hHWContext)
|
||||
@@ -26,7 +26,10 @@
|
||||
*/
|
||||
#include "trident_context.h"
|
||||
#include "trident_lock.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/tnl.h"
|
||||
|
||||
#define TRIDENTPACKCOLOR332(r, g, b) \
|
||||
(((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
|
||||
@@ -90,9 +93,9 @@ void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
unsigned char *MMIO;
|
||||
tridentContextPtr tmesa;
|
||||
GLint nbox, i, ret;
|
||||
GLint nbox, i;
|
||||
int busy;
|
||||
XF86DRIClipRectPtr pbox;
|
||||
drm_clip_rect_t *pbox;
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
@@ -110,7 +113,7 @@ void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv )
|
||||
for ( i = 0 ; i < nbox ; i++ ) {
|
||||
#if 0
|
||||
GLint nr = MIN2( i + MACH64_NR_SAREA_CLIPRECTS , nbox );
|
||||
XF86DRIClipRectPtr b = tmesa->sarea->boxes;
|
||||
drm_clip_rect_t *b = tmesa->sarea->boxes;
|
||||
GLint n = 0;
|
||||
|
||||
for ( ; i < nr ; i++ ) {
|
||||
@@ -151,11 +154,9 @@ static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
{
|
||||
tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
|
||||
unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
|
||||
__DRIdrawablePrivate *dPriv = tmesa->driDrawable;
|
||||
int busy;
|
||||
GLuint flags = 0;
|
||||
GLint i;
|
||||
GLint ret;
|
||||
|
||||
#define DRM_TRIDENT_FRONT 0x01
|
||||
#define DRM_TRIDENT_BACK 0x02
|
||||
@@ -195,8 +196,8 @@ static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||
for ( i = 0 ; i < tmesa->numClipRects ; i++ ) {
|
||||
#if 0
|
||||
int nr = MIN2( i + TRIDENT_NR_SAREA_CLIPRECTS, tmesa->numClipRects );
|
||||
XF86DRIClipRectPtr box = tmesa->pClipRects;
|
||||
XF86DRIClipRectPtr b = tmesa->sarea->boxes;
|
||||
drm_clip_rect_t *box = tmesa->pClipRects;
|
||||
drm_clip_rect_t *b = tmesa->sarea->boxes;
|
||||
GLint n = 0;
|
||||
|
||||
if ( !all ) {
|
||||
@@ -363,12 +364,12 @@ void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
|
||||
switch ( mode ) {
|
||||
case GL_FRONT_LEFT:
|
||||
if (dPriv->numClipRects == 0) {
|
||||
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
|
||||
static drm_clip_rect_t zeroareacliprect = {0,0,0,0};
|
||||
tmesa->numClipRects = 1;
|
||||
tmesa->pClipRects = &zeroareacliprect;
|
||||
} else {
|
||||
tmesa->numClipRects = dPriv->numClipRects;
|
||||
tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
|
||||
tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pClipRects;
|
||||
}
|
||||
tmesa->drawX = dPriv->x;
|
||||
tmesa->drawY = dPriv->y;
|
||||
@@ -376,19 +377,19 @@ void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
|
||||
case GL_BACK_LEFT:
|
||||
if ( dPriv->numBackClipRects == 0 ) {
|
||||
if (dPriv->numClipRects == 0) {
|
||||
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
|
||||
static drm_clip_rect_t zeroareacliprect = {0,0,0,0};
|
||||
tmesa->numClipRects = 1;
|
||||
tmesa->pClipRects = &zeroareacliprect;
|
||||
} else {
|
||||
tmesa->numClipRects = dPriv->numClipRects;
|
||||
tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
|
||||
tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pClipRects;
|
||||
tmesa->drawX = dPriv->x;
|
||||
tmesa->drawY = dPriv->y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmesa->numClipRects = dPriv->numBackClipRects;
|
||||
tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pBackClipRects;
|
||||
tmesa->pClipRects = (drm_clip_rect_t *)dPriv->pBackClipRects;
|
||||
tmesa->drawX = dPriv->backX;
|
||||
tmesa->drawY = dPriv->backY;
|
||||
}
|
||||
@@ -402,6 +403,7 @@ void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GLboolean tridentDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
|
||||
{
|
||||
tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
|
||||
@@ -450,7 +452,7 @@ static void tridentDDClearColor( GLcontext *ctx,
|
||||
color[0], color[1],
|
||||
color[2], color[3] );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void tridentDDUpdateState( GLcontext *ctx, GLuint new_state )
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
|
||||
static int first = 1;
|
||||
|
||||
@@ -277,7 +278,7 @@ void Init3D( tridentContextPtr tmesa )
|
||||
|
||||
int DrawTriangle( tridentContextPtr tmesa)
|
||||
{
|
||||
volatile unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
|
||||
unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
|
||||
dmaBufRec clr;
|
||||
|
||||
printf("DRAW TRI\n");
|
||||
@@ -416,6 +417,7 @@ static INLINE void trident_draw_point(tridentContextPtr tmesa,
|
||||
const tridentVertex *v0 )
|
||||
{
|
||||
unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
|
||||
(void) MMIO;
|
||||
}
|
||||
|
||||
static INLINE void trident_draw_line( tridentContextPtr tmesa,
|
||||
@@ -423,6 +425,7 @@ static INLINE void trident_draw_line( tridentContextPtr tmesa,
|
||||
const tridentVertex *v1 )
|
||||
{
|
||||
unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
|
||||
(void) MMIO;
|
||||
}
|
||||
|
||||
static INLINE void trident_draw_triangle( tridentContextPtr tmesa,
|
||||
@@ -547,6 +550,7 @@ if (vertsize == 4) {
|
||||
* primitives are being drawn, and only for the unaccelerated
|
||||
* primitives.
|
||||
*/
|
||||
#if 0
|
||||
static void
|
||||
trident_fallback_quad( tridentContextPtr tmesa,
|
||||
const tridentVertex *v0,
|
||||
@@ -562,6 +566,11 @@ trident_fallback_quad( tridentContextPtr tmesa,
|
||||
trident_translate_vertex( ctx, v3, &v[3] );
|
||||
_swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX hack to get the prototype defined in time... */
|
||||
void trident_translate_vertex(GLcontext *ctx, const tridentVertex *src,
|
||||
SWvertex *dst);
|
||||
|
||||
static void
|
||||
trident_fallback_tri( tridentContextPtr tmesa,
|
||||
@@ -649,10 +658,10 @@ do { \
|
||||
|
||||
|
||||
static struct {
|
||||
points_func points;
|
||||
line_func line;
|
||||
triangle_func triangle;
|
||||
quad_func quad;
|
||||
tnl_points_func points;
|
||||
tnl_line_func line;
|
||||
tnl_triangle_func triangle;
|
||||
tnl_quad_func quad;
|
||||
} rast_tab[TRIDENT_MAX_TRIFUNC];
|
||||
|
||||
|
||||
@@ -733,7 +742,9 @@ static const GLuint hw_prim[GL_POLYGON+1] = {
|
||||
#endif
|
||||
|
||||
static void tridentResetLineStipple( GLcontext *ctx );
|
||||
#if 0
|
||||
static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim );
|
||||
#endif
|
||||
static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim );
|
||||
|
||||
#define RASTERIZE(x) /*if (tmesa->hw_primitive != hw_prim[x]) \
|
||||
@@ -985,13 +996,14 @@ static void tridentChooseRenderState(GLcontext *ctx)
|
||||
* which renders strips as strips, the equivalent calculations are
|
||||
* performed in tridentrender.c.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim )
|
||||
{
|
||||
tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
|
||||
if (tmesa->hw_primitive != hwprim)
|
||||
tmesa->hw_primitive = hwprim;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim )
|
||||
{
|
||||
@@ -1043,6 +1055,7 @@ static void tridentRenderFinish( GLcontext *ctx )
|
||||
static void tridentResetLineStipple( GLcontext *ctx )
|
||||
{
|
||||
tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
|
||||
(void) tmesa;
|
||||
|
||||
/* Reset the hardware stipple counter.
|
||||
*/
|
||||
|
||||
@@ -26,10 +26,8 @@
|
||||
*/
|
||||
#include "glheader.h"
|
||||
#include "mtypes.h"
|
||||
#include "mem.h"
|
||||
#include "macros.h"
|
||||
#include "colormac.h"
|
||||
#include "mmath.h"
|
||||
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "swrast/swrast.h"
|
||||
@@ -49,8 +47,8 @@
|
||||
|
||||
static struct {
|
||||
void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
|
||||
interp_func interp;
|
||||
copy_pv_func copy_pv;
|
||||
tnl_interp_func interp;
|
||||
tnl_copy_pv_func copy_pv;
|
||||
GLboolean (*check_tex_sizes)( GLcontext *ctx );
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_stride_shift;
|
||||
@@ -77,10 +75,12 @@ static struct {
|
||||
#define DO_PTEX (IND & TRIDENT_PTEX_BIT)
|
||||
|
||||
#define VERTEX tridentVertex
|
||||
#define VERTEX_COLOR trident_color_t
|
||||
#define LOCALVARS tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
|
||||
#define GET_VIEWPORT_MAT() tmesa->hw_viewport
|
||||
#define GET_TEXSOURCE(n) tmesa->tmu_source[n]
|
||||
#define GET_VERTEX_FORMAT() tmesa->vertex_format
|
||||
#define GET_VERTEX_SIZE() tmesa->vertex_size
|
||||
#define GET_VERTEX_STORE() tmesa->verts
|
||||
#define GET_VERTEX_STRIDE_SHIFT() tmesa->vertex_stride_shift
|
||||
#define GET_UBYTE_COLOR_STORE() &tmesa->UbyteColor
|
||||
@@ -310,24 +310,24 @@ void tridentBuildVertices( GLcontext *ctx,
|
||||
if (!newinputs)
|
||||
return;
|
||||
|
||||
if (newinputs & VERT_CLIP) {
|
||||
if (newinputs & VERT_BIT_POS) {
|
||||
setup_tab[tmesa->SetupIndex].emit( ctx, start, count, v, stride );
|
||||
} else {
|
||||
GLuint ind = 0;
|
||||
|
||||
if (newinputs & VERT_RGBA)
|
||||
if (newinputs & VERT_BIT_COLOR0)
|
||||
ind |= TRIDENT_RGBA_BIT;
|
||||
|
||||
if (newinputs & VERT_SPEC_RGB)
|
||||
if (newinputs & VERT_BIT_COLOR1)
|
||||
ind |= TRIDENT_SPEC_BIT;
|
||||
|
||||
if (newinputs & VERT_TEX0)
|
||||
if (newinputs & VERT_BIT_TEX0)
|
||||
ind |= TRIDENT_TEX0_BIT;
|
||||
|
||||
if (newinputs & VERT_TEX1)
|
||||
if (newinputs & VERT_BIT_TEX1)
|
||||
ind |= TRIDENT_TEX1_BIT;
|
||||
|
||||
if (newinputs & VERT_FOG_COORD)
|
||||
if (newinputs & VERT_BIT_FOG)
|
||||
ind |= TRIDENT_FOG_BIT;
|
||||
|
||||
if (tmesa->SetupIndex & TRIDENT_PTEX_BIT)
|
||||
@@ -373,10 +373,9 @@ void tridentChooseVertexState( GLcontext *ctx )
|
||||
if (ctx->Fog.Enabled)
|
||||
ind |= TRIDENT_FOG_BIT;
|
||||
|
||||
if (ctx->Texture._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
ind |= TRIDENT_TEX0_BIT;
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled &&
|
||||
ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
ind |= TRIDENT_TEX1_BIT;
|
||||
}
|
||||
}
|
||||
@@ -424,12 +423,12 @@ void tridentFreeVB( GLcontext *ctx )
|
||||
}
|
||||
|
||||
if (tmesa->UbyteSecondaryColor.Ptr) {
|
||||
ALIGN_FREE(tmesa->UbyteSecondaryColor.Ptr);
|
||||
ALIGN_FREE((void *)tmesa->UbyteSecondaryColor.Ptr);
|
||||
tmesa->UbyteSecondaryColor.Ptr = 0;
|
||||
}
|
||||
|
||||
if (tmesa->UbyteColor.Ptr) {
|
||||
ALIGN_FREE(tmesa->UbyteColor.Ptr);
|
||||
ALIGN_FREE((void *)tmesa->UbyteColor.Ptr);
|
||||
tmesa->UbyteColor.Ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ DRIVER_SOURCES = \
|
||||
via_texmem.c \
|
||||
via_texstate.c \
|
||||
via_tris.c \
|
||||
via_vb.c \
|
||||
via_texcombine.c \
|
||||
xf86drmVIA.c
|
||||
|
||||
|
||||
@@ -40,14 +40,6 @@
|
||||
#define VIA_LOG_MIN_TEX_REGION_SIZE 16
|
||||
#endif
|
||||
|
||||
#define VIA_UPLOAD_TEX0IMAGE 0x1
|
||||
#define VIA_UPLOAD_TEX1IMAGE 0x2
|
||||
#define VIA_UPLOAD_CTX 0x4
|
||||
#define VIA_UPLOAD_BUFFERS 0x8
|
||||
#define VIA_UPLOAD_TEX0 0x10
|
||||
#define VIA_UPLOAD_TEX1 0x20
|
||||
#define VIA_UPLOAD_CLIPRECTS 0x40
|
||||
/*#define VIA_UPLOAD_ALL 0xff*/
|
||||
|
||||
/* VIA specific ioctls */
|
||||
#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(0x40, drm_via_mem_t)
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "via_tex.h"
|
||||
#include "via_span.h"
|
||||
#include "via_tris.h"
|
||||
#include "via_vb.h"
|
||||
#include "via_ioctl.h"
|
||||
#include "via_fb.h"
|
||||
#include "via_regs.h"
|
||||
@@ -68,45 +67,7 @@
|
||||
#ifdef DEBUG
|
||||
GLuint VIA_DEBUG = 0;
|
||||
#endif
|
||||
GLuint DRAW_FRONT = 0;
|
||||
#define DMA_SIZE 2
|
||||
GLuint VIA_PERFORMANCE = 0;
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
GLuint busy = 0;
|
||||
GLuint idle = 0;
|
||||
hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
|
||||
#endif
|
||||
/*=* John Sheng [2003.5.31] agp tex *=*/
|
||||
|
||||
static GLboolean
|
||||
AllocateBuffer(viaContextPtr vmesa)
|
||||
{
|
||||
vmesa->front_base = vmesa->driScreen->pFB;
|
||||
if (vmesa->drawType == GLX_PBUFFER_BIT) {
|
||||
if (vmesa->front.map)
|
||||
via_free_front_buffer(vmesa);
|
||||
if (!via_alloc_front_buffer(vmesa))
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (vmesa->hasBack) {
|
||||
if (vmesa->back.map)
|
||||
via_free_back_buffer(vmesa);
|
||||
if (!via_alloc_back_buffer(vmesa))
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (vmesa->hasDepth || vmesa->hasStencil) {
|
||||
if (vmesa->depth.map)
|
||||
via_free_depth_buffer(vmesa);
|
||||
if (!via_alloc_depth_buffer(vmesa)) {
|
||||
via_free_depth_buffer(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return various strings for \c glGetString.
|
||||
@@ -175,80 +136,92 @@ buffer_align( unsigned width )
|
||||
static GLboolean
|
||||
calculate_buffer_parameters( viaContextPtr vmesa )
|
||||
{
|
||||
const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
|
||||
const unsigned extra = (vmesa->drawType == GLX_PBUFFER_BIT) ? 0 : 32;
|
||||
unsigned w;
|
||||
unsigned h;
|
||||
const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
|
||||
const unsigned extra = 32;
|
||||
unsigned w;
|
||||
unsigned h;
|
||||
|
||||
if (vmesa->drawType == GLX_PBUFFER_BIT) {
|
||||
w = vmesa->driDrawable->w;
|
||||
h = vmesa->driDrawable->h;
|
||||
}
|
||||
else {
|
||||
w = vmesa->viaScreen->width;
|
||||
h = vmesa->viaScreen->height;
|
||||
/* Allocate front-buffer */
|
||||
if (vmesa->drawType == GLX_PBUFFER_BIT) {
|
||||
w = vmesa->driDrawable->w;
|
||||
h = vmesa->driDrawable->h;
|
||||
|
||||
vmesa->front.offset = 0;
|
||||
vmesa->front.map = (char *) vmesa->driScreen->pFB;
|
||||
}
|
||||
vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
|
||||
vmesa->front.pitch = buffer_align( w ) << shift;
|
||||
vmesa->front.size = vmesa->front.pitch * h;
|
||||
|
||||
vmesa->front.pitch = buffer_align( w ) << shift;
|
||||
vmesa->front.size = vmesa->front.pitch * h;
|
||||
if (vmesa->front.map)
|
||||
via_free_draw_buffer(vmesa, &vmesa->front);
|
||||
if (!via_alloc_draw_buffer(vmesa, &vmesa->front))
|
||||
return GL_FALSE;
|
||||
|
||||
}
|
||||
else {
|
||||
w = vmesa->viaScreen->width;
|
||||
h = vmesa->viaScreen->height;
|
||||
|
||||
vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
|
||||
vmesa->front.pitch = buffer_align( w ) << shift;
|
||||
vmesa->front.size = vmesa->front.pitch * h;
|
||||
vmesa->front.offset = 0;
|
||||
vmesa->front.map = (char *) vmesa->driScreen->pFB;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate back-buffer */
|
||||
/* Allocate back-buffer */
|
||||
if (vmesa->hasBack) {
|
||||
vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
|
||||
vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) + extra;
|
||||
vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
|
||||
if (vmesa->back.map)
|
||||
via_free_draw_buffer(vmesa, &vmesa->back);
|
||||
if (!via_alloc_draw_buffer(vmesa, &vmesa->back))
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
/* KW: mem leak if vmesa->hasBack ever changes:
|
||||
*/
|
||||
(void) memset( &vmesa->back, 0, sizeof( vmesa->back ) );
|
||||
}
|
||||
|
||||
vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift)
|
||||
+ extra;
|
||||
vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s backbuffer: w = %d h = %d bpp = %d sizs = %d\n",
|
||||
__FUNCTION__,
|
||||
vmesa->back.pitch,
|
||||
vmesa->driDrawable->h,
|
||||
8 << shift,
|
||||
vmesa->back.size);
|
||||
/* Allocate depth-buffer */
|
||||
if ( vmesa->hasStencil || vmesa->hasDepth ) {
|
||||
vmesa->depth.bpp = vmesa->depthBits;
|
||||
if (vmesa->depth.bpp == 24)
|
||||
vmesa->depth.bpp = 32;
|
||||
|
||||
/* Allocate depth-buffer */
|
||||
if ( vmesa->hasStencil || vmesa->hasDepth ) {
|
||||
const unsigned dShift = (vmesa->hasStencil)
|
||||
? 2 : (vmesa->depthBits / 16);
|
||||
vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * (vmesa->depth.bpp/8)) + extra;
|
||||
vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
|
||||
|
||||
vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) << dShift)
|
||||
+ extra;
|
||||
vmesa->depth.bpp = 8 << dShift;
|
||||
vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
|
||||
}
|
||||
else {
|
||||
(void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
|
||||
}
|
||||
if (vmesa->depth.map)
|
||||
via_free_draw_buffer(vmesa, &vmesa->depth);
|
||||
if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* KW: mem leak if vmesa->hasStencil/hasDepth ever changes:
|
||||
*/
|
||||
(void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
|
||||
}
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s depthbuffer: w = %d h = %d bpp = %d sizs = %d\n",
|
||||
__FUNCTION__,
|
||||
vmesa->depth.pitch,
|
||||
vmesa->driDrawable->h,
|
||||
vmesa->depth.bpp,
|
||||
vmesa->depth.size);
|
||||
|
||||
/*=* John Sheng [2003.5.31] flip *=*/
|
||||
if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
|
||||
vmesa->viaScreen->height == vmesa->driDrawable->h ) {
|
||||
#define ALLOW_EXPERIMENTAL_PAGEFLIP 1
|
||||
/*=* John Sheng [2003.5.31] flip *=*/
|
||||
if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
|
||||
vmesa->viaScreen->height == vmesa->driDrawable->h ) {
|
||||
#define ALLOW_EXPERIMENTAL_PAGEFLIP 0
|
||||
#if ALLOW_EXPERIMENTAL_PAGEFLIP
|
||||
vmesa->doPageFlip = GL_TRUE;
|
||||
vmesa->doPageFlip = GL_TRUE;
|
||||
#else
|
||||
vmesa->doPageFlip = GL_FALSE;
|
||||
vmesa->doPageFlip = GL_FALSE;
|
||||
#endif
|
||||
vmesa->currentPage = 0;
|
||||
vmesa->back.pitch = vmesa->front.pitch;
|
||||
}
|
||||
/* vmesa->currentPage = 0; */
|
||||
assert(vmesa->back.pitch == vmesa->front.pitch);
|
||||
}
|
||||
else
|
||||
vmesa->doPageFlip = GL_FALSE;
|
||||
|
||||
if (!AllocateBuffer(vmesa)) {
|
||||
FREE(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,20 +230,8 @@ void viaReAllocateBuffers(GLframebuffer *drawbuffer)
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx);
|
||||
|
||||
ctx->DrawBuffer->Width = drawbuffer->Width;
|
||||
ctx->DrawBuffer->Height = drawbuffer->Height;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
ctx->DrawBuffer->Accum = 0;
|
||||
|
||||
vmesa->driDrawable->w = ctx->DrawBuffer->Width;
|
||||
vmesa->driDrawable->h = ctx->DrawBuffer->Height;
|
||||
|
||||
LOCK_HARDWARE(vmesa);
|
||||
_swrast_alloc_buffers( drawbuffer );
|
||||
calculate_buffer_parameters( vmesa );
|
||||
UNLOCK_HARDWARE(vmesa);
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
|
||||
@@ -295,6 +256,8 @@ static const char * const card_extensions[] =
|
||||
"GL_EXT_texture_env_combine",
|
||||
"GL_EXT_texture_env_dot3",
|
||||
"GL_EXT_texture_lod_bias",
|
||||
"GL_EXT_secondary_color",
|
||||
"GL_EXT_fog_coord",
|
||||
"GL_NV_blend_square",
|
||||
NULL
|
||||
};
|
||||
@@ -310,10 +273,7 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
|
||||
&_tnl_texgen_stage,
|
||||
&_tnl_texture_transform_stage,
|
||||
/* REMOVE: point attenuation stage */
|
||||
#if 1
|
||||
&_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */
|
||||
&_via_render_stage, /* ADD: modification from _tnl_render_stage */
|
||||
#endif
|
||||
&_tnl_render_stage,
|
||||
0,
|
||||
};
|
||||
@@ -322,52 +282,28 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
|
||||
static GLboolean
|
||||
AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
|
||||
{
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
if (vmesa->dma)
|
||||
via_free_dma_buffer(vmesa);
|
||||
|
||||
if (!via_alloc_dma_buffer(vmesa)) {
|
||||
if (vmesa->front.map)
|
||||
via_free_front_buffer(vmesa);
|
||||
if (vmesa->back.map)
|
||||
via_free_back_buffer(vmesa);
|
||||
if (vmesa->depth.map)
|
||||
via_free_depth_buffer(vmesa);
|
||||
|
||||
if (!via_alloc_dma_buffer(vmesa))
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
|
||||
vmesa->dmaLow = 0;
|
||||
vmesa->dmaCliprectAddr = ~0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
InitVertexBuffer(viaContextPtr vmesa)
|
||||
{
|
||||
GLuint *addr;
|
||||
|
||||
addr = (GLuint *)vmesa->dma;
|
||||
*addr = 0xF210F110;
|
||||
*addr = (HC_ParaType_NotTex << 16);
|
||||
*addr = 0xcccccccc;
|
||||
*addr = 0xdddddddd;
|
||||
|
||||
vmesa->dmaLow = DMA_OFFSET;
|
||||
vmesa->dmaHigh = VIA_DMA_BUFSIZ;
|
||||
vmesa->dmaAddr = (unsigned char *)vmesa->dma;
|
||||
vmesa->dmaLastPrim = vmesa->dmaLow;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeBuffer(viaContextPtr vmesa)
|
||||
{
|
||||
if (vmesa->front.map)
|
||||
via_free_front_buffer(vmesa);
|
||||
via_free_draw_buffer(vmesa, &vmesa->front);
|
||||
|
||||
if (vmesa->back.map)
|
||||
via_free_back_buffer(vmesa);
|
||||
via_free_draw_buffer(vmesa, &vmesa->back);
|
||||
|
||||
if (vmesa->depth.map)
|
||||
via_free_depth_buffer(vmesa);
|
||||
via_free_draw_buffer(vmesa, &vmesa->depth);
|
||||
|
||||
if (vmesa->dma)
|
||||
via_free_dma_buffer(vmesa);
|
||||
@@ -406,31 +342,55 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
sPriv->myNum, "via");
|
||||
|
||||
/* pick back buffer */
|
||||
if (mesaVis->doubleBufferMode) {
|
||||
vmesa->hasBack = GL_TRUE;
|
||||
}
|
||||
else {
|
||||
vmesa->hasBack = GL_FALSE;
|
||||
}
|
||||
/* pick z buffer */
|
||||
if (mesaVis->haveDepthBuffer) {
|
||||
vmesa->hasDepth = GL_TRUE;
|
||||
vmesa->depthBits = mesaVis->depthBits;
|
||||
}
|
||||
else {
|
||||
vmesa->hasDepth = GL_FALSE;
|
||||
vmesa->depthBits = 0;
|
||||
}
|
||||
/* pick stencil buffer */
|
||||
if (mesaVis->haveStencilBuffer) {
|
||||
vmesa->hasStencil = GL_TRUE;
|
||||
vmesa->stencilBits = mesaVis->stencilBits;
|
||||
}
|
||||
else {
|
||||
vmesa->hasStencil = GL_FALSE;
|
||||
vmesa->stencilBits = 0;
|
||||
vmesa->hasBack = mesaVis->doubleBufferMode;
|
||||
|
||||
switch(mesaVis->depthBits) {
|
||||
case 0:
|
||||
vmesa->hasDepth = GL_FALSE;
|
||||
vmesa->depthBits = 0;
|
||||
vmesa->depth_max = 1.0;
|
||||
break;
|
||||
case 16:
|
||||
vmesa->hasDepth = GL_TRUE;
|
||||
vmesa->depthBits = mesaVis->depthBits;
|
||||
vmesa->have_hw_stencil = GL_FALSE;
|
||||
vmesa->depth_max = (GLfloat)0xffff;
|
||||
vmesa->depth_clear_mask = 0xf << 28;
|
||||
vmesa->ClearDepth = 0xffff;
|
||||
vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
|
||||
break;
|
||||
case 24:
|
||||
vmesa->hasDepth = GL_TRUE;
|
||||
vmesa->depthBits = mesaVis->depthBits;
|
||||
vmesa->depth_max = (GLfloat) 0xffffff;
|
||||
vmesa->depth_clear_mask = 0xe << 28;
|
||||
vmesa->ClearDepth = 0xffffff00;
|
||||
|
||||
assert(mesaVis->haveStencilBuffer);
|
||||
assert(mesaVis->stencilBits == 8);
|
||||
|
||||
vmesa->have_hw_stencil = GL_TRUE;
|
||||
vmesa->stencilBits = mesaVis->stencilBits;
|
||||
vmesa->stencil_clear_mask = 0x1 << 28;
|
||||
vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
|
||||
break;
|
||||
case 32:
|
||||
vmesa->hasDepth = GL_TRUE;
|
||||
vmesa->depthBits = mesaVis->depthBits;
|
||||
assert(!mesaVis->haveStencilBuffer);
|
||||
vmesa->have_hw_stencil = GL_FALSE;
|
||||
vmesa->depth_max = (GLfloat)0xffffffff;
|
||||
vmesa->depth_clear_mask = 0;
|
||||
vmesa->ClearDepth = 0xffffffff;
|
||||
vmesa->depth_clear_mask = 0xf << 28;
|
||||
vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
_mesa_init_driver_functions(&functions);
|
||||
viaInitTextureFuncs(&functions);
|
||||
|
||||
@@ -452,33 +412,21 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
|
||||
ctx = vmesa->glCtx;
|
||||
|
||||
/* check */
|
||||
/*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/
|
||||
/*if (viaScreen->textureSize < 2 * 1024 * 1024) {
|
||||
ctx->Const.MaxTextureLevels = 9;
|
||||
}
|
||||
else if (viaScreen->textureSize < 8 * 1024 * 1024) {
|
||||
ctx->Const.MaxTextureLevels = 10;
|
||||
}
|
||||
else {
|
||||
ctx->Const.MaxTextureLevels = 11;
|
||||
}*/
|
||||
ctx->Const.MaxTextureLevels = 11;
|
||||
|
||||
ctx->Const.MaxTextureLevels = 10;
|
||||
ctx->Const.MaxTextureUnits = 2;
|
||||
ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
|
||||
ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
|
||||
|
||||
ctx->Const.MinLineWidth = 1.0;
|
||||
ctx->Const.MinLineWidthAA = 1.0;
|
||||
ctx->Const.MaxLineWidth = 3.0;
|
||||
ctx->Const.MaxLineWidthAA = 3.0;
|
||||
ctx->Const.MaxLineWidth = 1.0;
|
||||
ctx->Const.MaxLineWidthAA = 1.0;
|
||||
ctx->Const.LineWidthGranularity = 1.0;
|
||||
|
||||
ctx->Const.MinPointSize = 1.0;
|
||||
ctx->Const.MinPointSizeAA = 1.0;
|
||||
ctx->Const.MaxPointSize = 3.0;
|
||||
ctx->Const.MaxPointSizeAA = 3.0;
|
||||
ctx->Const.MaxPointSize = 1.0;
|
||||
ctx->Const.MaxPointSizeAA = 1.0;
|
||||
ctx->Const.PointSizeGranularity = 1.0;
|
||||
|
||||
ctx->Driver.GetBufferSize = viaBufferSize;
|
||||
@@ -520,11 +468,8 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
vmesa->glBuffer = NULL;
|
||||
|
||||
vmesa->texHeap = mmInit(0, viaScreen->textureSize);
|
||||
vmesa->stippleInHw = 1;
|
||||
vmesa->renderIndex = ~0;
|
||||
vmesa->dirty = VIA_UPLOAD_ALL;
|
||||
vmesa->uploadCliprects = GL_TRUE;
|
||||
vmesa->needUploadAllState = 1;
|
||||
vmesa->setupIndex = ~0;
|
||||
|
||||
make_empty_list(&vmesa->TexObjList);
|
||||
make_empty_list(&vmesa->SwappedOut);
|
||||
@@ -534,13 +479,21 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
|
||||
_math_matrix_ctr(&vmesa->ViewportMatrix);
|
||||
|
||||
driInitExtensions( ctx, card_extensions, GL_TRUE );
|
||||
/* Do this early, before VIA_FLUSH_DMA can be called:
|
||||
*/
|
||||
if (!AllocateDmaBuffer(mesaVis, vmesa)) {
|
||||
fprintf(stderr ,"AllocateDmaBuffer fail\n");
|
||||
FreeBuffer(vmesa);
|
||||
FREE(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
driInitExtensions( ctx, card_extensions, GL_TRUE );
|
||||
viaInitStateFuncs(ctx);
|
||||
viaInitTextures(ctx);
|
||||
viaInitTriFuncs(ctx);
|
||||
viaInitSpanFuncs(ctx);
|
||||
viaInitIoctlFuncs(ctx);
|
||||
viaInitVB(ctx);
|
||||
viaInitState(ctx);
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -550,27 +503,10 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
VIA_DEBUG = 0;
|
||||
#endif
|
||||
|
||||
if (getenv("DRAW_FRONT"))
|
||||
DRAW_FRONT = 1;
|
||||
else
|
||||
DRAW_FRONT = 0;
|
||||
if (getenv("VIA_NO_RAST"))
|
||||
FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
|
||||
|
||||
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (getenv("VIA_PERFORMANCE"))
|
||||
VIA_PERFORMANCE = 1;
|
||||
else
|
||||
VIA_PERFORMANCE = 0;
|
||||
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < HASH_TABLE_SIZE; i++) {
|
||||
for (j = 0; j < HASH_TABLE_DEPTH; j ++) {
|
||||
hash_table[i][j].count = 0;
|
||||
sprintf(hash_table[i][j].func, "%s", "NULL");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* I don't understand why this isn't working:
|
||||
*/
|
||||
@@ -587,17 +523,9 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
if ( vmesa->get_ust == NULL ) {
|
||||
vmesa->get_ust = get_ust_nop;
|
||||
}
|
||||
(*vmesa->get_ust)( & vmesa->swap_ust );
|
||||
vmesa->get_ust( &vmesa->swap_ust );
|
||||
|
||||
|
||||
if (!AllocateDmaBuffer(mesaVis, vmesa)) {
|
||||
fprintf(stderr ,"AllocateDmaBuffer fail\n");
|
||||
FREE(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
InitVertexBuffer(vmesa);
|
||||
|
||||
vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
|
||||
vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
|
||||
vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
|
||||
@@ -609,43 +537,6 @@ viaCreateContext(const __GLcontextModes *mesaVis,
|
||||
}
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
{
|
||||
#ifndef USE_XINERAMA
|
||||
vmesa->saam = 0;
|
||||
#else
|
||||
GLboolean saam = XineramaIsActive(vmesa->display);
|
||||
int count = 0, fbSize;
|
||||
|
||||
if (saam && vmesa->viaScreen->drixinerama) {
|
||||
vmesa->xsi = XineramaQueryScreens(vmesa->display, &count);
|
||||
/* Test RightOf or Down */
|
||||
if (vmesa->xsi[0].x_org == 0 && vmesa->xsi[0].y_org == 0) {
|
||||
if (vmesa->xsi[1].x_org == vmesa->xsi[1].width) {
|
||||
vmesa->saam = RightOf;
|
||||
}
|
||||
else {
|
||||
vmesa->saam = Down;
|
||||
}
|
||||
}
|
||||
/* Test LeftOf or Up */
|
||||
else if (vmesa->xsi[0].x_org == vmesa->xsi[0].width) {
|
||||
vmesa->saam = LeftOf;
|
||||
}
|
||||
else if (vmesa->xsi[0].y_org == vmesa->xsi[0].height) {
|
||||
vmesa->saam = Up;
|
||||
}
|
||||
else
|
||||
vmesa->saam = 0;
|
||||
|
||||
|
||||
fbSize = vmesa->viaScreen->fbSize;
|
||||
}
|
||||
else
|
||||
vmesa->saam = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
vmesa->pSaamRects = (drm_clip_rect_t *) malloc(sizeof(drm_clip_rect_t));
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
@@ -655,18 +546,16 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
assert(vmesa); /* should never be null */
|
||||
/* viaFlushPrimsLocked(vmesa); */
|
||||
WAIT_IDLE
|
||||
|
||||
if (vmesa) {
|
||||
/*=* John Sheng [2003.5.31] agp tex *=*/
|
||||
WAIT_IDLE(vmesa);
|
||||
if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", vmesa->agpFullCount);
|
||||
|
||||
_swsetup_DestroyContext(vmesa->glCtx);
|
||||
_tnl_DestroyContext(vmesa->glCtx);
|
||||
_ac_DestroyContext(vmesa->glCtx);
|
||||
_swrast_DestroyContext(vmesa->glCtx);
|
||||
viaFreeVB(vmesa->glCtx);
|
||||
FreeBuffer(vmesa);
|
||||
/* free the Mesa context */
|
||||
_mesa_destroy_context(vmesa->glCtx);
|
||||
@@ -674,231 +563,62 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||
FREE(vmesa);
|
||||
}
|
||||
|
||||
P_M_R;
|
||||
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) fprintf(stderr, "idle = %d\n", idle);
|
||||
if (VIA_PERFORMANCE) fprintf(stderr, "busy = %d\n", busy);
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
|
||||
vmesa->numClipRects = dPriv->numClipRects;
|
||||
vmesa->pClipRects = dPriv->pClipRects;
|
||||
vmesa->drawX = dPriv->x;
|
||||
vmesa->drawY = dPriv->y;
|
||||
vmesa->drawW = dPriv->w;
|
||||
vmesa->drawH = dPriv->h;
|
||||
|
||||
viaEmitDrawingRectangle(vmesa);
|
||||
vmesa->uploadCliprects = GL_TRUE;
|
||||
}
|
||||
|
||||
void viaXMesaSetBackClipRects(viaContextPtr vmesa)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
/*=* John Sheng [2003.6.9] fix glxgears dirty screen */
|
||||
/*if (vmesa->saam) {*/
|
||||
vmesa->numClipRects = dPriv->numClipRects;
|
||||
vmesa->pClipRects = dPriv->pClipRects;
|
||||
vmesa->drawX = dPriv->x;
|
||||
vmesa->drawY = dPriv->y;
|
||||
vmesa->drawW = dPriv->w;
|
||||
vmesa->drawH = dPriv->h;
|
||||
/*}
|
||||
else {
|
||||
if (dPriv->numBackClipRects == 0) {
|
||||
vmesa->numClipRects = dPriv->numClipRects;
|
||||
vmesa->pClipRects = dPriv->pClipRects;
|
||||
vmesa->drawX = dPriv->x;
|
||||
vmesa->drawY = dPriv->y;
|
||||
vmesa->drawW = dPriv->w;
|
||||
vmesa->drawH = dPriv->h;
|
||||
}
|
||||
else {
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
vmesa->drawX = dPriv->backX;
|
||||
vmesa->drawY = dPriv->backY;
|
||||
vmesa->drawW = dPriv->w;
|
||||
vmesa->drawH = dPriv->h;
|
||||
}
|
||||
}*/
|
||||
viaEmitDrawingRectangle(vmesa);
|
||||
vmesa->uploadCliprects = GL_TRUE;
|
||||
}
|
||||
|
||||
void viaXMesaWindowMoved(viaContextPtr vmesa)
|
||||
{
|
||||
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
|
||||
#ifdef USE_XINERAMA
|
||||
GLuint side = 0;
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
#endif
|
||||
|
||||
switch (vmesa->glCtx->Color._DrawDestMask[0]) {
|
||||
case __GL_FRONT_BUFFER_MASK:
|
||||
viaXMesaSetFrontClipRects(vmesa);
|
||||
break;
|
||||
case __GL_BACK_BUFFER_MASK:
|
||||
viaXMesaSetBackClipRects(vmesa);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
|
||||
|
||||
#ifndef USE_XINERAMA
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam &= ~S1;
|
||||
vmesa->saam |= S0;
|
||||
#else
|
||||
side = vmesa->saam & P_MASK;
|
||||
|
||||
switch (side) {
|
||||
case RightOf:
|
||||
/* full in screen 1 */
|
||||
if (vmesa->drawX >= vmesa->xsi[0].width) {
|
||||
vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
|
||||
vmesa->drawX = vmesa->drawX - vmesa->xsi[1].width;
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
vmesa->drawX = dPriv->backX;
|
||||
vmesa->drawY = dPriv->backY;
|
||||
vmesa->saam &= ~S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
/* full in screen 0 */
|
||||
else if ((vmesa->drawX + vmesa->drawW) <= vmesa->xsi[0].width) {
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam &= ~S1;
|
||||
vmesa->saam |= S0;
|
||||
}
|
||||
/* between screen 0 && screen 1 */
|
||||
else {
|
||||
vmesa->numSaamRects = dPriv->numBackClipRects;
|
||||
vmesa->pSaamRects = dPriv->pBackClipRects;
|
||||
vmesa->drawXSaam = dPriv->backX;
|
||||
vmesa->drawYSaam = dPriv->backY;
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam |= S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
break;
|
||||
case LeftOf:
|
||||
/* full in screen 1 */
|
||||
if (vmesa->drawX + vmesa->drawW <= 0) {
|
||||
vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
|
||||
vmesa->drawX = vmesa->drawX + vmesa->xsi[1].width;
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
vmesa->drawX = dPriv->backX;
|
||||
vmesa->drawY = dPriv->backY;
|
||||
vmesa->saam &= ~S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
/* full in screen 0 */
|
||||
else if (vmesa->drawX >= 0) {
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam &= ~S1;
|
||||
vmesa->saam |= S0;
|
||||
}
|
||||
/* between screen 0 && screen 1 */
|
||||
else {
|
||||
vmesa->numSaamRects = dPriv->numBackClipRects;
|
||||
vmesa->pSaamRects = dPriv->pBackClipRects;
|
||||
vmesa->drawXSaam = dPriv->backX;
|
||||
vmesa->drawYSaam = dPriv->backY;
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam |= S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
break;
|
||||
case Down :
|
||||
/* full in screen 1 */
|
||||
if (vmesa->drawY >= vmesa->xsi[0].height) {
|
||||
vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
|
||||
vmesa->drawY = vmesa->drawY - vmesa->xsi[1].height;
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
vmesa->drawX = dPriv->backX;
|
||||
vmesa->drawY = dPriv->backY;
|
||||
vmesa->saam &= ~S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
/* full in screen 0 */
|
||||
else if ((vmesa->drawY + vmesa->drawH) <= vmesa->xsi[0].height) {
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam &= ~S1;
|
||||
vmesa->saam |= S0;
|
||||
}
|
||||
/* between screen 0 && screen 1 */
|
||||
else {
|
||||
vmesa->numSaamRects = dPriv->numBackClipRects;
|
||||
vmesa->pSaamRects = dPriv->pBackClipRects;
|
||||
vmesa->drawXSaam = dPriv->backX;
|
||||
vmesa->drawYSaam = dPriv->backY;
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam |= S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
break;
|
||||
case Up :
|
||||
/* full in screen 1 */
|
||||
if ((vmesa->drawY + vmesa->drawH) <= 0) {
|
||||
vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
|
||||
vmesa->drawY = vmesa->drawY + vmesa->xsi[1].height;
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
vmesa->drawX = dPriv->backX;
|
||||
vmesa->drawY = dPriv->backY;
|
||||
vmesa->saam &= ~S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
/* full in screen 0 */
|
||||
else if (vmesa->drawY >= 0) {
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam &= ~S1;
|
||||
vmesa->saam |= S0;
|
||||
}
|
||||
/* between screen 0 && screen 1 */
|
||||
else {
|
||||
vmesa->numSaamRects = dPriv->numBackClipRects;
|
||||
vmesa->pSaamRects = dPriv->pBackClipRects;
|
||||
vmesa->drawXSaam = dPriv->backX;
|
||||
vmesa->drawYSaam = dPriv->backY;
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
vmesa->saam |= S0;
|
||||
vmesa->saam |= S1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vmesa->viaScreen->fbOffset = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
GLuint pitch, offset;
|
||||
pitch = vmesa->front.pitch;
|
||||
offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
|
||||
vmesa->drawXoff = (GLuint)((offset & 0x1f) / bytePerPixel);
|
||||
if (vmesa->saam) {
|
||||
if (vmesa->pSaamRects) {
|
||||
offset = vmesa->viaScreen->fbOffset + (vmesa->pSaamRects[0].y1 * pitch +
|
||||
vmesa->pSaamRects[0].x1 * bytePerPixel);
|
||||
vmesa->drawXoffSaam = (GLuint)((offset & 0x1f) / bytePerPixel);
|
||||
}
|
||||
else
|
||||
vmesa->drawXoffSaam = 0;
|
||||
}
|
||||
else
|
||||
vmesa->drawXoffSaam = 0;
|
||||
}
|
||||
|
||||
viaCalcViewport(vmesa->glCtx);
|
||||
if (!dPriv)
|
||||
return;
|
||||
|
||||
switch (vmesa->glCtx->Color._DrawDestMask[0]) {
|
||||
case DD_FRONT_LEFT_BIT:
|
||||
if (dPriv->numBackClipRects == 0) {
|
||||
vmesa->numClipRects = dPriv->numClipRects;
|
||||
vmesa->pClipRects = dPriv->pClipRects;
|
||||
}
|
||||
else {
|
||||
vmesa->numClipRects = dPriv->numBackClipRects;
|
||||
vmesa->pClipRects = dPriv->pBackClipRects;
|
||||
}
|
||||
break;
|
||||
case DD_BACK_LEFT_BIT:
|
||||
vmesa->numClipRects = dPriv->numClipRects;
|
||||
vmesa->pClipRects = dPriv->pClipRects;
|
||||
break;
|
||||
default:
|
||||
vmesa->numClipRects = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vmesa->drawW != dPriv->w ||
|
||||
vmesa->drawH != dPriv->h)
|
||||
calculate_buffer_parameters( vmesa );
|
||||
|
||||
vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) / bytePerPixel);
|
||||
vmesa->drawX = dPriv->x - vmesa->drawXoff;
|
||||
vmesa->drawY = dPriv->y;
|
||||
vmesa->drawW = dPriv->w;
|
||||
vmesa->drawH = dPriv->h;
|
||||
|
||||
vmesa->front.orig = (vmesa->front.offset +
|
||||
vmesa->drawY * vmesa->front.pitch +
|
||||
vmesa->drawX * bytePerPixel);
|
||||
|
||||
vmesa->front.origMap = (vmesa->front.map +
|
||||
vmesa->drawY * vmesa->front.pitch +
|
||||
vmesa->drawX * bytePerPixel);
|
||||
|
||||
vmesa->back.orig = vmesa->back.offset;
|
||||
vmesa->depth.orig = vmesa->depth.offset;
|
||||
vmesa->back.origMap = vmesa->back.map;
|
||||
vmesa->depth.origMap = vmesa->depth.map;
|
||||
|
||||
viaCalcViewport(vmesa->glCtx);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
@@ -924,6 +644,7 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
|
||||
|
||||
if (driContextPriv) {
|
||||
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
|
||||
GLcontext *ctx = vmesa->glCtx;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", vmesa->driDrawable->w);
|
||||
|
||||
@@ -933,13 +654,24 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
|
||||
if ( ! calculate_buffer_parameters( vmesa ) ) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
|
||||
}
|
||||
|
||||
_mesa_make_current2(vmesa->glCtx,
|
||||
(GLframebuffer *)driDrawPriv->driverPrivate,
|
||||
(GLframebuffer *)driReadPriv->driverPrivate);
|
||||
if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
|
||||
viaXMesaWindowMoved(vmesa);
|
||||
|
||||
/* These are probably needed only the first time a context is
|
||||
* made current:
|
||||
*/
|
||||
viaXMesaWindowMoved(vmesa);
|
||||
ctx->Driver.Scissor(ctx,
|
||||
ctx->Scissor.X,
|
||||
ctx->Scissor.Y,
|
||||
ctx->Scissor.Width,
|
||||
ctx->Scissor.Height);
|
||||
|
||||
}
|
||||
else {
|
||||
_mesa_make_current(0,0);
|
||||
@@ -953,86 +685,29 @@ void viaGetLock(viaContextPtr vmesa, GLuint flags)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
__DRIscreenPrivate *sPriv = vmesa->driScreen;
|
||||
drm_via_sarea_t *sarea = vmesa->sarea;
|
||||
int me = vmesa->hHWContext;
|
||||
__DRIdrawablePrivate *pdp;
|
||||
__DRIscreenPrivate *psp;
|
||||
pdp = dPriv;
|
||||
psp = sPriv;
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
fprintf(stderr, "is: %x non-contend: %x want: %x\n",
|
||||
*(GLuint *)vmesa->driHwLock, vmesa->hHWContext,
|
||||
(DRM_LOCK_HELD|vmesa->hHWContext));
|
||||
}
|
||||
|
||||
drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
|
||||
|
||||
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
|
||||
|
||||
if (sarea->ctxOwner != me) {
|
||||
vmesa->uploadCliprects = GL_TRUE;
|
||||
sarea->ctxOwner = me;
|
||||
vmesa->needUploadAllState = 1;
|
||||
if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
|
||||
vmesa->sarea->ctxOwner = vmesa->hHWContext;
|
||||
vmesa->newEmitState = ~0;
|
||||
}
|
||||
|
||||
viaXMesaWindowMoved(vmesa);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void viaLock(viaContextPtr vmesa, GLuint flags)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
|
||||
__DRIscreenPrivate *sPriv = vmesa->driScreen;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
|
||||
/*=* John Sheng [2003.6.16] for xf43 */
|
||||
if(dPriv->pStamp == NULL)
|
||||
dPriv->pStamp = &dPriv->lastStamp;
|
||||
|
||||
if (*(dPriv->pStamp) != dPriv->lastStamp || vmesa->saam) {
|
||||
GLuint scrn;
|
||||
scrn = vmesa->saam & S_MASK;
|
||||
|
||||
DRM_SPINLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
|
||||
|
||||
if (scrn == S1)
|
||||
__driUtilUpdateDrawableInfo(dPriv);
|
||||
else
|
||||
DRI_VALIDATE_DRAWABLE_INFO_ONCE(dPriv);
|
||||
|
||||
viaXMesaWindowMoved(vmesa);
|
||||
DRM_SPINUNLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
|
||||
if (vmesa->lastStamp != dPriv->lastStamp) {
|
||||
viaXMesaWindowMoved(vmesa);
|
||||
vmesa->lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void viaUnLock(viaContextPtr vmesa, GLuint flags)
|
||||
{
|
||||
drm_via_sarea_t *sarea = vmesa->sarea;
|
||||
int me = vmesa->hHWContext;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
if (VIA_DEBUG) fprintf(stderr, "sarea->ctxOwner = %d\n", sarea->ctxOwner);
|
||||
if (VIA_DEBUG) fprintf(stderr, "me = %d\n", me);
|
||||
if (sarea->ctxOwner == me) {
|
||||
sarea->ctxOwner = 0;
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
if (dPriv && dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
viaContextPtr vmesa;
|
||||
GLcontext *ctx;
|
||||
|
||||
@@ -1048,7 +723,7 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
|
||||
}
|
||||
}
|
||||
else
|
||||
VIA_FIREVERTICES(vmesa);
|
||||
VIA_FLUSH_DMA(vmesa);
|
||||
}
|
||||
else {
|
||||
_mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
|
||||
|
||||
@@ -35,14 +35,13 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
|
||||
#include "mtypes.h"
|
||||
#include "drm.h"
|
||||
#include "mm.h"
|
||||
#include "tnl/t_vertex.h"
|
||||
|
||||
#include "via_screen.h"
|
||||
#include "via_tex.h"
|
||||
#include "via_common.h"
|
||||
#include "xf86drmVIA.h"
|
||||
#ifdef USE_XINERAMA
|
||||
#include "../../../../../include/extensions/Xinerama.h"
|
||||
#endif
|
||||
|
||||
#define VIA_FALLBACK_TEXTURE 0x1
|
||||
#define VIA_FALLBACK_DRAW_BUFFER 0x2
|
||||
#define VIA_FALLBACK_READ_BUFFER 0x4
|
||||
@@ -53,24 +52,14 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
|
||||
#define VIA_FALLBACK_STENCIL 0x100
|
||||
#define VIA_FALLBACK_BLEND_EQ 0x200
|
||||
#define VIA_FALLBACK_BLEND_FUNC 0x400
|
||||
#define VIA_FALLBACK_USER_DISABLE 0x800
|
||||
#define VIA_FALLBACK_PROJ_TEXTURE 0x1000
|
||||
|
||||
#define VIA_DMA_BUFSIZ 4096
|
||||
#define VIA_DMA_HIGHWATER (VIA_DMA_BUFSIZ - 128)
|
||||
|
||||
#define VIA_NO_CLIPRECTS 0x1
|
||||
|
||||
#define VIA_UPLOAD_NONE 0x0000
|
||||
#define VIA_UPLOAD_ALPHATEST 0x0001
|
||||
#define VIA_UPLOAD_BLEND 0x0002
|
||||
#define VIA_UPLOAD_FOG 0x0004
|
||||
#define VIA_UPLOAD_MASK_ROP 0x0008
|
||||
#define VIA_UPLOAD_LINESTIPPLE 0x0010
|
||||
#define VIA_UPLOAD_POLYGONSTIPPLE 0x0020
|
||||
#define VIA_UPLOAD_DEPTH 0x0040
|
||||
#define VIA_UPLOAD_TEXTURE 0x0080
|
||||
#define VIA_UPLOAD_STENCIL 0x0100
|
||||
#define VIA_UPLOAD_CLIPPING 0x0200
|
||||
#define VIA_UPLOAD_DESTBUFFER 0x0400
|
||||
#define VIA_UPLOAD_DEPTHBUFFER 0x0800
|
||||
#define VIA_UPLOAD_ENABLE 0x0800
|
||||
#define VIA_UPLOAD_ALL 0x1000
|
||||
|
||||
#define VIA_DMA_BUFSIZ 500000
|
||||
|
||||
/* Use the templated vertex formats:
|
||||
*/
|
||||
@@ -78,14 +67,6 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
#define RightOf 1
|
||||
#define LeftOf 2
|
||||
#define Down 4
|
||||
#define Up 8
|
||||
#define S0 16
|
||||
#define S1 32
|
||||
#define P_MASK 0x0f;
|
||||
#define S_MASK 0x30;
|
||||
typedef void (*via_tri_func)(viaContextPtr, viaVertex *, viaVertex *,
|
||||
viaVertex *);
|
||||
typedef void (*via_line_func)(viaContextPtr, viaVertex *, viaVertex *);
|
||||
@@ -99,6 +80,10 @@ typedef struct {
|
||||
GLuint pitch;
|
||||
GLuint bpp;
|
||||
char *map;
|
||||
GLuint orig; /* The drawing origin,
|
||||
* at (drawX,drawY) in screen space.
|
||||
*/
|
||||
char *origMap;
|
||||
} viaBuffer, *viaBufferPtr;
|
||||
|
||||
|
||||
@@ -106,7 +91,6 @@ struct via_context_t {
|
||||
GLint refcount;
|
||||
GLcontext *glCtx;
|
||||
GLcontext *shareCtx;
|
||||
unsigned char* front_base;
|
||||
viaBuffer front;
|
||||
viaBuffer back;
|
||||
viaBuffer depth;
|
||||
@@ -116,7 +100,15 @@ struct via_context_t {
|
||||
GLboolean hasAccum;
|
||||
GLuint depthBits;
|
||||
GLuint stencilBits;
|
||||
GLuint *dma;
|
||||
|
||||
GLboolean have_hw_stencil;
|
||||
GLuint ClearDepth;
|
||||
GLuint depth_clear_mask;
|
||||
GLuint stencil_clear_mask;
|
||||
GLfloat depth_max;
|
||||
GLfloat polygon_offset_scale;
|
||||
|
||||
GLubyte *dma;
|
||||
viaRegion tex;
|
||||
|
||||
GLuint isAGP;
|
||||
@@ -132,36 +124,29 @@ struct via_context_t {
|
||||
*/
|
||||
GLuint Fallback;
|
||||
|
||||
/* Temporaries for translating away float colors:
|
||||
*/
|
||||
struct gl_client_array UbyteColor;
|
||||
struct gl_client_array UbyteSecondaryColor;
|
||||
|
||||
/* State for via_vb.c and via_tris.c.
|
||||
/* State for via_tris.c.
|
||||
*/
|
||||
GLuint newState; /* _NEW_* flags */
|
||||
GLuint setupNewInputs;
|
||||
GLuint newEmitState; /* _NEW_* flags */
|
||||
GLuint newRenderState; /* _NEW_* flags */
|
||||
|
||||
struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
|
||||
GLuint vertex_attr_count;
|
||||
|
||||
GLuint setupIndex;
|
||||
GLuint renderIndex;
|
||||
GLmatrix ViewportMatrix;
|
||||
GLenum renderPrimitive;
|
||||
GLenum reducedPrimitive;
|
||||
GLuint hwPrimitive;
|
||||
GLenum hwPrimitive;
|
||||
unsigned char *verts;
|
||||
|
||||
/* drmBufPtr dma_buffer;
|
||||
*/
|
||||
unsigned char* dmaAddr;
|
||||
GLuint dmaLow;
|
||||
GLuint dmaHigh;
|
||||
GLuint dmaCliprectAddr;
|
||||
GLuint dmaLastPrim;
|
||||
GLboolean useAgp;
|
||||
|
||||
GLboolean uploadCliprects;
|
||||
|
||||
GLuint needUploadAllState;
|
||||
GLuint primitiveRendered;
|
||||
|
||||
|
||||
/* Fallback rasterization functions
|
||||
*/
|
||||
@@ -226,16 +211,18 @@ struct via_context_t {
|
||||
GLuint regHTXnTBLRAa_1;
|
||||
GLuint regHTXnTBLRFog_1;
|
||||
|
||||
/* Hardware state
|
||||
*/
|
||||
GLuint dirty;
|
||||
int vertexSize;
|
||||
int vertexStrideShift;
|
||||
int hwVertexSize;
|
||||
GLboolean ptexHack;
|
||||
int coloroffset;
|
||||
int specoffset;
|
||||
|
||||
GLint lastStamp;
|
||||
GLboolean stippleInHw;
|
||||
|
||||
GLenum TexEnvImageFmt[2];
|
||||
GLuint ClearColor;
|
||||
GLuint ClearMask;
|
||||
|
||||
/* DRI stuff
|
||||
*/
|
||||
GLuint needClip;
|
||||
@@ -243,25 +230,15 @@ struct via_context_t {
|
||||
GLboolean doPageFlip;
|
||||
/*=* John Sheng [2003.5.31] flip *=*/
|
||||
GLuint currentPage;
|
||||
char *drawMap; /* draw buffer address in virtual mem */
|
||||
char *readMap;
|
||||
|
||||
viaBuffer *drawBuffer;
|
||||
viaBuffer *readBuffer;
|
||||
int drawX; /* origin of drawable in draw buffer */
|
||||
int drawY;
|
||||
|
||||
int drawW;
|
||||
int drawH;
|
||||
GLuint saam;
|
||||
#ifdef USE_XINERAMA
|
||||
XineramaScreenInfo *xsi;
|
||||
#endif
|
||||
int drawXoffSaam;
|
||||
drm_clip_rect_t *pSaamRects;
|
||||
int drawXSaam;
|
||||
int drawYSaam;
|
||||
GLuint numSaamRects;
|
||||
|
||||
int drawPitch;
|
||||
int readPitch;
|
||||
int drawXoff;
|
||||
GLuint numClipRects; /* cliprects for that buffer */
|
||||
drm_clip_rect_t *pClipRects;
|
||||
@@ -311,72 +288,8 @@ struct via_context_t {
|
||||
PFNGLXGETUSTPROC get_ust;
|
||||
|
||||
};
|
||||
/*#define DMA_OFFSET 16*/
|
||||
#define DMA_OFFSET 32
|
||||
/*#define PERFORMANCE_MEASURE*/
|
||||
|
||||
extern GLuint VIA_PERFORMANCE;
|
||||
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
#define HASH_TABLE_SIZE 1000
|
||||
#define HASH_TABLE_DEPTH 10
|
||||
typedef struct {
|
||||
char func[50];
|
||||
GLuint count;
|
||||
} hash_element;
|
||||
extern hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
|
||||
#define P_M \
|
||||
do { \
|
||||
GLuint h_index,h_depth; \
|
||||
h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE); \
|
||||
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
|
||||
if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) { \
|
||||
sprintf(hash_table[h_index][h_depth].func, "%s", __FUNCTION__); \
|
||||
hash_table[h_index][h_depth].count++; \
|
||||
break; \
|
||||
} \
|
||||
else if (!strcmp(hash_table[h_index][h_depth].func, __FUNCTION__)) { \
|
||||
hash_table[h_index][h_depth].count++; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define P_M_X \
|
||||
do { \
|
||||
GLuint h_index,h_depth; \
|
||||
char str[80]; \
|
||||
strcpy(str, __FUNCTION__); \
|
||||
h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE); \
|
||||
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
|
||||
if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) { \
|
||||
sprintf(hash_table[h_index][h_depth].func, "%s_X", __FUNCTION__); \
|
||||
hash_table[h_index][h_depth].count++; \
|
||||
break; \
|
||||
} \
|
||||
else if (!strcmp(hash_table[h_index][h_depth].func, strcat(str, "_X"))) { \
|
||||
hash_table[h_index][h_depth].count++; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define P_M_R \
|
||||
do { \
|
||||
GLuint h_size, h_depth; \
|
||||
for (h_size = 0; h_size < HASH_TABLE_SIZE; h_size++) { \
|
||||
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
|
||||
if (hash_table[h_size][h_depth].count) { \
|
||||
fprintf(stderr, "func:%s count:%d\n", hash_table[h_size][h_depth].func, hash_table[h_size][h_depth].count); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* PERFORMANCE_MEASURE */
|
||||
#define P_M {}
|
||||
#define P_M_X {}
|
||||
#define P_M_R {}
|
||||
#endif
|
||||
|
||||
#define VIA_CONTEXT(ctx) ((viaContextPtr)(ctx->DriverCtx))
|
||||
|
||||
@@ -386,65 +299,27 @@ extern hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
/*
|
||||
#define LOCK_HARDWARE(vmesa) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DRM_CAS(vmesa->driHwLock, vmesa->hHWContext, \
|
||||
(DRM_LOCK_HELD|vmesa->hHWContext), __ret); \
|
||||
if (__ret) \
|
||||
viaGetLock(vmesa, 0); \
|
||||
} while (0)
|
||||
*/
|
||||
/*=* John Sheng [2003.6.20] fix pci *=*/
|
||||
/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
|
||||
#define LOCK_HARDWARE(vmesa) \
|
||||
if(1) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DRM_CAS(vmesa->driHwLock, vmesa->hHWContext, \
|
||||
(DRM_LOCK_HELD|vmesa->hHWContext), __ret); \
|
||||
if (__ret) \
|
||||
viaGetLock(vmesa, 0); \
|
||||
} while (0); \
|
||||
else \
|
||||
viaLock(vmesa, 0)
|
||||
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
#define LOCK_HARDWARE(vmesa) \
|
||||
viaLock(vmesa, 0);
|
||||
*/
|
||||
|
||||
/* Release the kernel lock.
|
||||
*/
|
||||
/*
|
||||
#define UNLOCK_HARDWARE(vmesa) \
|
||||
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);
|
||||
*/
|
||||
/*=* John Sheng [2003.6.20] fix pci *=*/
|
||||
/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
|
||||
#define UNLOCK_HARDWARE(vmesa) \
|
||||
if(1) \
|
||||
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext); \
|
||||
else \
|
||||
viaUnLock(vmesa, 0);
|
||||
/*
|
||||
#define UNLOCK_HARDWARE(vmesa) \
|
||||
viaUnLock(vmesa, 0);
|
||||
*/
|
||||
#define WAIT_IDLE \
|
||||
while (1) { \
|
||||
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);
|
||||
|
||||
#define WAIT_IDLE(vmesa) \
|
||||
do { \
|
||||
if ((((GLuint)*vmesa->regEngineStatus) & 0xFFFEFFFF) == 0x00020000) \
|
||||
break; \
|
||||
}
|
||||
} while (1)
|
||||
|
||||
#define LOCK_HARDWARE_QUIESCENT(vmesa) \
|
||||
do { \
|
||||
LOCK_HARDWARE(vmesa); \
|
||||
viaRegetLockQuiescent(vmesa); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern GLuint VIA_DEBUG;
|
||||
@@ -453,13 +328,11 @@ extern GLuint VIA_DEBUG;
|
||||
#endif
|
||||
|
||||
|
||||
extern GLuint DRAW_FRONT;
|
||||
extern void viaGetLock(viaContextPtr vmesa, GLuint flags);
|
||||
extern void viaLock(viaContextPtr vmesa, GLuint flags);
|
||||
extern void viaUnLock(viaContextPtr vmesa, GLuint flags);
|
||||
extern void viaEmitHwStateLocked(viaContextPtr vmesa);
|
||||
extern void viaEmitScissorValues(viaContextPtr vmesa, int box_nr, int emit);
|
||||
extern void viaEmitDrawingRectangle(viaContextPtr vmesa);
|
||||
extern void viaXMesaSetBackClipRects(viaContextPtr vmesa);
|
||||
extern void viaXMesaSetFrontClipRects(viaContextPtr vmesa);
|
||||
extern void viaReAllocateBuffers(GLframebuffer *drawbuffer);
|
||||
@@ -468,8 +341,10 @@ extern void viaXMesaWindowMoved(viaContextPtr vmesa);
|
||||
extern void viaTexCombineState(viaContextPtr vmesa,
|
||||
const struct gl_tex_env_combine_state * combine, unsigned unit );
|
||||
|
||||
#define SUBPIXEL_X -.5
|
||||
#define SUBPIXEL_Y -.5
|
||||
/* Via hw already adjusted for GL pixel centers:
|
||||
*/
|
||||
#define SUBPIXEL_X 0
|
||||
#define SUBPIXEL_Y 0
|
||||
|
||||
/* TODO XXX _SOLO temp defines to make code compilable */
|
||||
#ifndef GLX_PBUFFER_BIT
|
||||
|
||||
@@ -1,720 +0,0 @@
|
||||
/*
|
||||
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sub license,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VIA, S3 GRAPHICS, 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.
|
||||
*/
|
||||
|
||||
#if HAVE_RGBA
|
||||
#define VERT_SET_IND(v, c) (void)c
|
||||
#define VERT_COPY_IND(v0, v1)
|
||||
#define VERT_SAVE_IND(idx)
|
||||
#define VERT_RESTORE_IND(idx)
|
||||
#if HAVE_BACK_COLORS
|
||||
#define VERT_SET_RGBA(v, c)
|
||||
#endif
|
||||
#else
|
||||
#define VERT_SET_RGBA(v, c) (void)c
|
||||
#define VERT_COPY_RGBA(v0, v1)
|
||||
#define VERT_SAVE_RGBA(idx)
|
||||
#define VERT_RESTORE_RGBA(idx)
|
||||
#if HAVE_BACK_COLORS
|
||||
#define VERT_SET_IND(v, c)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_SPEC
|
||||
#define VERT_SET_SPEC(v, c) (void)c
|
||||
#define VERT_COPY_SPEC(v0, v1)
|
||||
#define VERT_SAVE_SPEC(idx)
|
||||
#define VERT_RESTORE_SPEC(idx)
|
||||
#if HAVE_BACK_COLORS
|
||||
#define VERT_COPY_SPEC1(v)
|
||||
#endif
|
||||
#else
|
||||
#if HAVE_BACK_COLORS
|
||||
#define VERT_SET_SPEC(v, c)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_BACK_COLORS
|
||||
#define VERT_COPY_SPEC1(v)
|
||||
#define VERT_COPY_IND1(v)
|
||||
#define VERT_COPY_RGBA1(v)
|
||||
#endif
|
||||
|
||||
#ifndef INSANE_VERTICES
|
||||
#define VERT_SET_Z(v, val) VERT_Z(v) = val
|
||||
#define VERT_Z_ADD(v, val) VERT_Z(v) += val
|
||||
#endif
|
||||
|
||||
#if DO_TRI
|
||||
static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2)
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
VERTEX *v[3];
|
||||
GLfloat offset;
|
||||
GLfloat z[3];
|
||||
GLenum mode = GL_FILL;
|
||||
GLuint facing;
|
||||
LOCAL_VARS(3);
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
|
||||
v[0] = (VERTEX *)GET_VERTEX(e0);
|
||||
v[1] = (VERTEX *)GET_VERTEX(e1);
|
||||
v[2] = (VERTEX *)GET_VERTEX(e2);
|
||||
|
||||
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
|
||||
GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
|
||||
GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
|
||||
GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
|
||||
GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
|
||||
GLfloat cc = ex * fy - ey * fx;
|
||||
|
||||
if (DO_TWOSIDE || DO_UNFILLED) {
|
||||
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
|
||||
|
||||
if (DO_UNFILLED) {
|
||||
if (facing) {
|
||||
mode = ctx->Polygon.BackMode;
|
||||
if (ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode != GL_FRONT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mode = ctx->Polygon.FrontMode;
|
||||
if (ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode != GL_BACK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TWOSIDE && facing == 1) {
|
||||
if (HAVE_RGBA) {
|
||||
if (HAVE_BACK_COLORS) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_COPY_RGBA1(v[0]);
|
||||
VERT_COPY_RGBA1(v[1]);
|
||||
}
|
||||
VERT_SAVE_RGBA(2);
|
||||
VERT_COPY_RGBA1(v[2]);
|
||||
if (HAVE_SPEC) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_COPY_SPEC1(v[0]);
|
||||
VERT_COPY_SPEC1(v[1]);
|
||||
}
|
||||
VERT_SAVE_SPEC(2);
|
||||
VERT_COPY_SPEC1(v[2]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
|
||||
ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
|
||||
(void)vbcolor;
|
||||
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_SET_RGBA(v[0], vbcolor[e0]);
|
||||
VERT_SET_RGBA(v[1], vbcolor[e1]);
|
||||
}
|
||||
VERT_SAVE_RGBA(2);
|
||||
VERT_SET_RGBA(v[2], vbcolor[e2]);
|
||||
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
|
||||
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
|
||||
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_SET_SPEC(v[0], vbspec[e0]);
|
||||
VERT_SET_SPEC(v[1], vbspec[e1]);
|
||||
}
|
||||
VERT_SAVE_SPEC(2);
|
||||
VERT_SET_SPEC(v[2], vbspec[e2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_IND( 0 );
|
||||
VERT_SAVE_IND( 1 );
|
||||
VERT_SET_IND(v[0], vbindex[e0]);
|
||||
VERT_SET_IND(v[1], vbindex[e1]);
|
||||
}
|
||||
VERT_SAVE_IND( 2 );
|
||||
VERT_SET_IND(v[2], vbindex[e2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_OFFSET) {
|
||||
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
|
||||
z[0] = VERT_Z(v[0]);
|
||||
z[1] = VERT_Z(v[1]);
|
||||
z[2] = VERT_Z(v[2]);
|
||||
if (cc * cc > 1e-16) {
|
||||
GLfloat ic = 1.0 / cc;
|
||||
GLfloat ez = z[0] - z[2];
|
||||
GLfloat fz = z[1] - z[2];
|
||||
GLfloat a = ey * fz - ez * fy;
|
||||
GLfloat b = ez * fx - ex * fz;
|
||||
GLfloat ac = a * ic;
|
||||
GLfloat bc = b * ic;
|
||||
if (ac < 0.0f) ac = -ac;
|
||||
if (bc < 0.0f) bc = -bc;
|
||||
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
|
||||
}
|
||||
offset *= ctx->MRD;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_COPY_RGBA(v[0], v[2]);
|
||||
VERT_COPY_RGBA(v[1], v[2]);
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_COPY_SPEC(v[0], v[2]);
|
||||
VERT_COPY_SPEC(v[1], v[2]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_SAVE_IND(0);
|
||||
VERT_SAVE_IND(1);
|
||||
VERT_COPY_IND(v[0], v[2]);
|
||||
VERT_COPY_IND(v[1], v[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == GL_POINT) {
|
||||
if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
}
|
||||
UNFILLED_TRI(ctx, GL_POINT, e0, e1, e2);
|
||||
}
|
||||
else if (mode == GL_LINE) {
|
||||
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
}
|
||||
UNFILLED_TRI(ctx, GL_LINE, e0, e1, e2);
|
||||
}
|
||||
else {
|
||||
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
}
|
||||
if (DO_UNFILLED)
|
||||
RASTERIZE(GL_TRIANGLES);
|
||||
TRI(v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
if (DO_OFFSET) {
|
||||
VERT_SET_Z(v[0], z[0]);
|
||||
VERT_SET_Z(v[1], z[1]);
|
||||
VERT_SET_Z(v[2], z[2]);
|
||||
}
|
||||
|
||||
if (DO_TWOSIDE && facing == 1) {
|
||||
if (HAVE_RGBA) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_RGBA(0);
|
||||
VERT_RESTORE_RGBA(1);
|
||||
}
|
||||
VERT_RESTORE_RGBA(2);
|
||||
if (HAVE_SPEC) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_SPEC(0);
|
||||
VERT_RESTORE_SPEC(1);
|
||||
}
|
||||
VERT_RESTORE_SPEC(2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_IND( 0 );
|
||||
VERT_RESTORE_IND( 1 );
|
||||
}
|
||||
VERT_RESTORE_IND( 2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_RESTORE_RGBA(0);
|
||||
VERT_RESTORE_RGBA(1);
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_RESTORE_SPEC(0);
|
||||
VERT_RESTORE_SPEC(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_RESTORE_IND(0);
|
||||
VERT_RESTORE_IND(1);
|
||||
}
|
||||
}
|
||||
SET_PRIMITIVE_RENDERED
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DO_QUAD
|
||||
#if DO_FULL_QUAD
|
||||
static void TAG(quad)(GLcontext *ctx,
|
||||
GLuint e0, GLuint e1, GLuint e2, GLuint e3)
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
|
||||
VERTEX *v[4];
|
||||
GLfloat offset;
|
||||
GLfloat z[4];
|
||||
GLenum mode = GL_FILL;
|
||||
GLuint facing;
|
||||
LOCAL_VARS(4);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
v[0] = (VERTEX *)GET_VERTEX(e0);
|
||||
v[1] = (VERTEX *)GET_VERTEX(e1);
|
||||
v[2] = (VERTEX *)GET_VERTEX(e2);
|
||||
v[3] = (VERTEX *)GET_VERTEX(e3);
|
||||
|
||||
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
|
||||
GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
|
||||
GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
|
||||
GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
|
||||
GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
|
||||
GLfloat cc = ex * fy - ey * fx;
|
||||
|
||||
if (DO_TWOSIDE || DO_UNFILLED) {
|
||||
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
|
||||
|
||||
if (DO_UNFILLED) {
|
||||
if (facing) {
|
||||
mode = ctx->Polygon.BackMode;
|
||||
if (ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode != GL_FRONT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mode = ctx->Polygon.FrontMode;
|
||||
if (ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode != GL_BACK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TWOSIDE && facing == 1) {
|
||||
if (HAVE_RGBA) {
|
||||
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
|
||||
(void)vbcolor;
|
||||
|
||||
if (HAVE_BACK_COLORS) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_SAVE_RGBA(2);
|
||||
VERT_COPY_RGBA1(v[0]);
|
||||
VERT_COPY_RGBA1(v[1]);
|
||||
VERT_COPY_RGBA1(v[2]);
|
||||
}
|
||||
VERT_SAVE_RGBA(3);
|
||||
VERT_COPY_RGBA1(v[3]);
|
||||
if (HAVE_SPEC) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_SAVE_SPEC(2);
|
||||
VERT_COPY_SPEC1(v[0]);
|
||||
VERT_COPY_SPEC1(v[1]);
|
||||
VERT_COPY_SPEC1(v[2]);
|
||||
}
|
||||
VERT_SAVE_SPEC(3);
|
||||
VERT_COPY_SPEC1(v[3]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_SAVE_RGBA(2);
|
||||
VERT_SET_RGBA(v[0], vbcolor[e0]);
|
||||
VERT_SET_RGBA(v[1], vbcolor[e1]);
|
||||
VERT_SET_RGBA(v[2], vbcolor[e2]);
|
||||
}
|
||||
VERT_SAVE_RGBA(3);
|
||||
VERT_SET_RGBA(v[3], vbcolor[e3]);
|
||||
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
|
||||
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
|
||||
ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
|
||||
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_SAVE_SPEC(2);
|
||||
VERT_SET_SPEC(v[0], vbspec[e0]);
|
||||
VERT_SET_SPEC(v[1], vbspec[e1]);
|
||||
VERT_SET_SPEC(v[2], vbspec[e2]);
|
||||
}
|
||||
VERT_SAVE_SPEC(3);
|
||||
VERT_SET_SPEC(v[3], vbspec[e3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
|
||||
if (!DO_FLAT) {
|
||||
VERT_SAVE_IND( 0 );
|
||||
VERT_SAVE_IND( 1 );
|
||||
VERT_SAVE_IND( 2 );
|
||||
VERT_SET_IND(v[0], vbindex[e0]);
|
||||
VERT_SET_IND(v[1], vbindex[e1]);
|
||||
VERT_SET_IND(v[2], vbindex[e2]);
|
||||
}
|
||||
VERT_SAVE_IND( 3 );
|
||||
VERT_SET_IND(v[3], vbindex[e3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (DO_OFFSET) {
|
||||
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
|
||||
z[0] = VERT_Z(v[0]);
|
||||
z[1] = VERT_Z(v[1]);
|
||||
z[2] = VERT_Z(v[2]);
|
||||
z[3] = VERT_Z(v[3]);
|
||||
if (cc * cc > 1e-16) {
|
||||
GLfloat ez = z[2] - z[0];
|
||||
GLfloat fz = z[3] - z[1];
|
||||
GLfloat a = ey * fz - ez * fy;
|
||||
GLfloat b = ez * fx - ex * fz;
|
||||
GLfloat ic = 1.0 / cc;
|
||||
GLfloat ac = a * ic;
|
||||
GLfloat bc = b * ic;
|
||||
if ( ac < 0.0f ) ac = -ac;
|
||||
if ( bc < 0.0f ) bc = -bc;
|
||||
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
|
||||
}
|
||||
offset *= ctx->MRD;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_SAVE_RGBA(0);
|
||||
VERT_SAVE_RGBA(1);
|
||||
VERT_SAVE_RGBA(2);
|
||||
VERT_COPY_RGBA(v[0], v[3]);
|
||||
VERT_COPY_RGBA(v[1], v[3]);
|
||||
VERT_COPY_RGBA(v[2], v[3]);
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_SAVE_SPEC(1);
|
||||
VERT_SAVE_SPEC(2);
|
||||
VERT_COPY_SPEC(v[0], v[3]);
|
||||
VERT_COPY_SPEC(v[1], v[3]);
|
||||
VERT_COPY_SPEC(v[2], v[3]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_SAVE_IND(0);
|
||||
VERT_SAVE_IND(1);
|
||||
VERT_SAVE_IND(2);
|
||||
VERT_COPY_IND(v[0], v[3]);
|
||||
VERT_COPY_IND(v[1], v[3]);
|
||||
VERT_COPY_IND(v[2], v[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == GL_POINT) {
|
||||
if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
VERT_Z_ADD(v[3], offset);
|
||||
}
|
||||
UNFILLED_QUAD(ctx, GL_POINT, e0, e1, e2, e3);
|
||||
}
|
||||
else if (mode == GL_LINE) {
|
||||
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
VERT_Z_ADD(v[3], offset);
|
||||
}
|
||||
UNFILLED_QUAD(ctx, GL_LINE, e0, e1, e2, e3);
|
||||
}
|
||||
else {
|
||||
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
|
||||
VERT_Z_ADD(v[0], offset);
|
||||
VERT_Z_ADD(v[1], offset);
|
||||
VERT_Z_ADD(v[2], offset);
|
||||
VERT_Z_ADD(v[3], offset);
|
||||
}
|
||||
RASTERIZE(GL_TRIANGLES);
|
||||
QUAD((v[0]), (v[1]), (v[2]), (v[3]));
|
||||
}
|
||||
|
||||
if (DO_OFFSET) {
|
||||
VERT_SET_Z(v[0], z[0]);
|
||||
VERT_SET_Z(v[1], z[1]);
|
||||
VERT_SET_Z(v[2], z[2]);
|
||||
VERT_SET_Z(v[3], z[3]);
|
||||
}
|
||||
|
||||
if (DO_TWOSIDE && facing == 1) {
|
||||
if (HAVE_RGBA) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_RGBA(0);
|
||||
VERT_RESTORE_RGBA(1);
|
||||
VERT_RESTORE_RGBA(2);
|
||||
}
|
||||
VERT_RESTORE_RGBA(3);
|
||||
if (HAVE_SPEC) {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_SPEC(0);
|
||||
VERT_RESTORE_SPEC(1);
|
||||
VERT_RESTORE_SPEC(2);
|
||||
}
|
||||
VERT_RESTORE_SPEC(3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!DO_FLAT) {
|
||||
VERT_RESTORE_IND( 0 );
|
||||
VERT_RESTORE_IND( 1 );
|
||||
VERT_RESTORE_IND( 2 );
|
||||
}
|
||||
VERT_RESTORE_IND( 3 );
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_RESTORE_RGBA(0);
|
||||
VERT_RESTORE_RGBA(1);
|
||||
VERT_RESTORE_RGBA(2);
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_RESTORE_SPEC(0);
|
||||
VERT_RESTORE_SPEC(1);
|
||||
VERT_RESTORE_SPEC(2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_RESTORE_IND(0);
|
||||
VERT_RESTORE_IND(1);
|
||||
VERT_RESTORE_IND(2);
|
||||
}
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
#else
|
||||
static void TAG(quad)(GLcontext *ctx, GLuint e0,
|
||||
GLuint e1, GLuint e2, GLuint e3)
|
||||
{
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
if (DO_UNFILLED) {
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLubyte ef1 = VB->EdgeFlag[e1];
|
||||
GLubyte ef3 = VB->EdgeFlag[e3];
|
||||
VB->EdgeFlag[e1] = 0;
|
||||
TAG(triangle)(ctx, e0, e1, e3);
|
||||
VB->EdgeFlag[e1] = ef1;
|
||||
VB->EdgeFlag[e3] = 0;
|
||||
TAG(triangle)(ctx, e1, e2, e3);
|
||||
VB->EdgeFlag[e3] = ef3;
|
||||
}
|
||||
else {
|
||||
TAG(triangle)(ctx, e0, e1, e3);
|
||||
TAG(triangle)(ctx, e1, e2, e3);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DO_LINE
|
||||
static void TAG(line)(GLcontext *ctx, GLuint e0, GLuint e1)
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
VERTEX *v[2];
|
||||
LOCAL_VARS(2);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
v[0] = (VERTEX *)GET_VERTEX(e0);
|
||||
v[1] = (VERTEX *)GET_VERTEX(e1);
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_SAVE_RGBA( 0 );
|
||||
VERT_COPY_RGBA( v[0], v[1] );
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_SAVE_SPEC(0);
|
||||
VERT_COPY_SPEC(v[0], v[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_SAVE_IND(0);
|
||||
VERT_COPY_IND(v[0], v[1]);
|
||||
}
|
||||
}
|
||||
|
||||
LINE(v[0], v[1]);
|
||||
|
||||
if (DO_FLAT) {
|
||||
if (HAVE_RGBA) {
|
||||
VERT_RESTORE_RGBA(0);
|
||||
|
||||
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
|
||||
VERT_RESTORE_SPEC(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VERT_RESTORE_IND(0);
|
||||
}
|
||||
}
|
||||
SET_PRIMITIVE_RENDERED
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DO_POINTS
|
||||
static void TAG(points)(GLcontext *ctx, GLuint first, GLuint last)
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
int i;
|
||||
LOCAL_VARS(1);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
if (VB->Elts == 0) {
|
||||
for (i = first; i < last; i++) {
|
||||
if (VB->ClipMask[i] == 0) {
|
||||
VERTEX *v = (VERTEX *)GET_VERTEX(i);
|
||||
POINT(v);
|
||||
SET_PRIMITIVE_RENDERED
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = first; i < last; i++) {
|
||||
GLuint e = VB->Elts[i];
|
||||
if (VB->ClipMask[e] == 0) {
|
||||
VERTEX *v = (VERTEX *)GET_VERTEX(e);
|
||||
POINT(v);
|
||||
SET_PRIMITIVE_RENDERED
|
||||
}
|
||||
}
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void TAG(init)(void)
|
||||
{
|
||||
#if DO_QUAD
|
||||
TAB[IND].quad = TAG(quad);
|
||||
#endif
|
||||
#if DO_TRI
|
||||
TAB[IND].triangle = TAG(triangle);
|
||||
#endif
|
||||
#if DO_LINE
|
||||
TAB[IND].line = TAG(line);
|
||||
#endif
|
||||
#if DO_POINTS
|
||||
TAB[IND].points = TAG(points);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef IND
|
||||
#undef TAG
|
||||
|
||||
#if HAVE_RGBA
|
||||
#undef VERT_SET_IND
|
||||
#undef VERT_COPY_IND
|
||||
#undef VERT_SAVE_IND
|
||||
#undef VERT_RESTORE_IND
|
||||
#if HAVE_BACK_COLORS
|
||||
#undef VERT_SET_RGBA
|
||||
#endif
|
||||
#else
|
||||
#undef VERT_SET_RGBA
|
||||
#undef VERT_COPY_RGBA
|
||||
#undef VERT_SAVE_RGBA
|
||||
#undef VERT_RESTORE_RGBA
|
||||
#if HAVE_BACK_COLORS
|
||||
#undef VERT_SET_IND
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_SPEC
|
||||
#undef VERT_SET_SPEC
|
||||
#undef VERT_COPY_SPEC
|
||||
#undef VERT_SAVE_SPEC
|
||||
#undef VERT_RESTORE_SPEC
|
||||
#if HAVE_BACK_COLORS
|
||||
#undef VERT_COPY_SPEC1
|
||||
#endif
|
||||
#else
|
||||
#if HAVE_BACK_COLORS
|
||||
#undef VERT_SET_SPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_BACK_COLORS
|
||||
#undef VERT_COPY_SPEC1
|
||||
#undef VERT_COPY_IND1
|
||||
#undef VERT_COPY_RGBA1
|
||||
#endif
|
||||
|
||||
#ifndef INSANE_VERTICES
|
||||
#undef VERT_SET_Z
|
||||
#undef VERT_Z_ADD
|
||||
#endif
|
||||
@@ -1,716 +0,0 @@
|
||||
/*
|
||||
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sub license,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VIA, S3 GRAPHICS, 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.
|
||||
*/
|
||||
|
||||
|
||||
/* Unlike the other templates here, this assumes quite a bit about the
|
||||
* underlying hardware. Specifically it assumes a d3d-like vertex
|
||||
* format, with a layout more or less constrained to look like the
|
||||
* following:
|
||||
*
|
||||
* union {
|
||||
* struct {
|
||||
* float x, y, z, w;
|
||||
* struct { char r, g, b, a; } color;
|
||||
* struct { char r, g, b, fog; } spec;
|
||||
* float u0, v0;
|
||||
* float u1, v1;
|
||||
* float u2, v2;
|
||||
* float u3, v3;
|
||||
* } v;
|
||||
* struct {
|
||||
* float x, y, z, w;
|
||||
* struct { char r, g, b, a; } color;
|
||||
* struct { char r, g, b, fog; } spec;
|
||||
* float u0, v0, q0;
|
||||
* float u1, v1, q1;
|
||||
* float u2, v2, q2;
|
||||
* float u3, v3, q3;
|
||||
* } pv;
|
||||
* struct {
|
||||
* float x, y, z;
|
||||
* struct { char r, g, b, a; } color;
|
||||
* } tv;
|
||||
* float f[16];
|
||||
* unsigned int ui[16];
|
||||
* unsigned char ub4[4][16];
|
||||
* }
|
||||
*
|
||||
|
||||
* DO_XYZW: Emit xyz and maybe w coordinates.
|
||||
* DO_RGBA: Emit color.
|
||||
* DO_SPEC: Emit specular color.
|
||||
* DO_FOG: Emit fog coordinate in specular alpha.
|
||||
* DO_TEX0: Emit tex0 u,v coordinates.
|
||||
* DO_TEX1: Emit tex1 u,v coordinates.
|
||||
* DO_TEX2: Emit tex2 u,v coordinates.
|
||||
* DO_TEX3: Emit tex3 u,v coordinates.
|
||||
* DO_PTEX: Emit tex0,1,2,3 q coordinates where possible.
|
||||
*
|
||||
* HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra).
|
||||
*
|
||||
* HAVE_HW_VIEWPORT: Hardware performs viewport transform.
|
||||
* HAVE_HW_DIVIDE: Hardware performs perspective divide.
|
||||
*
|
||||
* HAVE_TINY_VERTICES: Hardware understands v.tv format.
|
||||
* HAVE_PTEX_VERTICES: Hardware understands v.pv format.
|
||||
* HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0.
|
||||
*
|
||||
* Additionally, this template assumes it is emitting *transformed*
|
||||
* vertices; the modifications to emit untransformed vertices (ie. to
|
||||
* t&l hardware) are probably too great to cooexist with the code
|
||||
* already in this file.
|
||||
*
|
||||
* NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if
|
||||
* only TEX0 is enabled, in order to maintain a vertex size which is
|
||||
* an exact number of quadwords.
|
||||
*/
|
||||
|
||||
#if (HAVE_HW_VIEWPORT)
|
||||
#define VIEWPORT_X(dst, x) dst = x
|
||||
#define VIEWPORT_Y(dst, y) dst = y
|
||||
#define VIEWPORT_Z(dst, z) dst = z
|
||||
#else
|
||||
#define VIEWPORT_X(dst, x) dst = s[0] * x + s[12]
|
||||
#define VIEWPORT_Y(dst, y) dst = s[5] * y + s[13]
|
||||
#define VIEWPORT_Z(dst, z) dst = s[10] * z + s[14]
|
||||
#endif
|
||||
|
||||
#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES)
|
||||
#error "can't cope with this combination"
|
||||
#endif
|
||||
|
||||
#ifndef LOCALVARS
|
||||
#define LOCALVARS
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HW_DIVIDE
|
||||
#define CHECK_HW_DIVIDE 1
|
||||
#endif
|
||||
|
||||
#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES)
|
||||
|
||||
static void TAG(emit)(GLcontext *ctx,
|
||||
GLuint start, GLuint end,
|
||||
void *dest,
|
||||
GLuint stride)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
|
||||
GLfloat (*tc2)[4], (*tc3)[4];
|
||||
GLfloat (*col)[4], (*spec)[4];
|
||||
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
|
||||
GLuint tc2_stride, tc3_stride;
|
||||
GLuint tc0_size, tc1_size;
|
||||
GLuint tc2_size, tc3_size;
|
||||
GLfloat (*coord)[4];
|
||||
GLuint coord_stride;
|
||||
VERTEX *v = (VERTEX *)dest;
|
||||
const GLfloat *s = GET_VIEWPORT_MAT();
|
||||
const GLubyte *mask = VB->ClipMask;
|
||||
int i;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "TAG-emit for HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICE\n");
|
||||
|
||||
if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
|
||||
(void) s;
|
||||
coord = VB->ClipPtr->data;
|
||||
coord_stride = VB->ClipPtr->stride;
|
||||
}
|
||||
else {
|
||||
coord = VB->NdcPtr->data;
|
||||
coord_stride = VB->NdcPtr->stride;
|
||||
}
|
||||
|
||||
if (DO_TEX3) {
|
||||
const GLuint t3 = GET_TEXSOURCE(3);
|
||||
tc3 = VB->TexCoordPtr[t3]->data;
|
||||
tc3_stride = VB->TexCoordPtr[t3]->stride;
|
||||
if (DO_PTEX)
|
||||
tc3_size = VB->TexCoordPtr[t3]->size;
|
||||
}
|
||||
|
||||
if (DO_TEX2) {
|
||||
const GLuint t2 = GET_TEXSOURCE(2);
|
||||
tc2 = VB->TexCoordPtr[t2]->data;
|
||||
tc2_stride = VB->TexCoordPtr[t2]->stride;
|
||||
if (DO_PTEX)
|
||||
tc2_size = VB->TexCoordPtr[t2]->size;
|
||||
}
|
||||
|
||||
if (DO_TEX1) {
|
||||
const GLuint t1 = GET_TEXSOURCE(1);
|
||||
tc1 = VB->TexCoordPtr[t1]->data;
|
||||
tc1_stride = VB->TexCoordPtr[t1]->stride;
|
||||
if (DO_PTEX)
|
||||
tc1_size = VB->TexCoordPtr[t1]->size;
|
||||
}
|
||||
|
||||
if (DO_TEX0) {
|
||||
const GLuint t0 = GET_TEXSOURCE(0);
|
||||
/* test */
|
||||
tc0_stride = VB->TexCoordPtr[t0]->stride;
|
||||
tc0 = VB->TexCoordPtr[t0]->data;
|
||||
if (DO_PTEX)
|
||||
tc0_size = VB->TexCoordPtr[t0]->size;
|
||||
}
|
||||
|
||||
if (DO_RGBA) {
|
||||
col = VB->ColorPtr[0]->data;
|
||||
col_stride = VB->ColorPtr[0]->stride;
|
||||
}
|
||||
|
||||
if (DO_SPEC) {
|
||||
spec = VB->SecondaryColorPtr[0]->data;
|
||||
spec_stride = VB->SecondaryColorPtr[0]->stride;
|
||||
}
|
||||
|
||||
if (DO_FOG) {
|
||||
if (VB->FogCoordPtr) {
|
||||
fog = VB->FogCoordPtr->data;
|
||||
fog_stride = VB->FogCoordPtr->stride;
|
||||
}
|
||||
else {
|
||||
static GLfloat tmp[4] = { 0, 0, 0, 0 };
|
||||
fog = &tmp;
|
||||
fog_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* May have nonstandard strides:
|
||||
*/
|
||||
if (start) {
|
||||
STRIDE_4F(coord, start * coord_stride);
|
||||
if (DO_TEX0)
|
||||
STRIDE_4F(tc0, start * tc0_stride);
|
||||
if (DO_TEX1)
|
||||
STRIDE_4F(tc1, start * tc1_stride);
|
||||
if (DO_TEX2)
|
||||
STRIDE_4F(tc2, start * tc2_stride);
|
||||
if (DO_TEX3)
|
||||
STRIDE_4F(tc3, start * tc3_stride);
|
||||
if (DO_RGBA)
|
||||
STRIDE_4F(col, start * col_stride);
|
||||
if (DO_SPEC)
|
||||
STRIDE_4F(spec, start * spec_stride);
|
||||
if (DO_FOG)
|
||||
STRIDE_4F(fog, start * fog_stride);
|
||||
}
|
||||
|
||||
for (i = start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
|
||||
if (DO_XYZW) {
|
||||
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
|
||||
VIEWPORT_X(v->v.x, coord[0][0]);
|
||||
VIEWPORT_Y(v->v.y, coord[0][1]);
|
||||
VIEWPORT_Z(v->v.z, coord[0][2]);
|
||||
}
|
||||
v->v.w = coord[0][3];
|
||||
STRIDE_4F(coord, coord_stride);
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
|
||||
STRIDE_4F(col, col_stride);
|
||||
}
|
||||
|
||||
if (DO_SPEC) {
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
|
||||
STRIDE_4F(spec, spec_stride);
|
||||
}
|
||||
else {
|
||||
v->v.specular.red = 0;
|
||||
v->v.specular.green = 0;
|
||||
v->v.specular.blue = 0;
|
||||
}
|
||||
|
||||
if (DO_FOG) {
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
|
||||
/*=* [DBG] exy : fix lighting on + fog off error *=*/
|
||||
STRIDE_4F(fog, fog_stride);
|
||||
}
|
||||
else {
|
||||
v->v.specular.alpha = 0;
|
||||
}
|
||||
|
||||
if (DO_TEX0) {
|
||||
v->v.u0 = tc0[0][0];
|
||||
v->v.v0 = tc0[0][1];
|
||||
if (DO_PTEX) {
|
||||
if (HAVE_PTEX_VERTICES) {
|
||||
if (tc0_size == 4)
|
||||
v->pv.q0 = tc0[0][3];
|
||||
else
|
||||
v->pv.q0 = 1.0;
|
||||
}
|
||||
else if (tc0_size == 4) {
|
||||
float rhw = 1.0 / tc0[0][3];
|
||||
v->v.w *= tc0[0][3];
|
||||
v->v.u0 *= rhw;
|
||||
v->v.v0 *= rhw;
|
||||
}
|
||||
}
|
||||
STRIDE_4F(tc0, tc0_stride);
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
if (DO_PTEX && HAVE_PTEX_VERTICES) {
|
||||
v->pv.u1 = tc1[0][0];
|
||||
v->pv.v1 = tc1[0][1];
|
||||
if (tc1_size == 4)
|
||||
v->pv.q1 = tc1[0][3];
|
||||
else
|
||||
v->pv.q1 = 1.0;
|
||||
}
|
||||
else {
|
||||
v->v.u1 = tc1[0][0];
|
||||
v->v.v1 = tc1[0][1];
|
||||
}
|
||||
STRIDE_4F(tc1, tc1_stride);
|
||||
}
|
||||
else if (DO_PTEX) {
|
||||
*(GLuint *)&v->pv.q1 = 0;
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
if (DO_PTEX) {
|
||||
v->pv.u2 = tc2[0][0];
|
||||
v->pv.v2 = tc2[0][1];
|
||||
if (tc2_size == 4)
|
||||
v->pv.q2 = tc2[0][3];
|
||||
else
|
||||
v->pv.q2 = 1.0;
|
||||
}
|
||||
else {
|
||||
v->v.u2 = tc2[0][0];
|
||||
v->v.v2 = tc2[0][1];
|
||||
}
|
||||
STRIDE_4F(tc2, tc2_stride);
|
||||
}
|
||||
if (DO_TEX3) {
|
||||
if (DO_PTEX) {
|
||||
v->pv.u3 = tc3[0][0];
|
||||
v->pv.v3 = tc3[0][1];
|
||||
if (tc3_size == 4)
|
||||
v->pv.q3 = tc3[0][3];
|
||||
else
|
||||
v->pv.q3 = 1.0;
|
||||
}
|
||||
else {
|
||||
v->v.u3 = tc3[0][0];
|
||||
v->v.v3 = tc3[0][1];
|
||||
}
|
||||
STRIDE_4F(tc3, tc3_stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if DO_XYZW
|
||||
|
||||
#if HAVE_HW_DIVIDE
|
||||
#error "cannot use tiny vertices with hw perspective divide"
|
||||
#endif
|
||||
|
||||
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
|
||||
void *dest, GLuint stride)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLfloat (*col)[4];
|
||||
GLuint col_stride;
|
||||
GLfloat (*coord)[4] = VB->NdcPtr->data;
|
||||
GLuint coord_stride = VB->NdcPtr->stride;
|
||||
GLfloat *v = (GLfloat *)dest;
|
||||
const GLubyte *mask = VB->ClipMask;
|
||||
const GLfloat *s = GET_VIEWPORT_MAT();
|
||||
int i;
|
||||
|
||||
(void) s;
|
||||
|
||||
/*ASSERT(stride == 4);*/
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "TAG-emit for DO_XYZW\n");
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
col = VB->ColorPtr[0]->data;
|
||||
col_stride = VB->ColorPtr[0]->stride;
|
||||
|
||||
if (start) {
|
||||
STRIDE_4F(coord, start * coord_stride);
|
||||
STRIDE_4F(col, start * col_stride);
|
||||
}
|
||||
|
||||
for (i = start; i < end; i++, v += 4) {
|
||||
if (DO_XYZW) {
|
||||
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
|
||||
VIEWPORT_X(v[0], coord[0][0]);
|
||||
VIEWPORT_Y(v[1], coord[0][1]);
|
||||
VIEWPORT_Z(v[2], coord[0][2]);
|
||||
}
|
||||
STRIDE_4F(coord, coord_stride);
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
|
||||
STRIDE_4F( col, col_stride );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
|
||||
void *dest, GLuint stride)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLubyte (*col)[4];
|
||||
GLuint col_stride;
|
||||
GLfloat *v = (GLfloat *)dest;
|
||||
int i;
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "TAG-emit for No DO_XYZW\n");
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
|
||||
IMPORT_FLOAT_COLORS( ctx );
|
||||
|
||||
col = VB->ColorPtr[0]->Ptr;
|
||||
col_stride = VB->ColorPtr[0]->StrideB;
|
||||
|
||||
if (start)
|
||||
STRIDE_4UB(col, col_stride * start);
|
||||
|
||||
/* Need to figure out where color is:
|
||||
*/
|
||||
if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
|
||||
v += 3;
|
||||
else
|
||||
v += 4;
|
||||
|
||||
for (i = start; i < end; i++, STRIDE_F(v, stride)) {
|
||||
if (HAVE_RGBA_COLOR) {
|
||||
*(GLuint *)v = *(GLuint *)col[0];
|
||||
}
|
||||
else {
|
||||
GLubyte *b = (GLubyte *)v;
|
||||
b[0] = col[0][2];
|
||||
b[1] = col[0][1];
|
||||
b[2] = col[0][0];
|
||||
b[3] = col[0][3];
|
||||
}
|
||||
STRIDE_4UB(col, col_stride);
|
||||
}
|
||||
}
|
||||
#endif /* emit */
|
||||
#endif /* emit */
|
||||
|
||||
#if (DO_XYZW) && (DO_RGBA)
|
||||
|
||||
#if (HAVE_PTEX_VERTICES)
|
||||
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
|
||||
/* Force 'missing' texcoords to something valid.
|
||||
*/
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
|
||||
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
|
||||
|
||||
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
|
||||
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
|
||||
|
||||
if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
|
||||
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
|
||||
|
||||
if (DO_PTEX)
|
||||
return GL_TRUE;
|
||||
|
||||
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
|
||||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
|
||||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
|
||||
(DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
|
||||
return GL_FALSE;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
#else
|
||||
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
|
||||
/* Force 'missing' texcoords to something valid.
|
||||
*/
|
||||
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
|
||||
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
|
||||
|
||||
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
|
||||
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
|
||||
|
||||
if (DO_TEX1 && VB->TexCoordPtr[0] == 0) {
|
||||
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
|
||||
}
|
||||
|
||||
if (DO_PTEX)
|
||||
return GL_TRUE;
|
||||
|
||||
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
|
||||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
|
||||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
|
||||
/*PTEX_FALLBACK();*/
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
|
||||
if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
|
||||
/*PTEX_FALLBACK();*/
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
#endif /* ptex */
|
||||
|
||||
|
||||
static void TAG(interp)(GLcontext *ctx,
|
||||
GLfloat t,
|
||||
GLuint edst, GLuint eout, GLuint ein,
|
||||
GLboolean force_boundary)
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLubyte *ddverts = GET_VERTEX_STORE();
|
||||
GLuint shift = GET_VERTEX_STRIDE_SHIFT();
|
||||
const GLfloat *dstclip = VB->ClipPtr->data[edst];
|
||||
GLfloat w;
|
||||
const GLfloat *s = GET_VIEWPORT_MAT();
|
||||
|
||||
VERTEX *dst = (VERTEX *)(ddverts + (edst << shift));
|
||||
VERTEX *in = (VERTEX *)(ddverts + (ein << shift));
|
||||
VERTEX *out = (VERTEX *)(ddverts + (eout << shift));
|
||||
|
||||
(void)s;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
|
||||
VIEWPORT_X(dst->v.x, dstclip[0]);
|
||||
VIEWPORT_Y(dst->v.y, dstclip[1]);
|
||||
VIEWPORT_Z(dst->v.z, dstclip[2]);
|
||||
w = dstclip[3];
|
||||
}
|
||||
else {
|
||||
w = 1.0 / dstclip[3];
|
||||
VIEWPORT_X(dst->v.x, dstclip[0] * w);
|
||||
VIEWPORT_Y(dst->v.y, dstclip[1] * w);
|
||||
VIEWPORT_Z(dst->v.z, dstclip[2] * w);
|
||||
}
|
||||
|
||||
if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) ||
|
||||
DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 ||
|
||||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) {
|
||||
|
||||
dst->v.w = w;
|
||||
|
||||
INTERP_UB(t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0]);
|
||||
INTERP_UB(t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1]);
|
||||
INTERP_UB(t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2]);
|
||||
INTERP_UB(t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3]);
|
||||
|
||||
if (DO_SPEC) {
|
||||
INTERP_UB(t, dst->ub4[5][0], out->ub4[5][0], in->ub4[5][0]);
|
||||
INTERP_UB(t, dst->ub4[5][1], out->ub4[5][1], in->ub4[5][1]);
|
||||
INTERP_UB(t, dst->ub4[5][2], out->ub4[5][2], in->ub4[5][2]);
|
||||
}
|
||||
if (DO_FOG) {
|
||||
INTERP_UB(t, dst->ub4[5][3], out->ub4[5][3], in->ub4[5][3]);
|
||||
}
|
||||
if (DO_TEX0) {
|
||||
if (DO_PTEX) {
|
||||
if (HAVE_PTEX_VERTICES) {
|
||||
INTERP_F(t, dst->pv.u0, out->pv.u0, in->pv.u0);
|
||||
INTERP_F(t, dst->pv.v0, out->pv.v0, in->pv.v0);
|
||||
INTERP_F(t, dst->pv.q0, out->pv.q0, in->pv.q0);
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
|
||||
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
|
||||
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
|
||||
}
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
if (DO_PTEX) {
|
||||
if (HAVE_PTEX_VERTICES) {
|
||||
INTERP_F(t, dst->pv.u1, out->pv.u1, in->pv.u1);
|
||||
INTERP_F(t, dst->pv.v1, out->pv.v1, in->pv.v1);
|
||||
INTERP_F(t, dst->pv.q1, out->pv.q1, in->pv.q1);
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
|
||||
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
|
||||
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
|
||||
}
|
||||
}
|
||||
else if (DO_PTEX) {
|
||||
dst->pv.q0 = 0.0; /* must be a valid float on radeon */
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
if (DO_PTEX) {
|
||||
INTERP_F(t, dst->pv.u2, out->pv.u2, in->pv.u2);
|
||||
INTERP_F(t, dst->pv.v2, out->pv.v2, in->pv.v2);
|
||||
INTERP_F(t, dst->pv.q2, out->pv.q2, in->pv.q2);
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u2, out->v.u2, in->v.u2);
|
||||
INTERP_F(t, dst->v.v2, out->v.v2, in->v.v2);
|
||||
}
|
||||
}
|
||||
if (DO_TEX3) {
|
||||
if (DO_PTEX) {
|
||||
INTERP_F(t, dst->pv.u3, out->pv.u3, in->pv.u3);
|
||||
INTERP_F(t, dst->pv.v3, out->pv.v3, in->pv.v3);
|
||||
INTERP_F(t, dst->pv.q3, out->pv.q3, in->pv.q3);
|
||||
}
|
||||
else {
|
||||
INTERP_F(t, dst->v.u3, out->v.u3, in->v.u3);
|
||||
INTERP_F(t, dst->v.v3, out->v.v3, in->v.v3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate.
|
||||
*/
|
||||
INTERP_UB(t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0]);
|
||||
INTERP_UB(t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1]);
|
||||
INTERP_UB(t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2]);
|
||||
INTERP_UB(t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3]);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
#endif /* rgba && xyzw */
|
||||
|
||||
static void TAG(init)(void)
|
||||
{
|
||||
setup_tab[IND].emit = TAG(emit);
|
||||
|
||||
#if (DO_XYZW && DO_RGBA)
|
||||
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
|
||||
setup_tab[IND].interp = TAG(interp);
|
||||
#endif
|
||||
|
||||
if (DO_SPEC)
|
||||
setup_tab[IND].copyPv = copy_pv_rgba4_spec5;
|
||||
else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 ||
|
||||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES)
|
||||
setup_tab[IND].copyPv = copy_pv_rgba4;
|
||||
else
|
||||
setup_tab[IND].copyPv = copy_pv_rgba3;
|
||||
|
||||
if (DO_TEX3) {
|
||||
if (DO_PTEX && HAVE_PTEX_VERTICES) {
|
||||
ASSERT(HAVE_PTEX_VERTICES);
|
||||
setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 18;
|
||||
setup_tab[IND].vertexStrideShift = 7;
|
||||
}
|
||||
else {
|
||||
setup_tab[IND].vertexFormat = TEX3_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 14;
|
||||
setup_tab[IND].vertexStrideShift = 6;
|
||||
}
|
||||
}
|
||||
else if (DO_TEX2) {
|
||||
if (DO_PTEX && HAVE_PTEX_VERTICES) {
|
||||
ASSERT(HAVE_PTEX_VERTICES);
|
||||
setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 18;
|
||||
setup_tab[IND].vertexStrideShift = 7;
|
||||
}
|
||||
else {
|
||||
setup_tab[IND].vertexFormat = TEX2_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 12;
|
||||
setup_tab[IND].vertexStrideShift = 6;
|
||||
}
|
||||
}
|
||||
else if (DO_TEX1) {
|
||||
if (DO_PTEX && HAVE_PTEX_VERTICES) {
|
||||
ASSERT(HAVE_PTEX_VERTICES);
|
||||
setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 12;
|
||||
setup_tab[IND].vertexStrideShift = 6;
|
||||
}
|
||||
else {
|
||||
setup_tab[IND].vertexFormat = TEX1_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 10;
|
||||
setup_tab[IND].vertexStrideShift = 6;
|
||||
}
|
||||
}
|
||||
else if (DO_TEX0) {
|
||||
if (DO_PTEX && HAVE_PTEX_VERTICES) {
|
||||
setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 12;
|
||||
setup_tab[IND].vertexStrideShift = 6;
|
||||
}
|
||||
else {
|
||||
setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 8;
|
||||
setup_tab[IND].vertexStrideShift = 5;
|
||||
}
|
||||
}
|
||||
else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) {
|
||||
setup_tab[IND].vertexFormat = TINY_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 4;
|
||||
setup_tab[IND].vertexStrideShift = 4;
|
||||
}
|
||||
else if (HAVE_NOTEX_VERTICES) {
|
||||
setup_tab[IND].vertexFormat = NOTEX_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 6;
|
||||
setup_tab[IND].vertexStrideShift = 5;
|
||||
}
|
||||
else {
|
||||
setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
|
||||
setup_tab[IND].vertexSize = 8;
|
||||
setup_tab[IND].vertexStrideShift = 5;
|
||||
}
|
||||
|
||||
assert(setup_tab[IND].vertexSize * 4 <=
|
||||
1 << setup_tab[IND].vertexStrideShift);
|
||||
}
|
||||
|
||||
#undef IND
|
||||
#undef TAG
|
||||
@@ -1,556 +0,0 @@
|
||||
/*
|
||||
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sub license,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VIA, S3 GRAPHICS, 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.
|
||||
*/
|
||||
|
||||
/* Template for render stages which build and emit vertices directly
|
||||
* to fixed-size dma buffers. Useful for rendering strips and other
|
||||
* native primitives where clipping and per-vertex tweaks such as
|
||||
* those in t_dd_tritmp.h are not required.
|
||||
*
|
||||
* Produces code for both inline triangles and indexed triangles.
|
||||
* Where various primitive types are unaccelerated by hardware, the
|
||||
* code attempts to fallback to other primitive types (quadstrips to
|
||||
* tristrips, lineloops to linestrips), or to indexed vertices.
|
||||
* Ultimately, a FALLBACK() macro is invoked if there is no way to
|
||||
* render the primitive natively.
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_TRIANGLES)
|
||||
#error "must have at least triangles to use render template"
|
||||
#endif
|
||||
|
||||
#if !HAVE_ELTS
|
||||
#define ELTS_VARS
|
||||
#define ALLOC_ELTS(nr)
|
||||
#define EMIT_ELT(offset, elt)
|
||||
#define EMIT_TWO_ELTS(offset, elt0, elt1)
|
||||
#define INCR_ELTS(nr)
|
||||
#define ELT_INIT(prim)
|
||||
#define GET_CURRENT_VB_MAX_ELTS() 0
|
||||
#define GET_SUBSEQUENT_VB_MAX_ELTS() 0
|
||||
#define ALLOC_ELTS_NEW_PRIMITIVE(nr)
|
||||
#define RELEASE_ELT_VERTS()
|
||||
#define EMIT_INDEXED_VERTS(ctx, start, count)
|
||||
#endif
|
||||
|
||||
#ifndef EMIT_TWO_ELTS
|
||||
#define EMIT_TWO_ELTS(offset, elt0, elt1) \
|
||||
do { \
|
||||
EMIT_ELT(offset, elt0); \
|
||||
EMIT_ELT(offset + 1, elt1); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef FINISH
|
||||
#define FINISH
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Render non-indexed primitives.
|
||||
***********************************************************************/
|
||||
|
||||
static void TAG(render_points_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_POINTS) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
GLuint j, nr;
|
||||
|
||||
INIT(GL_POINTS);
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j < count; j += nr) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void TAG(render_lines_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_LINES) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
GLuint j, nr;
|
||||
|
||||
INIT(GL_LINES);
|
||||
|
||||
/* Emit whole number of lines in total and in each buffer:
|
||||
*/
|
||||
count -= (count - start) & 1;
|
||||
currentsz -= currentsz & 1;
|
||||
dmasz -= dmasz & 1;
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j < count; j += nr) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_line_strip_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_LINE_STRIPS) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
GLuint j, nr;
|
||||
|
||||
INIT(GL_LINE_STRIP);
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j + 1 < count; j += nr - 1) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_line_loop_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_LINE_STRIPS) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
GLuint j, nr;
|
||||
|
||||
INIT(GL_LINE_STRIP);
|
||||
|
||||
if (flags & PRIM_BEGIN)
|
||||
j = start;
|
||||
else
|
||||
j = start + 1;
|
||||
|
||||
/* Ensure last vertex won't wrap buffers:
|
||||
*/
|
||||
currentsz--;
|
||||
dmasz--;
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (; j + 1 < count; j += nr - 1) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
if (start < count - 1 && (flags & PRIM_END))
|
||||
EMIT_VERTS(ctx, start, 1);
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_triangles_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
LOCAL_VARS;
|
||||
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 3) * 3;
|
||||
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 3) * 3;
|
||||
GLuint j, nr;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
INIT(GL_TRIANGLES);
|
||||
|
||||
/* Emit whole number of tris in total. dmasz is already a multiple
|
||||
* of 3.
|
||||
*/
|
||||
count -= (count - start) % 3;
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j < count; j += nr) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
FINISH;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_tri_strip_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_TRI_STRIPS) {
|
||||
LOCAL_VARS;
|
||||
GLuint j, nr;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
INIT(GL_TRIANGLE_STRIP);
|
||||
|
||||
if (currentsz < 8) {
|
||||
NEW_BUFFER();
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
/* From here on emit even numbers of tris when wrapping over buffers:
|
||||
*/
|
||||
dmasz -= (dmasz & 1);
|
||||
currentsz -= (currentsz & 1);
|
||||
|
||||
for (j = start; j + 2 < count; j += nr - 2) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void TAG(render_tri_fan_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (HAVE_TRI_FANS) {
|
||||
LOCAL_VARS;
|
||||
GLuint j, nr;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
INIT(GL_TRIANGLE_FAN);
|
||||
|
||||
if (currentsz < 8) {
|
||||
NEW_BUFFER();
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
for (j = start + 1; j + 1 < count; j += nr - 1) {
|
||||
nr = MIN2(currentsz, count - j + 1);
|
||||
EMIT_VERTS(ctx, start, 1);
|
||||
EMIT_VERTS(ctx, j, nr - 1);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
/* Could write code to emit these as indexed vertices (for the
|
||||
* g400, for instance).
|
||||
*/
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_poly_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_POLYGONS) {
|
||||
LOCAL_VARS;
|
||||
GLuint j, nr;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
INIT(GL_POLYGON);
|
||||
|
||||
if (currentsz < 8) {
|
||||
NEW_BUFFER();
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
for (j = start + 1; j + 1 < count; j += nr - 1) {
|
||||
nr = MIN2(currentsz, count - j + 1);
|
||||
EMIT_VERTS(ctx, start, 1);
|
||||
EMIT_VERTS(ctx, j, nr - 1);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) {
|
||||
TAG(render_tri_fan_verts)(ctx, start, count, flags);
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void TAG(render_quad_strip_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
GLuint j, nr;
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (HAVE_QUAD_STRIPS) {
|
||||
LOCAL_VARS;
|
||||
GLuint j, nr;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz;
|
||||
|
||||
INIT(GL_QUAD_STRIP);
|
||||
|
||||
currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
if (currentsz < 8) {
|
||||
NEW_BUFFER();
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
dmasz -= (dmasz & 2);
|
||||
currentsz -= (currentsz & 2);
|
||||
|
||||
for (j = start; j + 3 < count; j += nr - 2) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else if (HAVE_TRI_STRIPS) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
/* Emit smooth-shaded quadstrips as tristrips:
|
||||
*/
|
||||
INIT(GL_TRIANGLE_STRIP);
|
||||
|
||||
/* Emit whole number of quads in total, and in each buffer.
|
||||
*/
|
||||
dmasz -= dmasz & 1;
|
||||
currentsz -= currentsz & 1;
|
||||
count -= (count - start) & 1;
|
||||
|
||||
if (currentsz < 8) {
|
||||
NEW_BUFFER();
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
for (j = start; j + 3 < count; j += nr - 2) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void TAG(render_quads_verts)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M_X;
|
||||
#endif
|
||||
if (HAVE_QUADS) {
|
||||
LOCAL_VARS;
|
||||
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 4) * 4;
|
||||
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 4) * 4;
|
||||
GLuint j, nr;
|
||||
|
||||
INIT(GL_QUADS);
|
||||
|
||||
/* Emit whole number of quads in total. dmasz is already a multiple
|
||||
* of 4.
|
||||
*/
|
||||
count -= (count - start) % 4;
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j < count; j += nr) {
|
||||
nr = MIN2(currentsz, count - j);
|
||||
EMIT_VERTS(ctx, j, nr);
|
||||
currentsz = dmasz;
|
||||
}
|
||||
FINISH;
|
||||
}
|
||||
else if (HAVE_TRIANGLES) {
|
||||
/* Hardware doesn't have a quad primitive type -- try to
|
||||
* simulate it using triangle primitive.
|
||||
*/
|
||||
LOCAL_VARS;
|
||||
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
|
||||
int currentsz;
|
||||
GLuint j;
|
||||
|
||||
INIT(GL_TRIANGLES);
|
||||
|
||||
currentsz = GET_CURRENT_VB_MAX_VERTS();
|
||||
|
||||
/* Emit whole number of quads in total, and in each buffer.
|
||||
*/
|
||||
dmasz -= dmasz & 3;
|
||||
count -= (count - start) & 3;
|
||||
currentsz -= currentsz & 3;
|
||||
|
||||
/* Adjust for rendering as triangles:
|
||||
*/
|
||||
currentsz = currentsz / 6 * 4;
|
||||
dmasz = dmasz / 6 * 4;
|
||||
|
||||
if (currentsz < 8)
|
||||
currentsz = dmasz;
|
||||
|
||||
for (j = start; j < count; j += 4) {
|
||||
/* Send v0, v1, v3
|
||||
*/
|
||||
EMIT_VERTS(ctx, j, 2);
|
||||
EMIT_VERTS(ctx, j + 3, 1);
|
||||
/* Send v1, v2, v3
|
||||
*/
|
||||
EMIT_VERTS(ctx, j + 1, 3);
|
||||
}
|
||||
FINISH;
|
||||
}
|
||||
else {
|
||||
/* Vertices won't fit in a single buffer, fallback.
|
||||
*/
|
||||
VERT_FALLBACK(ctx, start, count, flags);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void TAG(render_noop)(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static tnl_render_func TAG(render_tab_verts)[GL_POLYGON + 2] =
|
||||
{
|
||||
TAG(render_points_verts),
|
||||
TAG(render_lines_verts),
|
||||
TAG(render_line_loop_verts),
|
||||
TAG(render_line_strip_verts),
|
||||
TAG(render_triangles_verts),
|
||||
TAG(render_tri_strip_verts),
|
||||
TAG(render_tri_fan_verts),
|
||||
TAG(render_quads_verts),
|
||||
TAG(render_quad_strip_verts),
|
||||
TAG(render_poly_verts),
|
||||
TAG(render_noop),
|
||||
};
|
||||
|
||||
@@ -29,9 +29,6 @@ typedef struct {
|
||||
int priv2;
|
||||
int fbOffset;
|
||||
int fbSize;
|
||||
#ifdef USE_XINERAMA
|
||||
Bool drixinerama;
|
||||
#endif
|
||||
int backOffset;
|
||||
int depthOffset;
|
||||
int textureOffset;
|
||||
|
||||
@@ -31,150 +31,60 @@
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
GLboolean
|
||||
via_alloc_back_buffer(viaContextPtr vmesa)
|
||||
via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
unsigned char *pFB;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.size = vmesa->back.size;
|
||||
fb.type = VIDEO;
|
||||
if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
|
||||
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
|
||||
return GL_FALSE;
|
||||
|
||||
pFB = vmesa->driScreen->pFB;
|
||||
|
||||
vmesa->back.offset = fb.offset;
|
||||
vmesa->back.map = (char *)(fb.offset + (GLuint)pFB);
|
||||
vmesa->back.index = fb.index;
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "back offset = %08x\n", vmesa->back.offset);
|
||||
fprintf(stderr, "back index = %d\n", vmesa->back.index);
|
||||
}
|
||||
drm_via_mem_t mem;
|
||||
mem.context = vmesa->hHWContext;
|
||||
mem.size = buf->size;
|
||||
mem.type = VIDEO;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
via_alloc_front_buffer(viaContextPtr vmesa)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
unsigned char *pFB;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.size = vmesa->back.size;
|
||||
fb.type = VIDEO;
|
||||
if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
|
||||
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
|
||||
return GL_FALSE;
|
||||
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem))
|
||||
return GL_FALSE;
|
||||
|
||||
pFB = vmesa->driScreen->pFB;
|
||||
|
||||
vmesa->front.offset = fb.offset;
|
||||
vmesa->front.map = (char *)(fb.offset + (GLuint)pFB);
|
||||
vmesa->front.index = fb.index;
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "front offset = %08x\n", vmesa->front.offset);
|
||||
fprintf(stderr, "front index = %d\n", vmesa->front.index);
|
||||
}
|
||||
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
buf->offset = mem.offset;
|
||||
buf->map = (char *)vmesa->driScreen->pFB + mem.offset;
|
||||
buf->index = mem.index;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
via_free_back_buffer(viaContextPtr vmesa)
|
||||
via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
drm_via_mem_t mem;
|
||||
|
||||
if (!vmesa) return;
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.index = vmesa->back.index;
|
||||
fb.type = VIDEO;
|
||||
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
|
||||
vmesa->back.map = NULL;
|
||||
if (!vmesa) return;
|
||||
|
||||
mem.context = vmesa->hHWContext;
|
||||
mem.index = buf->index;
|
||||
mem.type = VIDEO;
|
||||
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem);
|
||||
buf->map = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
via_free_front_buffer(viaContextPtr vmesa)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
|
||||
if (!vmesa) return;
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.index = vmesa->front.index;
|
||||
fb.type = VIDEO;
|
||||
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
|
||||
vmesa->front.map = NULL;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
via_alloc_depth_buffer(viaContextPtr vmesa)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
unsigned char *pFB;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.size = vmesa->depth.size;
|
||||
fb.type = VIDEO;
|
||||
|
||||
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
pFB = vmesa->driScreen->pFB;
|
||||
|
||||
vmesa->depth.offset = fb.offset;
|
||||
vmesa->depth.map = (char *)(fb.offset + (GLuint)pFB);
|
||||
vmesa->depth.index = fb.index;
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "depth offset = %08x\n", vmesa->depth.offset);
|
||||
fprintf(stderr, "depth index = %d\n", vmesa->depth.index);
|
||||
}
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
via_free_depth_buffer(viaContextPtr vmesa)
|
||||
{
|
||||
drm_via_mem_t fb;
|
||||
|
||||
if (!vmesa) return;
|
||||
fb.context = vmesa->hHWContext;
|
||||
fb.index = vmesa->depth.index;
|
||||
fb.type = VIDEO;
|
||||
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
|
||||
vmesa->depth.map = NULL;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
via_alloc_dma_buffer(viaContextPtr vmesa)
|
||||
{
|
||||
drmVIADMAInit init;
|
||||
drmVIADMAInit init;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
vmesa->dma = (GLuint *) malloc(VIA_DMA_BUFSIZ);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ);
|
||||
|
||||
/*
|
||||
* Check whether AGP DMA has been initialized.
|
||||
*/
|
||||
|
||||
init.func = VIA_DMA_INITIALIZED;
|
||||
vmesa->useAgp =
|
||||
/*
|
||||
* Check whether AGP DMA has been initialized.
|
||||
*/
|
||||
init.func = VIA_DMA_INITIALIZED;
|
||||
vmesa->useAgp =
|
||||
( 0 == drmCommandWrite(vmesa->driFd, DRM_VIA_DMA_INIT,
|
||||
&init, sizeof(init)));
|
||||
if (vmesa->useAgp)
|
||||
printf("unichrome_dri.so: Using AGP.\n");
|
||||
else
|
||||
printf("unichrome_dri.so: Using PCI.\n");
|
||||
if (vmesa->useAgp)
|
||||
printf("unichrome_dri.so: Using AGP.\n");
|
||||
else
|
||||
printf("unichrome_dri.so: Using PCI.\n");
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -25,18 +25,14 @@
|
||||
#ifndef _VIAFB_INC
|
||||
#define _VIAFB_INC
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "swrast/swrast.h"
|
||||
extern GLboolean via_alloc_front_buffer(viaContextPtr vmesa);
|
||||
extern GLboolean via_alloc_back_buffer(viaContextPtr vmesa);
|
||||
extern void via_free_back_buffer(viaContextPtr vmesa);
|
||||
extern void via_free_front_buffer(viaContextPtr vmesa);
|
||||
extern GLboolean via_alloc_depth_buffer(viaContextPtr vmesa);
|
||||
extern void via_free_depth_buffer(viaContextPtr vmesa);
|
||||
#include "via_context.h"
|
||||
|
||||
extern GLboolean via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf);
|
||||
extern GLboolean via_alloc_dma_buffer(viaContextPtr vmesa);
|
||||
extern void via_free_dma_buffer(viaContextPtr vmesa);
|
||||
extern GLboolean via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
|
||||
/*=* John Sheng [2003.5.31] agp tex *=*/
|
||||
extern GLboolean via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t);
|
||||
|
||||
extern void via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf);
|
||||
extern void via_free_dma_buffer(viaContextPtr vmesa);
|
||||
extern void via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,58 +28,72 @@
|
||||
#include "via_context.h"
|
||||
|
||||
|
||||
void viaEmitPrim(viaContextPtr vmesa);
|
||||
void viaFlushPrims(viaContextPtr vmesa);
|
||||
void viaFlushPrimsLocked(viaContextPtr vmesa);
|
||||
void viaFinishPrimitive(viaContextPtr vmesa);
|
||||
void viaFlushDma(viaContextPtr vmesa);
|
||||
void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags);
|
||||
|
||||
void viaDmaFinish(viaContextPtr vmesa);
|
||||
void viaRegetLockQuiescent(viaContextPtr vmesa);
|
||||
void viaInitIoctlFuncs(GLcontext *ctx);
|
||||
void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
|
||||
void viaPageFlip(const __DRIdrawablePrivate *dpriv);
|
||||
int via_check_copy(int fd);
|
||||
void viaFillFrontBuffer(viaContextPtr vmesa);
|
||||
void viaFillFrontBufferSaam(viaContextPtr vmesa);
|
||||
void viaFillFrontPBuffer(viaContextPtr vmesa);
|
||||
void viaFillBackBuffer(viaContextPtr vmesa);
|
||||
void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel);
|
||||
void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel);
|
||||
void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel);
|
||||
void viaDoSwapBuffers(viaContextPtr vmesa);
|
||||
void viaDoSwapBuffersSaam(viaContextPtr vmesa);
|
||||
void viaDoSwapPBuffers(viaContextPtr vmesa);
|
||||
void viaCheckDma(viaContextPtr vmesa, GLuint bytes);
|
||||
|
||||
int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd);
|
||||
int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd);
|
||||
int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf);
|
||||
#define VIA_FINISH_PRIM(vmesa) do { \
|
||||
if (vmesa->dmaLastPrim) \
|
||||
viaFinishPrimitive( vmesa ); \
|
||||
} while (0)
|
||||
|
||||
#define VIA_STATECHANGE(vmesa, flag) \
|
||||
do { \
|
||||
if (vmesa->dmaLow != vmesa->dmaLastPrim) \
|
||||
viaFlushPrims(vmesa); \
|
||||
vmesa->dirty |= flag; \
|
||||
} while (0) \
|
||||
|
||||
|
||||
#define VIA_FIREVERTICES(vmesa) \
|
||||
do { \
|
||||
if (vmesa->dmaLow) { \
|
||||
viaFlushPrims(vmesa); \
|
||||
} \
|
||||
} while (0)
|
||||
#define VIA_FLUSH_DMA(vmesa) do { \
|
||||
VIA_FINISH_PRIM(vmesa); \
|
||||
if (vmesa->dmaLow) \
|
||||
viaFlushDma(vmesa); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static __inline GLuint *viaCheckDma(viaContextPtr vmesa, int bytes)
|
||||
{
|
||||
if (vmesa->dmaLow + bytes > vmesa->dmaHigh) {
|
||||
if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n",
|
||||
vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
|
||||
viaFlushPrims(vmesa);
|
||||
}
|
||||
GLuint *viaExtendPrimitive(viaContextPtr vmesa, int bytes);
|
||||
GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int line);
|
||||
#define viaAllocDma( v, b ) viaAllocDmaFunc(v, b, __FUNCTION__, __LINE__)
|
||||
|
||||
|
||||
#define RING_VARS GLuint *_vb = 0, _nr, _x;
|
||||
|
||||
#define BEGIN_RING(n) do { \
|
||||
if (_vb != 0) abort(); \
|
||||
_vb = viaAllocDma(vmesa, (n) * sizeof(GLuint)); \
|
||||
_nr = (n); \
|
||||
_x = 0; \
|
||||
} while (0)
|
||||
|
||||
#define BEGIN_RING_NOCHECK(n) do { \
|
||||
if (_vb != 0) abort(); \
|
||||
_vb = (GLuint *)(vmesa->dma + vmesa->dmaLow); \
|
||||
vmesa->dmaLow += (n) * sizeof(GLuint); \
|
||||
_nr = (n); \
|
||||
_x = 0; \
|
||||
} while (0)
|
||||
|
||||
#define OUT_RING(n) _vb[_x++] = (n)
|
||||
|
||||
#define ADVANCE_RING() do { \
|
||||
if (_x != _nr) abort(); \
|
||||
_vb = 0; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_RING_VARIABLE() do { \
|
||||
if (_x > _nr) abort(); \
|
||||
vmesa->dmaLow -= (_nr - _x) * sizeof(GLuint); \
|
||||
_vb = 0; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define QWORD_PAD_RING() do { \
|
||||
if (vmesa->dmaLow & 0x4) { \
|
||||
BEGIN_RING(1); \
|
||||
OUT_RING(HC_DUMMY); \
|
||||
ADVANCE_RING(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
|
||||
return start;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "via_context.h"
|
||||
#include "via_tris.h"
|
||||
#include "via_state.h"
|
||||
#include "via_vb.h"
|
||||
#include "via_ioctl.h"
|
||||
|
||||
/*
|
||||
@@ -52,7 +51,7 @@
|
||||
#define HAVE_LINE_LOOP 1
|
||||
#define HAVE_TRIANGLES 1
|
||||
#define HAVE_TRI_STRIPS 1
|
||||
#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */
|
||||
#define HAVE_TRI_STRIP_1 0
|
||||
#define HAVE_TRI_FANS 1
|
||||
#define HAVE_POLYGONS 1
|
||||
#define HAVE_QUADS 0
|
||||
@@ -60,70 +59,25 @@
|
||||
|
||||
#define HAVE_ELTS 0
|
||||
|
||||
static const GLenum reducedPrim[GL_POLYGON + 1] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINES,
|
||||
GL_LINES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES
|
||||
};
|
||||
|
||||
/* Fallback to normal rendering.
|
||||
*/
|
||||
static void VERT_FALLBACK(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
fprintf(stderr, "VERT_FALLBACK\n");
|
||||
tnl->Driver.Render.PrimitiveNotify(ctx, flags & PRIM_MODE_MASK);
|
||||
tnl->Driver.Render.BuildVertices(ctx, start, count, ~0);
|
||||
tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK](ctx, start,
|
||||
count, flags);
|
||||
VIA_CONTEXT(ctx)->setupNewInputs = VERT_BIT_CLIP;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
#define LOCAL_VARS viaContextPtr vmesa = VIA_CONTEXT(ctx)
|
||||
/*
|
||||
#define INIT(prim) \
|
||||
do { \
|
||||
VIA_STATECHANGE(vmesa, 0); \
|
||||
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
|
||||
} while (0)
|
||||
*/
|
||||
#define INIT(prim) \
|
||||
do { \
|
||||
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
|
||||
} while (0)
|
||||
#define NEW_PRIMITIVE() VIA_STATECHANGE(vmesa, 0)
|
||||
#define NEW_BUFFER() VIA_FIREVERTICES(vmesa)
|
||||
#define INIT(prim) do { \
|
||||
viaRasterPrimitive(ctx, prim, prim); \
|
||||
} while (0)
|
||||
#define GET_CURRENT_VB_MAX_VERTS() \
|
||||
(((int)vmesa->dmaHigh - (int)vmesa->dmaLow) / (vmesa->vertexSize * 4))
|
||||
((VIA_DMA_BUF_SZ - (512 + (int)vmesa->dmaLow)) / (vmesa->vertexSize * 4))
|
||||
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
|
||||
(VIA_DMA_BUF_SZ - 4) / (vmesa->vertexSize * 4)
|
||||
(VIA_DMA_BUF_SZ - 512) / (vmesa->vertexSize * 4)
|
||||
|
||||
#define ALLOC_VERTS( nr ) \
|
||||
viaExtendPrimitive( vmesa, (nr) * vmesa->vertexSize * 4)
|
||||
|
||||
#define EMIT_VERTS(ctx, j, nr) \
|
||||
via_emit_contiguous_verts(ctx, j, (j) + (nr))
|
||||
#define EMIT_VERTS(ctx, j, nr, buf) \
|
||||
_tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
|
||||
|
||||
#define FINISH \
|
||||
do { \
|
||||
vmesa->primitiveRendered = GL_TRUE; \
|
||||
viaRasterPrimitiveFinish(ctx); \
|
||||
} while (0)
|
||||
|
||||
#define FLUSH() VIA_FINISH_PRIM( vmesa )
|
||||
|
||||
#define TAG(x) via_fast##x
|
||||
#include "via_dmatmp.h"
|
||||
#include "tnl_dd/t_dd_dmatmp.h"
|
||||
#undef TAG
|
||||
#undef LOCAL_VARS
|
||||
#undef INIT
|
||||
@@ -139,27 +93,18 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i;
|
||||
|
||||
/* Don't handle clipping or indexed vertices.
|
||||
*/
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
|
||||
if (VB->ClipOrMask || vmesa->renderIndex != 0 || VB->Elts) {
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "slow path\n");
|
||||
fprintf(stderr, "ClipOrMask = %08x\n", VB->ClipOrMask);
|
||||
fprintf(stderr, "renderIndex = %08x\n", vmesa->renderIndex);
|
||||
fprintf(stderr, "Elts = %08x\n", (GLuint)VB->Elts);
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
vmesa->setupNewInputs = VERT_BIT_CLIP;
|
||||
vmesa->primitiveRendered = GL_TRUE;
|
||||
|
||||
tnl->Driver.Render.Start(ctx);
|
||||
|
||||
if (VB->ClipOrMask ||
|
||||
vmesa->renderIndex != 0 ||
|
||||
!via_fastvalidate_render( ctx, VB )) {
|
||||
tnl->Driver.Render.Finish(ctx);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
tnl->clipspace.new_inputs |= VERT_BIT_POS;
|
||||
|
||||
for (i = 0; i < VB->PrimitiveCount; ++i) {
|
||||
GLuint mode = VB->Primitive[i].mode;
|
||||
GLuint start = VB->Primitive[i].start;
|
||||
@@ -169,34 +114,14 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
|
||||
}
|
||||
|
||||
tnl->Driver.Render.Finish(ctx);
|
||||
|
||||
/*=* DBG - viewperf7.0 : fix command buffer overflow *=*/
|
||||
if (vmesa->dmaLow > (VIA_DMA_BUFSIZ / 2))
|
||||
viaFlushPrims(vmesa);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
|
||||
return GL_FALSE; /* finished the pipe */
|
||||
}
|
||||
|
||||
|
||||
static void via_check_fastrender(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
GLuint inputs = VERT_BIT_CLIP | VERT_BIT_COLOR0;
|
||||
|
||||
if (ctx->RenderMode == GL_RENDER) {
|
||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
|
||||
inputs |= VERT_BIT_COLOR1;
|
||||
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled)
|
||||
inputs |= VERT_BIT_TEX0;
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled)
|
||||
inputs |= VERT_BIT_TEX1;
|
||||
|
||||
if (ctx->Fog.Enabled)
|
||||
inputs |= VERT_BIT_FOG;
|
||||
}
|
||||
|
||||
stage->inputs = inputs;
|
||||
stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,310 +148,3 @@ const struct tnl_pipeline_stage _via_fastrender_stage =
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Render whole vertex buffers, including projection of vertices from
|
||||
* clip space and clipping of primitives.
|
||||
*
|
||||
* This file makes calls to project vertices and to the point, line
|
||||
* and triangle rasterizers via the function pointers:
|
||||
*
|
||||
* context->Driver.Render.*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Clip single primitives */
|
||||
/**********************************************************************/
|
||||
#undef DIFFERENT_SIGNS
|
||||
#if defined(USE_IEEE)
|
||||
#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1 << 31))
|
||||
#define DIFFERENT_SIGNS(x, y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1 << 31))
|
||||
#else
|
||||
#define NEGATIVE(x) (x < 0)
|
||||
#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
|
||||
/* Could just use (x*y<0) except for the flatshading requirements.
|
||||
* Maybe there's a better way?
|
||||
*/
|
||||
#endif
|
||||
|
||||
#define W(i) coord[i][3]
|
||||
#define Z(i) coord[i][2]
|
||||
#define Y(i) coord[i][1]
|
||||
#define X(i) coord[i][0]
|
||||
#define SIZE 4
|
||||
#define TAG(x) x##_4
|
||||
#include "via_vb_cliptmp.h"
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Clip and render whole begin/end objects */
|
||||
/**********************************************************************/
|
||||
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
|
||||
#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
|
||||
#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
|
||||
|
||||
|
||||
/* Vertices, with the possibility of clipping.
|
||||
*/
|
||||
#define RENDER_POINTS(start, count) \
|
||||
tnl->Driver.Render.Points(ctx, start, count)
|
||||
|
||||
#define RENDER_LINE(v1, v2) \
|
||||
do { \
|
||||
GLubyte c1 = mask[v1], c2 = mask[v2]; \
|
||||
GLubyte ormask = c1 | c2; \
|
||||
if (!ormask) \
|
||||
LineFunc(ctx, v1, v2); \
|
||||
else if (!(c1 & c2 & 0x3f)) \
|
||||
clip_line_4(ctx, v1, v2, ormask); \
|
||||
} while (0)
|
||||
|
||||
#define RENDER_TRI(v1, v2, v3) \
|
||||
if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - clip\n"); \
|
||||
do { \
|
||||
GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \
|
||||
GLubyte ormask = c1 | c2 | c3; \
|
||||
if (!ormask) \
|
||||
TriangleFunc(ctx, v1, v2, v3); \
|
||||
else if (!(c1 & c2 & c3 & 0x3f)) \
|
||||
clip_tri_4(ctx, v1, v2, v3, ormask); \
|
||||
} while (0)
|
||||
|
||||
#define RENDER_QUAD(v1, v2, v3, v4) \
|
||||
do { \
|
||||
GLubyte c1 = mask[v1], c2 = mask[v2]; \
|
||||
GLubyte c3 = mask[v3], c4 = mask[v4]; \
|
||||
GLubyte ormask = c1 | c2 | c3 | c4; \
|
||||
if (!ormask) \
|
||||
QuadFunc(ctx, v1, v2, v3, v4); \
|
||||
else if (!(c1 & c2 & c3 & c4 & 0x3f)) \
|
||||
clip_quad_4(ctx, v1, v2, v3, v4, ormask); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define LOCAL_VARS \
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx); \
|
||||
struct vertex_buffer *VB = &tnl->vb; \
|
||||
const GLuint * const elt = VB->Elts; \
|
||||
const GLubyte *mask = VB->ClipMask; \
|
||||
const GLuint sz = VB->ClipPtr->size; \
|
||||
const tnl_line_func LineFunc = tnl->Driver.Render.Line; \
|
||||
const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \
|
||||
const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \
|
||||
const GLboolean stipple = ctx->Line.StippleFlag; \
|
||||
(void) (LineFunc && TriangleFunc && QuadFunc); \
|
||||
(void) elt; (void) mask; (void) sz; (void) stipple;
|
||||
|
||||
#define POSTFIX \
|
||||
viaRasterPrimitiveFinish(ctx)
|
||||
|
||||
#define TAG(x) clip_##x##_verts
|
||||
#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)
|
||||
#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx)
|
||||
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
|
||||
#define PRESERVE_VB_DEFS
|
||||
#include "via_vb_rendertmp.h"
|
||||
|
||||
|
||||
/* Elts, with the possibility of clipping.
|
||||
*/
|
||||
#undef ELT
|
||||
#undef TAG
|
||||
#define ELT(x) elt[x]
|
||||
#define TAG(x) clip_##x##_elts
|
||||
#include "via_vb_rendertmp.h"
|
||||
|
||||
/* TODO: do this for all primitives, verts and elts:
|
||||
*/
|
||||
static void clip_elt_triangles(GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count,
|
||||
GLuint flags)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
const GLuint * const elt = VB->Elts;
|
||||
GLubyte *mask = VB->ClipMask;
|
||||
GLuint last = count-2;
|
||||
GLuint j;
|
||||
(void)flags;
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
tnl->Driver.Render.PrimitiveNotify(ctx, GL_TRIANGLES);
|
||||
|
||||
for (j = start; j < last; j += 3) {
|
||||
GLubyte c1 = mask[elt[j]];
|
||||
GLubyte c2 = mask[elt[j + 1]];
|
||||
GLubyte c3 = mask[elt[j + 2]];
|
||||
GLubyte ormask = c1 | c2 | c3;
|
||||
if (ormask) {
|
||||
if (start < j)
|
||||
render_tris(ctx, start, j, 0);
|
||||
if (!(c1 & c2 & c3 & 0x3f))
|
||||
clip_tri_4(ctx, elt[j], elt[j + 1], elt[j + 2], ormask);
|
||||
start = j+3;
|
||||
}
|
||||
}
|
||||
|
||||
if (start < j)
|
||||
render_tris(ctx, start, j, 0);
|
||||
|
||||
viaRasterPrimitiveFinish(ctx);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Helper functions for drivers */
|
||||
/**********************************************************************/
|
||||
/*
|
||||
void _tnl_RenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint *tmp = VB->Elts;
|
||||
|
||||
VB->Elts = (GLuint *)elts;
|
||||
tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END);
|
||||
VB->Elts = tmp;
|
||||
}
|
||||
|
||||
void _tnl_RenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
tnl->Driver.Render.Line(ctx, ii, jj);
|
||||
}
|
||||
*/
|
||||
|
||||
/**********************************************************************/
|
||||
/* Render pipeline stage */
|
||||
/**********************************************************************/
|
||||
static GLboolean via_run_render(GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
/* DBG */
|
||||
GLuint newInputs = stage->changed_inputs;
|
||||
/*GLuint newInputs = stage->inputs;*/
|
||||
|
||||
tnl_render_func *tab;
|
||||
GLuint pass = 0;
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
#ifdef PERFORMANCE_MEASURE
|
||||
if (VIA_PERFORMANCE) P_M;
|
||||
#endif
|
||||
tnl->Driver.Render.Start(ctx);
|
||||
tnl->Driver.Render.BuildVertices(ctx, 0, VB->Count, newInputs);
|
||||
if (VB->ClipOrMask) {
|
||||
tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
|
||||
clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
|
||||
}
|
||||
else {
|
||||
tab = VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts;
|
||||
}
|
||||
|
||||
do {
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < VB->PrimitiveCount; i++) {
|
||||
GLuint flags = VB->Primitive[i].mode;
|
||||
GLuint start = VB->Primitive[i].start;
|
||||
GLuint length= VB->Primitive[i].count;
|
||||
ASSERT(length || (flags & PRIM_END));
|
||||
ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON + 1);
|
||||
if (length)
|
||||
tab[flags & PRIM_MODE_MASK](ctx, start, start + length,flags);
|
||||
}
|
||||
}
|
||||
while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass(ctx, ++pass));
|
||||
tnl->Driver.Render.Finish(ctx);
|
||||
|
||||
/*=* DBG - flush : if hw idel *=*/
|
||||
/*{
|
||||
GLuint volatile *pnEnginStatus = vmesa->regEngineStatus;
|
||||
GLuint nStatus;
|
||||
nStatus = *pnEnginStatus;
|
||||
if ((nStatus & 0xFFFEFFFF) == 0x00020000)
|
||||
viaFlushPrims(vmesa);
|
||||
}*/
|
||||
|
||||
/*=* DBG viewperf7.0 : fix command buffer overflow *=*/
|
||||
if (vmesa->dmaLow > (VIA_DMA_BUFSIZ / 2))
|
||||
viaFlushPrims(vmesa);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
|
||||
return GL_FALSE; /* finished the pipe */
|
||||
}
|
||||
|
||||
/* Quite a bit of work involved in finding out the inputs for the
|
||||
* render stage.
|
||||
*/
|
||||
|
||||
static void via_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
GLuint inputs = VERT_BIT_CLIP;
|
||||
|
||||
if (ctx->Visual.rgbMode) {
|
||||
inputs |= VERT_BIT_COLOR0;
|
||||
|
||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
|
||||
inputs |= VERT_BIT_COLOR1;
|
||||
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
inputs |= VERT_BIT_TEX0;
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
inputs |= VERT_BIT_TEX1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*inputs |= VERT_BIT_INDEX;*/
|
||||
}
|
||||
|
||||
/*if (ctx->Point._Attenuated)
|
||||
inputs |= VERT_POINT_SIZE;*/
|
||||
|
||||
if (ctx->Fog.Enabled)
|
||||
inputs |= VERT_BIT_FOG;
|
||||
|
||||
/*if (ctx->_TriangleCaps & DD_TRI_UNFILLED)
|
||||
inputs |= VERT_EDGE;
|
||||
|
||||
if (ctx->RenderMode == GL_FEEDBACK)
|
||||
inputs |= VERT_TEX_ANY;*/
|
||||
|
||||
stage->inputs = inputs;
|
||||
}
|
||||
|
||||
|
||||
static void dtr(struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
(void)stage;
|
||||
}
|
||||
|
||||
|
||||
const struct tnl_pipeline_stage _via_render_stage =
|
||||
{
|
||||
"via render",
|
||||
(_NEW_BUFFERS |
|
||||
_DD_NEW_SEPARATE_SPECULAR |
|
||||
_DD_NEW_FLATSHADE |
|
||||
_NEW_TEXTURE |
|
||||
_NEW_LIGHT |
|
||||
_NEW_POINT |
|
||||
_NEW_FOG |
|
||||
_DD_NEW_TRI_UNFILLED |
|
||||
_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 */
|
||||
via_check_render, /* check - initially set to alloc data */
|
||||
via_run_render /* run */
|
||||
};
|
||||
|
||||
@@ -117,9 +117,6 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
|
||||
viaScreen->irqEnabled = gDRIPriv->irqEnabled;
|
||||
viaScreen->irqEnabled = 1;
|
||||
|
||||
#ifdef USE_XINERAMA
|
||||
viaScreen->drixinerama = gDRIPriv->drixinerama;
|
||||
#endif
|
||||
if (VIA_DEBUG) {
|
||||
fprintf(stderr, "deviceID = %08x\n", viaScreen->deviceID);
|
||||
fprintf(stderr, "width = %08x\n", viaScreen->width);
|
||||
@@ -219,36 +216,24 @@ viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
|
||||
const __GLcontextModes *mesaVis,
|
||||
GLboolean isPixmap)
|
||||
{
|
||||
/* KW: Bogus: Do this sort of thing in MakeCurrent or similar.
|
||||
*/
|
||||
viaContextPtr vmesa;
|
||||
viaContextPtr vmesa = 0;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
|
||||
mesaVis->depthBits != 24);
|
||||
|
||||
if (ctx)
|
||||
vmesa = VIA_CONTEXT(ctx);
|
||||
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
|
||||
/*=* John Sheng [2003.7.2] for visual config & patch viewperf *=*/
|
||||
if (vmesa && mesaVis->depthBits == 32 && vmesa->depthBits == 16) {
|
||||
vmesa->depthBits = mesaVis->depthBits;
|
||||
vmesa->depth.size *= 2;
|
||||
vmesa->depth.pitch *= 2;
|
||||
vmesa->depth.bpp *= 2;
|
||||
if (vmesa->depth.map)
|
||||
via_free_depth_buffer(vmesa);
|
||||
if (!via_alloc_depth_buffer(vmesa)) {
|
||||
via_free_depth_buffer(vmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
((__GLcontextModes*)mesaVis)->depthBits = 16; /* XXX : sure you want to change read-only data? */
|
||||
}
|
||||
|
||||
|
||||
/* KW: removed bogus depth recalculations.
|
||||
*/
|
||||
|
||||
if (isPixmap) {
|
||||
driDrawPriv->driverPrivate = (void *)
|
||||
_mesa_create_framebuffer(mesaVis,
|
||||
GL_FALSE, /* software depth buffer? */
|
||||
mesaVis->stencilBits > 0,
|
||||
swStencil,
|
||||
mesaVis->accumRedBits > 0,
|
||||
GL_FALSE /* s/w alpha planes */);
|
||||
|
||||
@@ -260,7 +245,7 @@ viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
|
||||
driDrawPriv->driverPrivate = (void *)
|
||||
_mesa_create_framebuffer(mesaVis,
|
||||
GL_FALSE, /* software depth buffer? */
|
||||
mesaVis->stencilBits > 0,
|
||||
swStencil,
|
||||
mesaVis->accumRedBits > 0,
|
||||
GL_FALSE /* s/w alpha planes */);
|
||||
|
||||
|
||||
@@ -44,9 +44,6 @@ typedef struct {
|
||||
int fbFormat;
|
||||
int fbOffset;
|
||||
int fbSize;
|
||||
#ifdef USE_XINERAMA
|
||||
Bool drixinerama;
|
||||
#endif
|
||||
|
||||
int fbStride;
|
||||
|
||||
|
||||
@@ -32,28 +32,13 @@
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#define DBG 0
|
||||
#define LOCAL_VARS \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
viaScreenPrivate *viaScreen = vmesa->viaScreen; \
|
||||
GLuint pitch = vmesa->drawPitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLushort p; \
|
||||
char *buf = (char *)(vmesa->drawMap + \
|
||||
dPriv->x * viaScreen->bytesPerPixel + \
|
||||
dPriv->y * pitch); \
|
||||
char *read_buf = (char *)(vmesa->readMap + \
|
||||
dPriv->x * viaScreen->bytesPerPixel + \
|
||||
dPriv->y * pitch); \
|
||||
(void)read_buf; (void)buf; (void)p
|
||||
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
viaScreenPrivate *viaScreen = vmesa->viaScreen; \
|
||||
GLuint pitch = viaScreen->backPitch; \
|
||||
GLuint depth_pitch = vmesa->depth.pitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(vmesa->depth.map + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch)
|
||||
char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
|
||||
|
||||
#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
|
||||
_y >= miny && _y < maxy)
|
||||
@@ -72,124 +57,52 @@
|
||||
|
||||
#define Y_FLIP(_y) (height - _y - 1)
|
||||
|
||||
#define HW_LOCK() \
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
|
||||
LOCK_HARDWARE_QUIESCENT(vmesa);
|
||||
#define HW_LOCK()
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
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;
|
||||
|
||||
/*=* [DBG] csmash saam : bitmap option menu can't be drawn in saam *=*/
|
||||
/*#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
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_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
int _nc = dPriv->numClipRects; \
|
||||
GLuint scrn = vmesa->saam & S_MASK; \
|
||||
if(scrn == S1) _nc = 1; \
|
||||
while (_nc--) { \
|
||||
int minx; \
|
||||
int miny; \
|
||||
int maxx; \
|
||||
int maxy; \
|
||||
if (!vmesa->saam) { \
|
||||
minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
|
||||
miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
|
||||
maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
|
||||
maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
|
||||
} \
|
||||
else { \
|
||||
minx = -10000; \
|
||||
miny = -10000; \
|
||||
maxx = 10000; \
|
||||
maxy = 10000; \
|
||||
}
|
||||
|
||||
/*else if (scrn == S0) { \
|
||||
minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
|
||||
miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
|
||||
maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
|
||||
maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
|
||||
} \
|
||||
else if (scrn == S1) { \
|
||||
drm_clip_rect_t *b = vmesa->sarea->boxes; \
|
||||
minx = b->x1; \
|
||||
miny = b->y1; \
|
||||
maxx = b->x2; \
|
||||
maxy = b->y2; \
|
||||
} \
|
||||
else { \
|
||||
drm_clip_rect_t *b = vmesa->sarea->boxes + vmesa->numClipRects;\
|
||||
minx = b->x1; \
|
||||
miny = b->y1; \
|
||||
maxx = b->x2; \
|
||||
maxy = b->y2; \
|
||||
}*/
|
||||
|
||||
#define HW_ENDCLIPLOOP() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HW_UNLOCK() \
|
||||
UNLOCK_HARDWARE(vmesa);
|
||||
|
||||
#define HW_UNLOCK()
|
||||
|
||||
/* 16 bit, 565 rgb color spanline and pixel functions
|
||||
*/
|
||||
/*=* [DBG] csmash : fix options worng position *=*/
|
||||
/*#define LOCAL_VARS \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
GLuint pitch = vmesa->drawPitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLushort p; \
|
||||
char *buf = (char *)(vmesa->drawMap + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch); \
|
||||
char *read_buf = (char *)(vmesa->readMap + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch); \
|
||||
(void)read_buf; (void)buf; (void)p*/
|
||||
|
||||
#undef LOCAL_VARS
|
||||
#define LOCAL_VARS \
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
GLuint pitch = vmesa->drawPitch; \
|
||||
GLuint draw_pitch = vmesa->drawBuffer->pitch; \
|
||||
GLuint read_pitch = vmesa->readBuffer->pitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLushort p; \
|
||||
char *buf, *read_buf; \
|
||||
p = 0; \
|
||||
if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) { \
|
||||
buf = (char *)(vmesa->drawMap); \
|
||||
read_buf = (char *)(vmesa->readMap); \
|
||||
} \
|
||||
else { \
|
||||
buf = (char *)(vmesa->drawMap + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch); \
|
||||
read_buf = (char *)(vmesa->readMap + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch); \
|
||||
}
|
||||
GLushort p = 0; \
|
||||
char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 2); \
|
||||
char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 2); \
|
||||
(void) (read_pitch && draw_pitch && buf && read_buf && p);
|
||||
|
||||
#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) | \
|
||||
*(GLushort *)(buf + _x * 2 + _y * draw_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
|
||||
*(GLushort *)(buf + _x * 2 + _y * draw_pitch) = p
|
||||
|
||||
#define READ_RGBA(rgba, _x, _y) \
|
||||
do { \
|
||||
GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * pitch); \
|
||||
GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * read_pitch); \
|
||||
rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
|
||||
rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
|
||||
@@ -203,29 +116,23 @@
|
||||
*/
|
||||
#undef LOCAL_VARS
|
||||
#undef LOCAL_DEPTH_VARS
|
||||
#undef INIT_MONO_PIXEL
|
||||
#undef DBG
|
||||
#define DBG 0
|
||||
|
||||
#define LOCAL_VARS \
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
GLuint pitch = vmesa->drawPitch; \
|
||||
GLuint draw_pitch = vmesa->drawBuffer->pitch; \
|
||||
GLuint read_pitch = vmesa->readBuffer->pitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLuint p; \
|
||||
char *buf, *read_buf; \
|
||||
p = 0; \
|
||||
if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) { \
|
||||
buf = (char *)(vmesa->drawMap); \
|
||||
read_buf = (char *)(vmesa->readMap); \
|
||||
} \
|
||||
else { \
|
||||
buf = (char *)(vmesa->drawMap + \
|
||||
dPriv->x * 4 + \
|
||||
dPriv->y * pitch); \
|
||||
read_buf = (char *)(vmesa->readMap + \
|
||||
dPriv->x * 4 + \
|
||||
dPriv->y * pitch); \
|
||||
}
|
||||
GLuint p = 0; \
|
||||
char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 4); \
|
||||
char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 4); \
|
||||
(void) (read_pitch && draw_pitch && buf && read_buf && p);
|
||||
|
||||
#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * pitch)
|
||||
#define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * pitch)
|
||||
#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * read_pitch)
|
||||
#define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * draw_pitch)
|
||||
#define SPANTMP_PIXEL_FMT GL_BGRA
|
||||
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
|
||||
@@ -236,27 +143,21 @@
|
||||
|
||||
/* 16 bit depthbuffer functions.
|
||||
*/
|
||||
/*=* John Sheng [2003.6.16] fix exy press 'i' dirty screen *=*/
|
||||
/*#define LOCAL_DEPTH_VARS \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
GLuint pitch = vmesa->depth.pitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(vmesa->depth.map + \
|
||||
dPriv->x * 2 + \
|
||||
dPriv->y * pitch) */
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
|
||||
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
|
||||
/*viaScreenPrivate *viaScreen = vmesa->viaScreen;*/ \
|
||||
GLuint pitch = vmesa->depth.pitch; \
|
||||
GLuint depth_pitch = vmesa->depth.pitch; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(vmesa->depth.map)
|
||||
char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
|
||||
|
||||
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
|
||||
|
||||
|
||||
#define WRITE_DEPTH(_x, _y, d) \
|
||||
*(GLushort *)(buf + _x * 2 + _y * pitch) = d;
|
||||
*(GLushort *)(buf + _x * 2 + _y * depth_pitch) = d;
|
||||
|
||||
#define READ_DEPTH(d, _x, _y) \
|
||||
d = *(GLushort *)(buf + _x * 2 + _y * pitch);
|
||||
d = *(GLushort *)(buf + _x * 2 + _y * depth_pitch);
|
||||
|
||||
#define TAG(x) via##x##_16
|
||||
#include "depthtmp.h"
|
||||
@@ -264,54 +165,80 @@
|
||||
/* 32 bit depthbuffer functions.
|
||||
*/
|
||||
#define WRITE_DEPTH(_x, _y, d) \
|
||||
*(GLuint *)(buf + _x * 4 + _y * pitch) = d;
|
||||
*(GLuint *)(buf + _x * 4 + _y * depth_pitch) = d;
|
||||
|
||||
#define READ_DEPTH(d, _x, _y) \
|
||||
d = *(GLuint *)(buf + _x * 4 + _y * pitch);
|
||||
d = *(GLuint *)(buf + _x * 4 + _y * depth_pitch);
|
||||
|
||||
#define TAG(x) via##x##_32
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 24/8 bit depthbuffer functions.
|
||||
*/
|
||||
/*
|
||||
#define WRITE_DEPTH(_x, _y, d) { \
|
||||
GLuint tmp = *(GLuint *)(buf + _x * 4 + y * pitch); \
|
||||
tmp &= 0xff; \
|
||||
tmp |= (d) & 0xffffff00; \
|
||||
*(GLuint *)(buf + _x * 4 + _y * pitch) = tmp; \
|
||||
|
||||
#define READ_DEPTH(d, _x, _y) \
|
||||
d = (*(GLuint *)(buf + _x * 4 + _y * pitch) & ~0xff) >> 8;
|
||||
|
||||
/* 24/8 bit interleaved depth/stencil functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) { \
|
||||
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
|
||||
tmp &= 0x000000ff; \
|
||||
tmp |= ((d)<<8); \
|
||||
*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
|
||||
}
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
|
||||
|
||||
|
||||
#define TAG(x) via##x##_24_8
|
||||
#include "depthtmp.h"
|
||||
*/
|
||||
|
||||
#define WRITE_STENCIL( _x, _y, d ) { \
|
||||
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
|
||||
tmp &= 0xffffff00; \
|
||||
tmp |= (d); \
|
||||
*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
|
||||
}
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
|
||||
|
||||
#define TAG(x) via##x##_24_8
|
||||
#include "stenciltmp.h"
|
||||
|
||||
|
||||
|
||||
static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
|
||||
GLuint bufferBit)
|
||||
{
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx);
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
|
||||
if (bufferBit == DD_FRONT_LEFT_BIT) {
|
||||
vmesa->drawMap = (char *)vmesa->driScreen->pFB;
|
||||
vmesa->readMap = (char *)vmesa->driScreen->pFB;
|
||||
vmesa->drawPitch = vmesa->front.pitch;
|
||||
vmesa->readPitch = vmesa->front.pitch;
|
||||
vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front;
|
||||
}
|
||||
else if (bufferBit == DD_BACK_LEFT_BIT) {
|
||||
vmesa->drawMap = vmesa->back.map;
|
||||
vmesa->readMap = vmesa->back.map;
|
||||
vmesa->drawPitch = vmesa->back.pitch;
|
||||
vmesa->readPitch = vmesa->back.pitch;
|
||||
vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back;
|
||||
}
|
||||
else {
|
||||
ASSERT(0);
|
||||
}
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
/* Move locking out to get reasonable span performance.
|
||||
*/
|
||||
void viaSpanRenderStart( GLcontext *ctx )
|
||||
{
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx);
|
||||
VIA_FINISH_PRIM(vmesa);
|
||||
LOCK_HARDWARE(vmesa);
|
||||
viaFlushDmaLocked(vmesa, 0);
|
||||
WAIT_IDLE(vmesa);
|
||||
}
|
||||
|
||||
void viaSpanRenderFinish( GLcontext *ctx )
|
||||
{
|
||||
viaContextPtr vmesa = VIA_CONTEXT(ctx);
|
||||
_swrast_flush( ctx );
|
||||
UNLOCK_HARDWARE( vmesa );
|
||||
}
|
||||
|
||||
void viaInitSpanFuncs(GLcontext *ctx)
|
||||
{
|
||||
@@ -320,7 +247,7 @@ void viaInitSpanFuncs(GLcontext *ctx)
|
||||
|
||||
swdd->SetBuffer = viaSetBuffer;
|
||||
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
|
||||
if (vmesa->viaScreen->bitsPerPixel == 0x10) {
|
||||
if (vmesa->viaScreen->bitsPerPixel == 16) {
|
||||
swdd->WriteRGBASpan = viaWriteRGBASpan_565;
|
||||
swdd->WriteRGBSpan = viaWriteRGBSpan_565;
|
||||
swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_565;
|
||||
@@ -329,24 +256,44 @@ void viaInitSpanFuncs(GLcontext *ctx)
|
||||
swdd->ReadRGBASpan = viaReadRGBASpan_565;
|
||||
swdd->ReadRGBAPixels = viaReadRGBAPixels_565;
|
||||
}
|
||||
else if (vmesa->viaScreen->bitsPerPixel == 0x20) {
|
||||
else if (vmesa->viaScreen->bitsPerPixel == 32) {
|
||||
viaInitPointers_8888( swdd );
|
||||
}
|
||||
else
|
||||
ASSERT(0);
|
||||
else {
|
||||
fprintf(stderr, "%s: failed\n", __FUNCTION__);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (vmesa->glCtx->Visual.depthBits == 0x10) {
|
||||
if (vmesa->glCtx->Visual.depthBits == 16) {
|
||||
swdd->ReadDepthSpan = viaReadDepthSpan_16;
|
||||
swdd->WriteDepthSpan = viaWriteDepthSpan_16;
|
||||
swdd->WriteMonoDepthSpan = viaWriteMonoDepthSpan_16;
|
||||
swdd->ReadDepthPixels = viaReadDepthPixels_16;
|
||||
swdd->WriteDepthPixels = viaWriteDepthPixels_16;
|
||||
}
|
||||
else if (vmesa->glCtx->Visual.depthBits == 0x20) {
|
||||
else if (vmesa->glCtx->Visual.depthBits == 24) {
|
||||
fprintf(stderr, "%s: 24/8 span functions\n", __FUNCTION__);
|
||||
swdd->ReadDepthSpan = viaReadDepthSpan_24_8;
|
||||
swdd->WriteDepthSpan = viaWriteDepthSpan_24_8;
|
||||
swdd->ReadDepthPixels = viaReadDepthPixels_24_8;
|
||||
swdd->WriteDepthPixels = viaWriteDepthPixels_24_8;
|
||||
|
||||
swdd->WriteStencilSpan = viaWriteStencilSpan_24_8;
|
||||
swdd->ReadStencilSpan = viaReadStencilSpan_24_8;
|
||||
swdd->WriteStencilPixels = viaWriteStencilPixels_24_8;
|
||||
swdd->ReadStencilPixels = viaReadStencilPixels_24_8;
|
||||
}
|
||||
else if (vmesa->glCtx->Visual.depthBits == 32) {
|
||||
swdd->ReadDepthSpan = viaReadDepthSpan_32;
|
||||
swdd->WriteDepthSpan = viaWriteDepthSpan_32;
|
||||
swdd->WriteMonoDepthSpan = viaWriteMonoDepthSpan_32;
|
||||
swdd->ReadDepthPixels = viaReadDepthPixels_32;
|
||||
swdd->WriteDepthPixels = viaWriteDepthPixels_32;
|
||||
}
|
||||
|
||||
swdd->SpanRenderStart = viaSpanRenderStart;
|
||||
swdd->SpanRenderFinish = viaSpanRenderFinish;
|
||||
|
||||
|
||||
swdd->WriteCI8Span = NULL;
|
||||
swdd->WriteCI32Span = NULL;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user