Compare commits

...

86 Commits

Author SHA1 Message Date
Vladimir Dergachev
380ba2daec Reduce the amount of debug output, while still printing important messages.
Make guessing texture formats easier.
2005-01-05 04:56:23 +00:00
Vladimir Dergachev
e99f390ff6 Play a little bit with texture formats.
Get NeHe demos 06, 07 and 19 working.
2005-01-05 00:18:46 +00:00
Vladimir Dergachev
065f725672 Sync with master copy. 2005-01-04 22:52:53 +00:00
Vladimir Dergachev
6b185aaedf Port code from r200 that implements color blending. Seems to work.
This can be tested with lesson19 from NeHe.
This has also shown that the alpha code does not work - we pick up a red tint
for transparent pixels somewhere.
2005-01-04 20:25:11 +00:00
Vladimir Dergachev
55ee1daaf9 Unify rendering of textured and non-textured primitives. 2005-01-04 19:15:37 +00:00
Vladimir Dergachev
638faa92fc Major code restructuring:
* move proven code into the r300_state.c
  * update ClearBuffer to cope with more dynamic state
  * cleanup !
2005-01-04 18:59:47 +00:00
Brian Paul
85edffd5ff added GLX_NV_float_buffer 2005-01-04 14:48:14 +00:00
Brian Paul
932dee87e3 use HIDDEN macro to export fewer symbols (bug 2210) 2005-01-04 14:33:47 +00:00
Brian Paul
bdbdab837e directfb changes (Claudio Ciccani) 2005-01-04 14:19:25 +00:00
Keith Whitwell
6650264802 Add GL_EXT_fog_coord 2005-01-04 12:57:02 +00:00
Keith Whitwell
31c25f2edc Add GL_EXT_secondary_color 2005-01-04 12:56:17 +00:00
Keith Whitwell
e024cae14b Turn specular lighting state on/off appropriately. 2005-01-04 12:53:41 +00:00
Keith Whitwell
b6ab7a1bf1 Change to use the t_vertex.c mechanisms for building vertices,
including Felix's ptex code.

Re-enable some assembly for performance.
2005-01-04 12:18:05 +00:00
Brian Paul
f72e4424d9 Use the GLX 1.3 pbuffer/fbconfig functions in preference to the SGIX ones.
Added more functions to pbutil.[ch] to better isolate API differences.
2005-01-04 00:58:29 +00:00
Felix Kuehling
e3748eb19b Added support for floating point depth buffers on Savage4-based
hardware. By also reversing the depth range this can compensate the loss
of accuracy of far objects caused by the projective transformation.
Software fallbacks work but are slightly slower since floats in a custom
(non IEEE) format have to be encoded and decoded. I havn't done anything
about polygon offsets yet. There doesn't seem to be an easy way do get
it right except making the offset unit as big as the lowest resolution
of depth values. For now float depth is disabled by default but can be
enabled through driconf (though I have seen only positive effects so
far).
2005-01-03 22:24:44 +00:00
Felix Kuehling
87889aeab4 Added a boolean option for a floating-point depth buffer. 2005-01-03 22:15:41 +00:00
Ian Romanick
3276c192b7 The opcode and command length fields of RenderLarge commands were
mistakenly emitted in the wrong order.
2005-01-03 21:03:03 +00:00
Brian Paul
dd1a817c50 latest updates 2005-01-03 15:55:51 +00:00
Vladimir Dergachev
a5039af357 Add structs describing vertex and pixel shader state to r300_state.
Take apart program_pipeline() and move it into appropriate pieces within the driver.
Test the framework on run_flat_render()
2005-01-03 15:45:10 +00:00
Brian Paul
8e73b14228 bump version to 6.3, etc. 2005-01-03 15:36:27 +00:00
Brian Paul
81ca616e7e DirectFB driver (Claudio Ciccani) 2005-01-03 15:35:00 +00:00
Brian Paul
6563c16e38 updates from Jouk 2005-01-03 15:01:26 +00:00
Vladimir Dergachev
25faa2d56e Turns out I left flat primitives in vertex buffer mode. Switch them back to immediate which works correctly.. 2005-01-03 06:53:38 +00:00
Vladimir Dergachev
63473a8e76 Enable code to compute other constants that were used by R200 code.
Add fprintf to print these constants.
Correct t->size computation, so it works now.
2005-01-03 06:48:50 +00:00
Vladimir Dergachev
2fc9351ee7 Port texture allocation code from R200.
Hook it up, so lesson06 displays red colored textures.
2005-01-03 05:44:20 +00:00
Vladimir Dergachev
63fd67e561 Add texture units registers 2005-01-02 21:53:53 +00:00
Vladimir Dergachev
f50a1964d1 Cleanup !
I can not trigger any lockups now..
2005-01-02 06:16:44 +00:00
Vladimir Dergachev
d6be8dd651 I think I fixed the lockups issue. 2005-01-02 05:57:15 +00:00
Vladimir Dergachev
9a04b25c60 Get textures to work with NeHe lesson06.
The code is still disabled since we are displaying random image data instead of actual texture and because I had to put a sleep(1) in lesson06 drawing loop to prevent lockups.
2005-01-02 04:46:25 +00:00
Adam Jackson
3c80f5c56b linux-dri-x86 build fix from Andreas Stenglein. 2005-01-02 03:36:53 +00:00
Felix Kuehling
7a231da442 Improved the performance of software fallbacks by not waiting for idle
in every single span function. Instead flush and wait in the
SpanRenderStart hook and in wrappers around _swrast_Copy/Draw/ReadPixels.
Misc. cleanups in savagespan.c while I'm there.
2005-01-02 01:22:10 +00:00
Felix Kuehling
1067ce0cea Removed all direct hardware access (MMIO, BCI) from the Savage DRI
driver. It uses the new DRM version 2.0.x now, which has just been
committed to DRM CVS.
2005-01-01 20:40:14 +00:00
Felix Kuehling
467d64a177 Use DRM headers from $(DRM_SOURCE_PATH)/shared-core instead of .../shared. 2005-01-01 20:33:45 +00:00
Vladimir Dergachev
404d925b58 Add a convenience function to issue CP delays. 2005-01-01 18:41:43 +00:00
Vladimir Dergachev
e443d1ec47 Qualify the magic 20B0 register as SE_VTE_CNTL similar to R200. Looks like disabling Z offset and scaling displays gears properly, not sure why. Perhaps the meaning of the bits has changed ?
Cleanup code a bit.
2004-12-31 21:28:36 +00:00
Vladimir Dergachev
92d47e79f1 Sync with master copy. 2004-12-31 20:57:48 +00:00
Vladimir Dergachev
11374bdb86 Add texture drawing code. Note: it is broken at the moment and is disabled in CVS. However, all hooks are there.
Fix vertex buffer drawing code.
2004-12-31 19:39:03 +00:00
Vladimir Dergachev
24b5e49141 Rework slightly r300_get_primitive_type - make it clearer and more compact.. 2004-12-30 20:24:30 +00:00
Keith Whitwell
179cc373f1 Get scissor test working again. Passes glean scissor test. 2004-12-30 17:47:08 +00:00
Keith Whitwell
c664f0c515 Calculate DEPTH_SCALE correctly for polygon offset. 2004-12-30 16:30:26 +00:00
Keith Whitwell
8be4747fd6 Simplify viaBlit a bit more.
Implement masked clears.
2004-12-30 16:13:35 +00:00
Vladimir Dergachev
4a04f002db Add missing files. 2004-12-30 16:06:37 +00:00
Keith Whitwell
8f1ba083ba Initialize depth pointer correctly. 2004-12-30 16:05:07 +00:00
Keith Whitwell
58cc2e9124 Don't need to adjust for drawXoff in fallback clipping. 2004-12-30 15:58:45 +00:00
Keith Whitwell
18551e75ea fix regression with fallbacks from recent commits 2004-12-30 14:32:19 +00:00
Keith Whitwell
6fcc6c4965 Fix MagFilter state for texunit 0 2004-12-30 14:21:46 +00:00
Vladimir Dergachev
bcd1a9ed68 Update vertex buffer code (still does not work properly..) 2004-12-30 11:43:04 +00:00
Vladimir Dergachev
2269445f6d Update to recent r300_lib.
Cleanup code that is not relevant anymore.
Play with unknown2 parameter.
2004-12-30 11:17:42 +00:00
Vladimir Dergachev
b53030a94c Hooked up projection matrix - the gears actually rotate ! 2004-12-30 10:27:04 +00:00
Vladimir Dergachev
a656dc251e Restructure code.
Add drawing code that uses vertex buffers - does not lockup, but does not draw correctly either.. Perhaps something to do with vertices being overwritten ?
Start using hardware state retained by the driver and cut back on direct register writes significantly.
2004-12-30 10:11:39 +00:00
Vladimir Dergachev
51050efe0e Change default RS settings so that glxgears will display something.. 2004-12-30 07:50:15 +00:00
Vladimir Dergachev
7d8c1fb03a Clarify some of the unkXXXX atoms. 2004-12-30 07:11:28 +00:00
Vladimir Dergachev
74bf43051c Port viewport setting code from R200.
Take it outside R300ResetHwState.
2004-12-30 06:06:54 +00:00
Keith Whitwell
5be14fd59a Fix some wrapping bugs in the last commit. Probably there are more
remaining.
2004-12-29 21:17:06 +00:00
Keith Whitwell
490e764d7a Simplfy clear() and swapbuffers() code.
Fix various mishandling of cliprects.
Allow multiple primitives to be emitted to a single dma buffer, which
was largely impossible previously.
Re-enable the fast unclipped render stage.
2004-12-29 20:46:27 +00:00
Keith Whitwell
ef494c06b6 Use Point._Size in calculation 2004-12-29 14:38:17 +00:00
Keith Whitwell
54ef88109b use clamped Line._Width in calculations 2004-12-29 14:36:58 +00:00
Keith Whitwell
e158292ee3 Don't advertise wide lines or points. 2004-12-29 14:09:21 +00:00
Keith Whitwell
e972497310 Make line stipple a fallback.
Make sure fallbacks are wrapped by SpanRenderStart/SpanRenderFinish
2004-12-29 14:06:09 +00:00
Keith Whitwell
f102f7ae3d Don't pingpong cliprects through sarea on CopyBuffer(). 2004-12-29 14:05:16 +00:00
Keith Whitwell
cb0cc796d2 Fallback on 3d textures correctly. 2004-12-29 13:03:12 +00:00
Keith Whitwell
3b486d795d Get twoside-lit triangles working again 2004-12-29 12:48:50 +00:00
Keith Whitwell
13ae06cf36 Large update
- Remove via duplicates of shared template files
	- Update driver to work with current versions of the above
	- Rework dma accounting
	- Rework emitting to dma to use a consistent set of macros

The handling of cliprects in the driver is still pretty questionable.
2004-12-29 12:39:50 +00:00
Vladimir Dergachev
7b05b70c2a Rearrange code so we don't dump state as often. 2004-12-29 04:51:46 +00:00
Vladimir Dergachev
4c3f041862 Get most primitives working using immediate mode.
Glxgears displays "rotating" gears, all in the same place (no transform mode, remember ?)
Work needs to be done to understand how to have glxgears working properly.
2004-12-29 04:33:33 +00:00
Vladimir Dergachev
5bdb4652f9 Bring in latest revision of r300_lib.
New capabilities: using vertex buffers, immediate vertex data, immediate indices.
2004-12-29 03:48:05 +00:00
Vladimir Dergachev
6a50fc43cb Use R300_CMD_END3D for end_3d(). 2004-12-27 23:30:39 +00:00
Adam Jackson
c6cca6a3b8 Fix read-from-uninitialized in s3vMakeCurrent() 2004-12-27 22:57:05 +00:00
Adam Jackson
29c88396db Unused variable cleanup. 2004-12-27 22:08:34 +00:00
Adam Jackson
d9fcfa2797 Bug #1859: Initialize 'size' before first use in intelTryReadPixels() 2004-12-27 21:52:17 +00:00
Adam Jackson
0983c9dd99 Build s3v and trident by default too.
Smoky the bear says: Only you can prevent bitrot.
2004-12-27 20:38:29 +00:00
Adam Jackson
c3eaa17b37 Get s3v building with a minimum of warnings. 2004-12-27 20:31:56 +00:00
Vladimir Dergachev
99edafd4e8 Implement rendering of (flat color) QUAD primitives as an experiment. 2004-12-27 17:18:48 +00:00
Ian Romanick
83fcf49647 Fixed two problems with the handling of GLX protocol replies. The logic
for determining when extra data needed to be read after a reply (to ensure
4-byte alignment) and the logic to determine whether or not to read reply
data after the SingleReply packet were both slightly wrong.
2004-12-27 08:29:54 +00:00
Vladimir Dergachev
3cbc2bd833 Expose primitive types being rendered, in preparation to implement fixed pipeline primitive drawing.
Note: these are only visible when export LIBGL_DEBUG=verbose is specified.
2004-12-26 21:42:14 +00:00
Vladimir Dergachev
1b2a655521 Update with most recent version. 2004-12-26 19:32:21 +00:00
Adam Jackson
46a35b2284 Get trident building and -Werror clean.
- Added Makefile
- Deleted references to old headers
- Added prototypes all over the place
- Lots of type updates (drmHandle -> drm_handle_t etc.)
- Added __driCreateNewScreen(), deleted __driCreateScreen()
- Fixed context creation to match other drivers
- Fixed various bitfield names
- Bumped driver date

Still nowhere close to usable, the DDX isn't DRI-aware and there's no DRM.
2004-12-24 03:04:14 +00:00
Felix Kuehling
1c86c7ad9c Simplified and optimized _savage_texnorm_stage. 2004-12-23 20:26:59 +00:00
Keith Whitwell
3deaf21745 Remove the VIA_PERFORMANCE code. A step towards moving the driver
back to using the shared template files.
2004-12-23 18:26:40 +00:00
Keith Whitwell
9876730f7a Chop out more dead code.
Get the drawXoff adjustment working a bit better.
Seems to pass the glean orthoPos tests.
2004-12-23 18:16:22 +00:00
Keith Whitwell
15da29b5e7 Fix merge error. 2004-12-22 19:31:10 +00:00
Keith Whitwell
7db50bb3a8 Remove dead code.
Fix 24/8 depth/stencil visuals.
2004-12-22 19:30:02 +00:00
Felix Kuehling
922bfd70ff Enabled hardware rendering of 1D textures. No need for a software fallback. 2004-12-22 16:12:59 +00:00
Felix Kuehling
80dd3c7917 - Fake projective textures on a single texture unit. A fallback is only
needed if a second texture unit is enabled.
- Also worked around an application bug in Chromium B.S.U.: it sends 3D
  texture coordinates while only a 2D texture is enabled. This used to
  trigger a PTEX fallback. Now the 3rd coordinate is just ignored.
- Fixed the _savage_texnorm_stage to never normalize homogenous texture
  coordinates.
2004-12-22 00:21:32 +00:00
Keith Whitwell
8bdaa927eb Remove debug code which referenced an old global variable. 2004-12-21 23:07:13 +00:00
Ian Romanick
990dec7ea0 Used GCC's __builtin_expect when available. Change the way code is
generated for commands that can use RenderLarge packets.  Tweak the code for
__glXFlushRenderBuffer slightly.
2004-12-21 23:06:02 +00:00
136 changed files with 12167 additions and 10342 deletions

View File

@@ -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
View 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

View File

@@ -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
View 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.

View File

@@ -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 $

View File

@@ -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
View 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

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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
}

View File

@@ -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*/

View File

@@ -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

View File

@@ -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

View 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

View 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 );
}

View File

@@ -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

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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

View 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

View File

@@ -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);
}
}
}

View File

@@ -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__ */

View File

@@ -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;

View File

@@ -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))

View 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

View File

@@ -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;

View File

@@ -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__ */

View File

@@ -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 */

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View 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__ */

View 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(&region, 0, sizeof(region));
r300AllocDmaRegion(rmesa, &region, 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(&region),
dstPitch, t->bufAddr,
0, 0, 0, done, width, lines);
r300EmitWait(rmesa, RADEON_WAIT_2D);
r300ReleaseDmaRegion(rmesa, &region, __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;
}

File diff suppressed because it is too large Load Diff

View 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

View 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:

View 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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"

View 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

View File

@@ -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 |

View File

@@ -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));

View File

@@ -3,7 +3,7 @@
*/
typedef struct _s3vRegion {
drmHandle handle;
drm_handle_t handle;
drmSize size;
drmAddress map;
} s3vRegion, *s3vRegionPtr;

View File

@@ -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:

View File

@@ -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;

View File

@@ -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];

View File

@@ -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

View File

@@ -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));

View File

@@ -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

View File

@@ -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];

View File

@@ -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: "));

View File

@@ -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;
}
}

View File

@@ -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)
{

View File

@@ -25,8 +25,7 @@ DRIVER_SOURCES = \
savagetex.c \
savagetris.c \
savageioctl.c \
savagespan.c \
savagedma.c
savagespan.c
C_SOURCES = \
$(COMMON_SOURCES) \

View File

@@ -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

View File

@@ -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 );

View File

@@ -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,

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View 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:

View File

@@ -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 */

View File

@@ -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))

View File

@@ -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.
*/

View 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

View 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)

View File

@@ -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 )
{

View File

@@ -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.
*/

View File

@@ -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;
}
}

View File

@@ -29,7 +29,6 @@ DRIVER_SOURCES = \
via_texmem.c \
via_texstate.c \
via_tris.c \
via_vb.c \
via_texcombine.c \
xf86drmVIA.c

View File

@@ -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)

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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),
};

View File

@@ -29,9 +29,6 @@ typedef struct {
int priv2;
int fbOffset;
int fbSize;
#ifdef USE_XINERAMA
Bool drixinerama;
#endif
int backOffset;
int depthOffset;
int textureOffset;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */
};

View File

@@ -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 */);

View File

@@ -44,9 +44,6 @@ typedef struct {
int fbFormat;
int fbOffset;
int fbSize;
#ifdef USE_XINERAMA
Bool drixinerama;
#endif
int fbStride;

View File

@@ -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