mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-30 08:20:41 +02:00
Initial revision
This commit is contained in:
parent
bbe364603c
commit
f30d53e049
28 changed files with 8258 additions and 0 deletions
72
src/mesa/drivers/dri/r300/Makefile
Normal file
72
src/mesa/drivers/dri/r300/Makefile
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# src/mesa/drivers/dri/r300/Makefile
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = r300_dri.so
|
||||
DEFINES += -DCOMPILE_R300
|
||||
|
||||
MINIGLX_SOURCES = server/radeon_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 = \
|
||||
radeon_screen.c \
|
||||
radeon_context.c \
|
||||
radeon_ioctl.c \
|
||||
radeon_lock.c \
|
||||
radeon_span.c \
|
||||
\
|
||||
r300_context.c \
|
||||
r300_ioctl.c \
|
||||
r300_cmdbuf.c \
|
||||
r300_state.c \
|
||||
\
|
||||
r200_context.c \
|
||||
r200_ioctl.c \
|
||||
r200_state.c \
|
||||
r200_state_init.c \
|
||||
r200_cmdbuf.c \
|
||||
r200_pixel.c \
|
||||
r200_tex.c \
|
||||
r200_texmem.c \
|
||||
r200_texstate.c \
|
||||
r200_tcl.c \
|
||||
r200_swtcl.c \
|
||||
r200_maos.c \
|
||||
r200_sanity.c \
|
||||
r200_vtxfmt.c \
|
||||
r200_vtxfmt_c.c \
|
||||
r200_vtxfmt_sse.c \
|
||||
r200_vtxfmt_x86.c
|
||||
|
||||
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
|
||||
|
||||
X86_SOURCES = r200_vtxtmp_x86.S
|
||||
|
||||
SYMLINKS = \
|
||||
server/radeon_dri.c \
|
||||
server/radeon_dri.h \
|
||||
server/radeon.h \
|
||||
server/radeon_macros.h \
|
||||
server/radeon_reg.h
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
$(SYMLINKS):
|
||||
mkdir -p server
|
||||
for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done
|
||||
|
||||
symlinks: $(SYMLINKS)
|
||||
|
||||
840
src/mesa/drivers/dri/r300/r200_context.h
Normal file
840
src/mesa/drivers/dri/r300/r200_context.h
Normal file
|
|
@ -0,0 +1,840 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes 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 __R200_CONTEXT_H__
|
||||
#define __R200_CONTEXT_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "tnl/t_vertex.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "dri_util.h"
|
||||
#include "texmem.h"
|
||||
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
#include "r200_reg.h"
|
||||
#include "radeon_context.h"
|
||||
|
||||
#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */
|
||||
|
||||
struct r200_context;
|
||||
typedef struct r200_context r200ContextRec;
|
||||
typedef struct r200_context *r200ContextPtr;
|
||||
|
||||
#include "mm.h"
|
||||
|
||||
/* The blit width for texture uploads
|
||||
*/
|
||||
#define BLIT_WIDTH_BYTES 1024
|
||||
|
||||
/* Use the templated vertex format:
|
||||
*/
|
||||
#define COLOR_IS_RGBA
|
||||
#define TAG(x) r200##x
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
typedef void (*r200_tri_func) (r200ContextPtr,
|
||||
r200Vertex *, r200Vertex *, r200Vertex *);
|
||||
|
||||
typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *);
|
||||
|
||||
typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *);
|
||||
|
||||
struct r200_depthbuffer_state {
|
||||
GLfloat scale;
|
||||
};
|
||||
|
||||
struct r200_scissor_state {
|
||||
drm_clip_rect_t rect;
|
||||
GLboolean enabled;
|
||||
|
||||
GLuint numClipRects; /* Cliprects active */
|
||||
GLuint numAllocedClipRects; /* Cliprects available */
|
||||
drm_clip_rect_t *pClipRects;
|
||||
};
|
||||
|
||||
struct r200_stencilbuffer_state {
|
||||
GLboolean hwBuffer;
|
||||
GLuint clear; /* rb3d_stencilrefmask value */
|
||||
};
|
||||
|
||||
struct r200_stipple_state {
|
||||
GLuint mask[32];
|
||||
};
|
||||
|
||||
#define TEX_0 0x1
|
||||
#define TEX_1 0x2
|
||||
#define TEX_2 0x4
|
||||
#define TEX_3 0x8
|
||||
#define TEX_4 0x10
|
||||
#define TEX_5 0x20
|
||||
#define TEX_ALL 0x3f
|
||||
|
||||
typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr;
|
||||
|
||||
/* Texture object in locally shared texture space.
|
||||
*/
|
||||
struct r200_tex_obj {
|
||||
driTextureObject base;
|
||||
|
||||
GLuint bufAddr; /* Offset to start of locally
|
||||
shared texture block */
|
||||
|
||||
GLuint dirty_state; /* Flags (1 per texunit) for
|
||||
whether or not this texobj
|
||||
has dirty hardware state
|
||||
(pp_*) that needs to be
|
||||
brought into the
|
||||
texunit. */
|
||||
|
||||
drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
|
||||
/* Six, for the cube faces */
|
||||
|
||||
GLuint pp_txfilter; /* hardware register values */
|
||||
GLuint pp_txformat;
|
||||
GLuint pp_txformat_x;
|
||||
GLuint pp_txoffset; /* Image location in texmem.
|
||||
All cube faces follow. */
|
||||
GLuint pp_txsize; /* npot only */
|
||||
GLuint pp_txpitch; /* npot only */
|
||||
GLuint pp_border_color;
|
||||
GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */
|
||||
|
||||
GLboolean border_fallback;
|
||||
};
|
||||
|
||||
struct r200_texture_env_state {
|
||||
r200TexObjPtr texobj;
|
||||
GLenum format;
|
||||
GLenum envMode;
|
||||
};
|
||||
|
||||
#define R200_MAX_TEXTURE_UNITS 6
|
||||
|
||||
struct r200_texture_state {
|
||||
struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS];
|
||||
};
|
||||
|
||||
struct r200_state_atom {
|
||||
struct r200_state_atom *next, *prev;
|
||||
const char *name; /* for debug */
|
||||
int cmd_size; /* size in bytes */
|
||||
GLuint idx;
|
||||
int *cmd; /* one or more cmd's */
|
||||
int *lastcmd; /* one or more cmd's */
|
||||
int *savedcmd; /* one or more cmd's */
|
||||
GLboolean dirty;
|
||||
GLboolean(*check) (GLcontext *, int); /* is this state active? */
|
||||
};
|
||||
|
||||
/* Trying to keep these relatively short as the variables are becoming
|
||||
* extravagently long. Drop the driver name prefix off the front of
|
||||
* everything - I think we know which driver we're in by now, and keep the
|
||||
* prefix to 3 letters unless absolutely impossible.
|
||||
*/
|
||||
|
||||
#define CTX_CMD_0 0
|
||||
#define CTX_PP_MISC 1
|
||||
#define CTX_PP_FOG_COLOR 2
|
||||
#define CTX_RE_SOLID_COLOR 3
|
||||
#define CTX_RB3D_BLENDCNTL 4
|
||||
#define CTX_RB3D_DEPTHOFFSET 5
|
||||
#define CTX_RB3D_DEPTHPITCH 6
|
||||
#define CTX_RB3D_ZSTENCILCNTL 7
|
||||
#define CTX_CMD_1 8
|
||||
#define CTX_PP_CNTL 9
|
||||
#define CTX_RB3D_CNTL 10
|
||||
#define CTX_RB3D_COLOROFFSET 11
|
||||
#define CTX_CMD_2 12 /* why */
|
||||
#define CTX_RB3D_COLORPITCH 13 /* why */
|
||||
#define CTX_STATE_SIZE_OLDDRM 14
|
||||
#define CTX_CMD_3 14
|
||||
#define CTX_RB3D_BLENDCOLOR 15
|
||||
#define CTX_RB3D_ABLENDCNTL 16
|
||||
#define CTX_RB3D_CBLENDCNTL 17
|
||||
#define CTX_STATE_SIZE_NEWDRM 18
|
||||
|
||||
#define SET_CMD_0 0
|
||||
#define SET_SE_CNTL 1
|
||||
#define SET_RE_CNTL 2 /* replace se_coord_fmt */
|
||||
#define SET_STATE_SIZE 3
|
||||
|
||||
#define VTE_CMD_0 0
|
||||
#define VTE_SE_VTE_CNTL 1
|
||||
#define VTE_STATE_SIZE 2
|
||||
|
||||
#define LIN_CMD_0 0
|
||||
#define LIN_RE_LINE_PATTERN 1
|
||||
#define LIN_RE_LINE_STATE 2
|
||||
#define LIN_CMD_1 3
|
||||
#define LIN_SE_LINE_WIDTH 4
|
||||
#define LIN_STATE_SIZE 5
|
||||
|
||||
#define MSK_CMD_0 0
|
||||
#define MSK_RB3D_STENCILREFMASK 1
|
||||
#define MSK_RB3D_ROPCNTL 2
|
||||
#define MSK_RB3D_PLANEMASK 3
|
||||
#define MSK_STATE_SIZE 4
|
||||
|
||||
#define VPT_CMD_0 0
|
||||
#define VPT_SE_VPORT_XSCALE 1
|
||||
#define VPT_SE_VPORT_XOFFSET 2
|
||||
#define VPT_SE_VPORT_YSCALE 3
|
||||
#define VPT_SE_VPORT_YOFFSET 4
|
||||
#define VPT_SE_VPORT_ZSCALE 5
|
||||
#define VPT_SE_VPORT_ZOFFSET 6
|
||||
#define VPT_STATE_SIZE 7
|
||||
|
||||
#define ZBS_CMD_0 0
|
||||
#define ZBS_SE_ZBIAS_FACTOR 1
|
||||
#define ZBS_SE_ZBIAS_CONSTANT 2
|
||||
#define ZBS_STATE_SIZE 3
|
||||
|
||||
#define MSC_CMD_0 0
|
||||
#define MSC_RE_MISC 1
|
||||
#define MSC_STATE_SIZE 2
|
||||
|
||||
#define TAM_CMD_0 0
|
||||
#define TAM_DEBUG3 1
|
||||
#define TAM_STATE_SIZE 2
|
||||
|
||||
#define TEX_CMD_0 0
|
||||
#define TEX_PP_TXFILTER 1 /*2c00 */
|
||||
#define TEX_PP_TXFORMAT 2 /*2c04 */
|
||||
#define TEX_PP_TXFORMAT_X 3 /*2c08 */
|
||||
#define TEX_PP_TXSIZE 4 /*2c0c */
|
||||
#define TEX_PP_TXPITCH 5 /*2c10 */
|
||||
#define TEX_PP_BORDER_COLOR 6 /*2c14 */
|
||||
#define TEX_CMD_1 7
|
||||
#define TEX_PP_TXOFFSET 8 /*2d00 */
|
||||
#define TEX_STATE_SIZE 9
|
||||
|
||||
#define CUBE_CMD_0 0 /* 1 register follows */
|
||||
#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */
|
||||
#define CUBE_CMD_1 2 /* 5 registers follow */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */
|
||||
#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */
|
||||
#define CUBE_STATE_SIZE 8
|
||||
|
||||
#define PIX_CMD_0 0
|
||||
#define PIX_PP_TXCBLEND 1
|
||||
#define PIX_PP_TXCBLEND2 2
|
||||
#define PIX_PP_TXABLEND 3
|
||||
#define PIX_PP_TXABLEND2 4
|
||||
#define PIX_STATE_SIZE 5
|
||||
|
||||
#define TF_CMD_0 0
|
||||
#define TF_TFACTOR_0 1
|
||||
#define TF_TFACTOR_1 2
|
||||
#define TF_TFACTOR_2 3
|
||||
#define TF_TFACTOR_3 4
|
||||
#define TF_TFACTOR_4 5
|
||||
#define TF_TFACTOR_5 6
|
||||
#define TF_STATE_SIZE 7
|
||||
|
||||
#define TCL_CMD_0 0
|
||||
#define TCL_LIGHT_MODEL_CTL_0 1
|
||||
#define TCL_LIGHT_MODEL_CTL_1 2
|
||||
#define TCL_PER_LIGHT_CTL_0 3
|
||||
#define TCL_PER_LIGHT_CTL_1 4
|
||||
#define TCL_PER_LIGHT_CTL_2 5
|
||||
#define TCL_PER_LIGHT_CTL_3 6
|
||||
#define TCL_CMD_1 7
|
||||
#define TCL_UCP_VERT_BLEND_CTL 8
|
||||
#define TCL_STATE_SIZE 9
|
||||
|
||||
#define MSL_CMD_0 0
|
||||
#define MSL_MATRIX_SELECT_0 1
|
||||
#define MSL_MATRIX_SELECT_1 2
|
||||
#define MSL_MATRIX_SELECT_2 3
|
||||
#define MSL_MATRIX_SELECT_3 4
|
||||
#define MSL_MATRIX_SELECT_4 5
|
||||
#define MSL_STATE_SIZE 6
|
||||
|
||||
#define TCG_CMD_0 0
|
||||
#define TCG_TEX_PROC_CTL_2 1
|
||||
#define TCG_TEX_PROC_CTL_3 2
|
||||
#define TCG_TEX_PROC_CTL_0 3
|
||||
#define TCG_TEX_PROC_CTL_1 4
|
||||
#define TCG_TEX_CYL_WRAP_CTL 5
|
||||
#define TCG_STATE_SIZE 6
|
||||
|
||||
#define MTL_CMD_0 0
|
||||
#define MTL_EMMISSIVE_RED 1
|
||||
#define MTL_EMMISSIVE_GREEN 2
|
||||
#define MTL_EMMISSIVE_BLUE 3
|
||||
#define MTL_EMMISSIVE_ALPHA 4
|
||||
#define MTL_AMBIENT_RED 5
|
||||
#define MTL_AMBIENT_GREEN 6
|
||||
#define MTL_AMBIENT_BLUE 7
|
||||
#define MTL_AMBIENT_ALPHA 8
|
||||
#define MTL_DIFFUSE_RED 9
|
||||
#define MTL_DIFFUSE_GREEN 10
|
||||
#define MTL_DIFFUSE_BLUE 11
|
||||
#define MTL_DIFFUSE_ALPHA 12
|
||||
#define MTL_SPECULAR_RED 13
|
||||
#define MTL_SPECULAR_GREEN 14
|
||||
#define MTL_SPECULAR_BLUE 15
|
||||
#define MTL_SPECULAR_ALPHA 16
|
||||
#define MTL_CMD_1 17
|
||||
#define MTL_SHININESS 18
|
||||
#define MTL_STATE_SIZE 19
|
||||
|
||||
#define VAP_CMD_0 0
|
||||
#define VAP_SE_VAP_CNTL 1
|
||||
#define VAP_STATE_SIZE 2
|
||||
|
||||
/* Replaces a lot of packet info from radeon
|
||||
*/
|
||||
#define VTX_CMD_0 0
|
||||
#define VTX_VTXFMT_0 1
|
||||
#define VTX_VTXFMT_1 2
|
||||
#define VTX_TCL_OUTPUT_VTXFMT_0 3
|
||||
#define VTX_TCL_OUTPUT_VTXFMT_1 4
|
||||
#define VTX_CMD_1 5
|
||||
#define VTX_TCL_OUTPUT_COMPSEL 6
|
||||
#define VTX_CMD_2 7
|
||||
#define VTX_STATE_CNTL 8
|
||||
#define VTX_STATE_SIZE 9
|
||||
|
||||
#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
|
||||
R200_VTX_COLOR_MASK)
|
||||
|
||||
/**
|
||||
* Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine
|
||||
* how many components are in texture coordinate \c n.
|
||||
*/
|
||||
#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07)
|
||||
|
||||
#define MAT_CMD_0 0
|
||||
#define MAT_ELT_0 1
|
||||
#define MAT_STATE_SIZE 17
|
||||
|
||||
#define GRD_CMD_0 0
|
||||
#define GRD_VERT_GUARD_CLIP_ADJ 1
|
||||
#define GRD_VERT_GUARD_DISCARD_ADJ 2
|
||||
#define GRD_HORZ_GUARD_CLIP_ADJ 3
|
||||
#define GRD_HORZ_GUARD_DISCARD_ADJ 4
|
||||
#define GRD_STATE_SIZE 5
|
||||
|
||||
/* position changes frequently when lighting in modelpos - separate
|
||||
* out to new state item?
|
||||
*/
|
||||
#define LIT_CMD_0 0
|
||||
#define LIT_AMBIENT_RED 1
|
||||
#define LIT_AMBIENT_GREEN 2
|
||||
#define LIT_AMBIENT_BLUE 3
|
||||
#define LIT_AMBIENT_ALPHA 4
|
||||
#define LIT_DIFFUSE_RED 5
|
||||
#define LIT_DIFFUSE_GREEN 6
|
||||
#define LIT_DIFFUSE_BLUE 7
|
||||
#define LIT_DIFFUSE_ALPHA 8
|
||||
#define LIT_SPECULAR_RED 9
|
||||
#define LIT_SPECULAR_GREEN 10
|
||||
#define LIT_SPECULAR_BLUE 11
|
||||
#define LIT_SPECULAR_ALPHA 12
|
||||
#define LIT_POSITION_X 13
|
||||
#define LIT_POSITION_Y 14
|
||||
#define LIT_POSITION_Z 15
|
||||
#define LIT_POSITION_W 16
|
||||
#define LIT_DIRECTION_X 17
|
||||
#define LIT_DIRECTION_Y 18
|
||||
#define LIT_DIRECTION_Z 19
|
||||
#define LIT_DIRECTION_W 20
|
||||
#define LIT_ATTEN_QUADRATIC 21
|
||||
#define LIT_ATTEN_LINEAR 22
|
||||
#define LIT_ATTEN_CONST 23
|
||||
#define LIT_ATTEN_XXX 24
|
||||
#define LIT_CMD_1 25
|
||||
#define LIT_SPOT_DCD 26
|
||||
#define LIT_SPOT_DCM 27
|
||||
#define LIT_SPOT_EXPONENT 28
|
||||
#define LIT_SPOT_CUTOFF 29
|
||||
#define LIT_SPECULAR_THRESH 30
|
||||
#define LIT_RANGE_CUTOFF 31 /* ? */
|
||||
#define LIT_ATTEN_CONST_INV 32
|
||||
#define LIT_STATE_SIZE 33
|
||||
|
||||
/* Fog
|
||||
*/
|
||||
#define FOG_CMD_0 0
|
||||
#define FOG_R 1
|
||||
#define FOG_C 2
|
||||
#define FOG_D 3
|
||||
#define FOG_PAD 4
|
||||
#define FOG_STATE_SIZE 5
|
||||
|
||||
/* UCP
|
||||
*/
|
||||
#define UCP_CMD_0 0
|
||||
#define UCP_X 1
|
||||
#define UCP_Y 2
|
||||
#define UCP_Z 3
|
||||
#define UCP_W 4
|
||||
#define UCP_STATE_SIZE 5
|
||||
|
||||
/* GLT - Global ambient
|
||||
*/
|
||||
#define GLT_CMD_0 0
|
||||
#define GLT_RED 1
|
||||
#define GLT_GREEN 2
|
||||
#define GLT_BLUE 3
|
||||
#define GLT_ALPHA 4
|
||||
#define GLT_STATE_SIZE 5
|
||||
|
||||
/* EYE
|
||||
*/
|
||||
#define EYE_CMD_0 0
|
||||
#define EYE_X 1
|
||||
#define EYE_Y 2
|
||||
#define EYE_Z 3
|
||||
#define EYE_RESCALE_FACTOR 4
|
||||
#define EYE_STATE_SIZE 5
|
||||
|
||||
/* CST - constant state
|
||||
*/
|
||||
#define CST_CMD_0 0
|
||||
#define CST_PP_CNTL_X 1
|
||||
#define CST_CMD_1 2
|
||||
#define CST_RB3D_DEPTHXY_OFFSET 3
|
||||
#define CST_CMD_2 4
|
||||
#define CST_RE_AUX_SCISSOR_CNTL 5
|
||||
#define CST_CMD_3 6
|
||||
#define CST_RE_SCISSOR_TL_0 7
|
||||
#define CST_RE_SCISSOR_BR_0 8
|
||||
#define CST_CMD_4 9
|
||||
#define CST_SE_VAP_CNTL_STATUS 10
|
||||
#define CST_CMD_5 11
|
||||
#define CST_RE_POINTSIZE 12
|
||||
#define CST_CMD_6 13
|
||||
#define CST_SE_TCL_INPUT_VTX_0 14
|
||||
#define CST_SE_TCL_INPUT_VTX_1 15
|
||||
#define CST_SE_TCL_INPUT_VTX_2 16
|
||||
#define CST_SE_TCL_INPUT_VTX_3 17
|
||||
#define CST_STATE_SIZE 18
|
||||
|
||||
struct r200_hw_state {
|
||||
/* Head of the linked list of state atoms. */
|
||||
struct r200_state_atom atomlist;
|
||||
|
||||
/* Hardware state, stored as cmdbuf commands:
|
||||
* -- Need to doublebuffer for
|
||||
* - reviving state after loss of context
|
||||
* - eliding noop statechange loops? (except line stipple count)
|
||||
*/
|
||||
struct r200_state_atom ctx;
|
||||
struct r200_state_atom set;
|
||||
struct r200_state_atom vte;
|
||||
struct r200_state_atom lin;
|
||||
struct r200_state_atom msk;
|
||||
struct r200_state_atom vpt;
|
||||
struct r200_state_atom vap;
|
||||
struct r200_state_atom vtx;
|
||||
struct r200_state_atom tcl;
|
||||
struct r200_state_atom msl;
|
||||
struct r200_state_atom tcg;
|
||||
struct r200_state_atom msc;
|
||||
struct r200_state_atom cst;
|
||||
struct r200_state_atom tam;
|
||||
struct r200_state_atom tf;
|
||||
struct r200_state_atom tex[6];
|
||||
struct r200_state_atom cube[6];
|
||||
struct r200_state_atom zbs;
|
||||
struct r200_state_atom mtl[2];
|
||||
struct r200_state_atom mat[9];
|
||||
struct r200_state_atom lit[8]; /* includes vec, scl commands */
|
||||
struct r200_state_atom ucp[6];
|
||||
struct r200_state_atom pix[6]; /* pixshader stages */
|
||||
struct r200_state_atom eye; /* eye pos */
|
||||
struct r200_state_atom grd; /* guard band clipping */
|
||||
struct r200_state_atom fog;
|
||||
struct r200_state_atom glt;
|
||||
|
||||
int max_state_size; /* Number of bytes necessary for a full state emit. */
|
||||
GLboolean is_dirty, all_dirty;
|
||||
};
|
||||
|
||||
struct r200_colorbuffer_state {
|
||||
int roundEnable;
|
||||
};
|
||||
|
||||
struct r200_state {
|
||||
/* Derived state for internal purposes:
|
||||
*/
|
||||
struct r200_colorbuffer_state color;
|
||||
struct r200_depthbuffer_state depth;
|
||||
struct r200_scissor_state scissor;
|
||||
struct r200_stencilbuffer_state stencil;
|
||||
struct r200_stipple_state stipple;
|
||||
struct r200_texture_state texture;
|
||||
};
|
||||
|
||||
/* Need refcounting on dma buffers:
|
||||
*/
|
||||
struct r200_dma_buffer {
|
||||
int refcount; /* the number of retained regions in buf */
|
||||
drmBufPtr buf;
|
||||
};
|
||||
|
||||
#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
|
||||
(rvb)->address - rmesa->dma.buf0_address + \
|
||||
(rvb)->start)
|
||||
|
||||
/* A retained region, eg vertices for indexed vertices.
|
||||
*/
|
||||
struct r200_dma_region {
|
||||
struct r200_dma_buffer *buf;
|
||||
char *address; /* == buf->address */
|
||||
int start, end, ptr; /* offsets from start of buf */
|
||||
int aos_start;
|
||||
int aos_stride;
|
||||
int aos_size;
|
||||
};
|
||||
|
||||
struct r200_dma {
|
||||
/* Active dma region. Allocations for vertices and retained
|
||||
* regions come from here. Also used for emitting random vertices,
|
||||
* these may be flushed by calling flush_current();
|
||||
*/
|
||||
struct r200_dma_region current;
|
||||
|
||||
void (*flush) (r200ContextPtr);
|
||||
|
||||
char *buf0_address; /* start of buf[0], for index calcs */
|
||||
GLuint nr_released_bufs; /* flush after so many buffers released */
|
||||
};
|
||||
|
||||
#define R200_CMD_BUF_SZ (8*1024)
|
||||
|
||||
struct r200_store {
|
||||
GLuint statenr;
|
||||
GLuint primnr;
|
||||
char cmd_buf[R200_CMD_BUF_SZ];
|
||||
int cmd_used;
|
||||
int elts_start;
|
||||
};
|
||||
|
||||
/* r200_tcl.c
|
||||
*/
|
||||
struct r200_tcl_info {
|
||||
GLuint vertex_format;
|
||||
GLint last_offset;
|
||||
GLuint hw_primitive;
|
||||
|
||||
struct r200_dma_region *aos_components[8];
|
||||
GLuint nr_aos_components;
|
||||
|
||||
GLuint *Elts;
|
||||
|
||||
struct r200_dma_region indexed_verts;
|
||||
struct r200_dma_region obj;
|
||||
struct r200_dma_region rgba;
|
||||
struct r200_dma_region spec;
|
||||
struct r200_dma_region fog;
|
||||
struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
|
||||
struct r200_dma_region norm;
|
||||
};
|
||||
|
||||
/* r200_swtcl.c
|
||||
*/
|
||||
struct r200_swtcl_info {
|
||||
GLuint RenderIndex;
|
||||
|
||||
/**
|
||||
* Size of a hardware vertex. This is calculated when \c ::vertex_attrs is
|
||||
* installed in the Mesa state vector.
|
||||
*/
|
||||
GLuint vertex_size;
|
||||
|
||||
/**
|
||||
* Attributes instructing the Mesa TCL pipeline where / how to put vertex
|
||||
* data in the hardware buffer.
|
||||
*/
|
||||
struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
|
||||
|
||||
/**
|
||||
* Number of elements of \c ::vertex_attrs that are actually used.
|
||||
*/
|
||||
GLuint vertex_attr_count;
|
||||
|
||||
/**
|
||||
* Cached pointer to the buffer where Mesa will store vertex data.
|
||||
*/
|
||||
GLubyte *verts;
|
||||
|
||||
/* Fallback rasterization functions
|
||||
*/
|
||||
r200_point_func draw_point;
|
||||
r200_line_func draw_line;
|
||||
r200_tri_func draw_tri;
|
||||
|
||||
GLuint hw_primitive;
|
||||
GLenum render_primitive;
|
||||
GLuint numverts;
|
||||
|
||||
/**
|
||||
* Offset of the 4UB color data within a hardware (swtcl) vertex.
|
||||
*/
|
||||
GLuint coloroffset;
|
||||
|
||||
/**
|
||||
* Offset of the 3UB specular color data within a hardware (swtcl) vertex.
|
||||
*/
|
||||
GLuint specoffset;
|
||||
|
||||
/**
|
||||
* Should Mesa project vertex data or will the hardware do it?
|
||||
*/
|
||||
GLboolean needproj;
|
||||
|
||||
struct r200_dma_region indexed_verts;
|
||||
};
|
||||
|
||||
struct r200_ioctl {
|
||||
GLuint vertex_offset;
|
||||
GLuint vertex_size;
|
||||
};
|
||||
|
||||
#define R200_MAX_PRIMS 64
|
||||
|
||||
/* Want to keep a cache of these around. Each is parameterized by
|
||||
* only a single value which has only a small range. Only expect a
|
||||
* few, so just rescan the list each time?
|
||||
*/
|
||||
struct dynfn {
|
||||
struct dynfn *next, *prev;
|
||||
int key[2];
|
||||
char *code;
|
||||
};
|
||||
|
||||
struct dfn_lists {
|
||||
struct dynfn Vertex2f;
|
||||
struct dynfn Vertex2fv;
|
||||
struct dynfn Vertex3f;
|
||||
struct dynfn Vertex3fv;
|
||||
struct dynfn Color4ub;
|
||||
struct dynfn Color4ubv;
|
||||
struct dynfn Color3ub;
|
||||
struct dynfn Color3ubv;
|
||||
struct dynfn Color4f;
|
||||
struct dynfn Color4fv;
|
||||
struct dynfn Color3f;
|
||||
struct dynfn Color3fv;
|
||||
struct dynfn SecondaryColor3ubEXT;
|
||||
struct dynfn SecondaryColor3ubvEXT;
|
||||
struct dynfn SecondaryColor3fEXT;
|
||||
struct dynfn SecondaryColor3fvEXT;
|
||||
struct dynfn Normal3f;
|
||||
struct dynfn Normal3fv;
|
||||
struct dynfn TexCoord3f;
|
||||
struct dynfn TexCoord3fv;
|
||||
struct dynfn TexCoord2f;
|
||||
struct dynfn TexCoord2fv;
|
||||
struct dynfn TexCoord1f;
|
||||
struct dynfn TexCoord1fv;
|
||||
struct dynfn MultiTexCoord3fARB;
|
||||
struct dynfn MultiTexCoord3fvARB;
|
||||
struct dynfn MultiTexCoord2fARB;
|
||||
struct dynfn MultiTexCoord2fvARB;
|
||||
struct dynfn MultiTexCoord1fARB;
|
||||
struct dynfn MultiTexCoord1fvARB;
|
||||
};
|
||||
|
||||
struct dfn_generators {
|
||||
struct dynfn *(*Vertex2f) (GLcontext *, const int *);
|
||||
struct dynfn *(*Vertex2fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*Vertex3f) (GLcontext *, const int *);
|
||||
struct dynfn *(*Vertex3fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color4ub) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color4ubv) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color3ub) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color3ubv) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color4f) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color4fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color3f) (GLcontext *, const int *);
|
||||
struct dynfn *(*Color3fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *);
|
||||
struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *);
|
||||
struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *);
|
||||
struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *);
|
||||
struct dynfn *(*Normal3f) (GLcontext *, const int *);
|
||||
struct dynfn *(*Normal3fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord3f) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord3fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord2f) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord2fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord1f) (GLcontext *, const int *);
|
||||
struct dynfn *(*TexCoord1fv) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *);
|
||||
struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *);
|
||||
};
|
||||
|
||||
struct r200_prim {
|
||||
GLuint start;
|
||||
GLuint end;
|
||||
GLuint prim;
|
||||
};
|
||||
|
||||
/* A maximum total of 29 elements per vertex: 3 floats for position, 3
|
||||
* floats for normal, 4 floats for color, 4 bytes for secondary color,
|
||||
* 3 floats for each texture unit (18 floats total).
|
||||
*
|
||||
* we maybe need add. 4 to prevent segfault if someone specifies
|
||||
* GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: )
|
||||
*
|
||||
* The position data is never actually stored here, so 3 elements could be
|
||||
* trimmed out of the buffer.
|
||||
*/
|
||||
|
||||
#define R200_MAX_VERTEX_SIZE ((3*6)+11)
|
||||
|
||||
struct r200_vbinfo {
|
||||
GLint counter, initial_counter;
|
||||
GLint *dmaptr;
|
||||
void (*notify) (void);
|
||||
GLint vertex_size;
|
||||
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
r200_color_t color;
|
||||
} vertex[R200_MAX_VERTEX_SIZE];
|
||||
|
||||
GLfloat *normalptr;
|
||||
GLfloat *floatcolorptr;
|
||||
r200_color_t *colorptr;
|
||||
GLfloat *floatspecptr;
|
||||
r200_color_t *specptr;
|
||||
GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */
|
||||
|
||||
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
|
||||
GLuint primflags;
|
||||
GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */
|
||||
GLboolean installed;
|
||||
GLboolean fell_back;
|
||||
GLboolean recheck;
|
||||
GLint nrverts;
|
||||
GLuint vtxfmt_0, vtxfmt_1;
|
||||
|
||||
GLuint installed_vertex_format;
|
||||
GLuint installed_color_3f_sz;
|
||||
|
||||
struct r200_prim primlist[R200_MAX_PRIMS];
|
||||
int nrprims;
|
||||
|
||||
struct dfn_lists dfn_cache;
|
||||
struct dfn_generators codegen;
|
||||
GLvertexformat vtxfmt;
|
||||
};
|
||||
|
||||
/**
|
||||
* R200 context structure.
|
||||
*/
|
||||
struct r200_context {
|
||||
struct radeon_context radeon; /* parent class, must be first */
|
||||
|
||||
/* Driver and hardware state management
|
||||
*/
|
||||
struct r200_hw_state hw;
|
||||
struct r200_state state;
|
||||
|
||||
/* Texture object bookkeeping
|
||||
*/
|
||||
unsigned nr_heaps;
|
||||
driTexHeap *texture_heaps[R200_NR_TEX_HEAPS];
|
||||
driTextureObject swapped;
|
||||
int texture_depth;
|
||||
float initialMaxAnisotropy;
|
||||
|
||||
/* Rasterization and vertex state:
|
||||
*/
|
||||
GLuint NewGLState;
|
||||
|
||||
/* Vertex buffers
|
||||
*/
|
||||
struct r200_ioctl ioctl;
|
||||
struct r200_dma dma;
|
||||
struct r200_store store;
|
||||
GLboolean save_on_next_unlock;
|
||||
|
||||
/* Clientdata textures;
|
||||
*/
|
||||
GLuint prefer_gart_client_texturing;
|
||||
|
||||
/* TCL stuff
|
||||
*/
|
||||
GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS];
|
||||
GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS];
|
||||
GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS];
|
||||
GLuint TexMatEnabled;
|
||||
GLuint TexMatCompSel;
|
||||
GLuint TexGenEnabled;
|
||||
GLuint TexGenInputs;
|
||||
GLuint TexGenCompSel;
|
||||
GLmatrix tmpmat;
|
||||
|
||||
/* r200_tcl.c
|
||||
*/
|
||||
struct r200_tcl_info tcl;
|
||||
|
||||
/* r200_swtcl.c
|
||||
*/
|
||||
struct r200_swtcl_info swtcl;
|
||||
|
||||
/* r200_vtxfmt.c
|
||||
*/
|
||||
struct r200_vbinfo vb;
|
||||
};
|
||||
|
||||
#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx))
|
||||
|
||||
extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv);
|
||||
extern GLboolean r200CreateContext(const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPrivate);
|
||||
|
||||
#endif
|
||||
#endif /* __R200_CONTEXT_H__ */
|
||||
204
src/mesa/drivers/dri/r300/r200_ioctl.h
Normal file
204
src/mesa/drivers/dri/r300/r200_ioctl.h
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __R200_IOCTL_H__
|
||||
#define __R200_IOCTL_H__
|
||||
|
||||
#include "simple_list.h"
|
||||
#include "radeon_dri.h"
|
||||
#include "radeon_lock.h"
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
#include "r200_context.h"
|
||||
#include "radeon_drm.h"
|
||||
|
||||
extern void r200EmitState(r200ContextPtr rmesa);
|
||||
extern void r200EmitVertexAOS(r200ContextPtr rmesa,
|
||||
GLuint vertex_size, GLuint offset);
|
||||
|
||||
extern void r200EmitVbufPrim(r200ContextPtr rmesa,
|
||||
GLuint primitive, GLuint vertex_nr);
|
||||
|
||||
extern void r200FlushElts(r200ContextPtr rmesa);
|
||||
|
||||
extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa,
|
||||
GLuint primitive, GLuint min_nr);
|
||||
|
||||
extern void r200EmitAOS(r200ContextPtr rmesa,
|
||||
struct r200_dma_region **regions,
|
||||
GLuint n, GLuint offset);
|
||||
|
||||
extern void r200EmitBlit(r200ContextPtr rmesa,
|
||||
GLuint color_fmt,
|
||||
GLuint src_pitch,
|
||||
GLuint src_offset,
|
||||
GLuint dst_pitch,
|
||||
GLuint dst_offset,
|
||||
GLint srcx, GLint srcy,
|
||||
GLint dstx, GLint dsty, GLuint w, GLuint h);
|
||||
|
||||
extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags);
|
||||
|
||||
extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *);
|
||||
extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller);
|
||||
extern void r200Flush(GLcontext * ctx);
|
||||
|
||||
extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa);
|
||||
|
||||
extern void r200AllocDmaRegion(r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int bytes, int alignment);
|
||||
|
||||
extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
int numverts, int vertsize, int alignment);
|
||||
|
||||
extern void r200ReleaseDmaRegion(r200ContextPtr rmesa,
|
||||
struct r200_dma_region *region,
|
||||
const char *caller);
|
||||
|
||||
extern void r200WaitForVBlank(r200ContextPtr rmesa);
|
||||
extern void r200InitIoctlFuncs(struct dd_function_table *functions);
|
||||
|
||||
extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn,
|
||||
GLsizei size, GLfloat readfreq,
|
||||
GLfloat writefreq, GLfloat priority);
|
||||
extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn,
|
||||
GLvoid * pointer);
|
||||
extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
|
||||
const GLvoid * pointer);
|
||||
|
||||
extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer,
|
||||
GLint size);
|
||||
|
||||
extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa,
|
||||
const GLvoid * pointer);
|
||||
|
||||
void r200SaveHwState(r200ContextPtr radeon);
|
||||
void r200SetUpAtomList(r200ContextPtr rmesa);
|
||||
|
||||
/* ================================================================
|
||||
* Helper macros:
|
||||
*/
|
||||
|
||||
/* Close off the last primitive, if it exists.
|
||||
*/
|
||||
#define R200_NEWPRIM( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->dma.flush ) \
|
||||
rmesa->dma.flush( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
/* Can accomodate several state changes and primitive changes without
|
||||
* actually firing the buffer.
|
||||
*/
|
||||
#define R200_STATECHANGE( rmesa, ATOM ) \
|
||||
do { \
|
||||
R200_NEWPRIM( rmesa ); \
|
||||
rmesa->hw.ATOM.dirty = GL_TRUE; \
|
||||
rmesa->hw.is_dirty = GL_TRUE; \
|
||||
} while (0)
|
||||
|
||||
#define R200_DB_STATE( ATOM ) \
|
||||
memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
|
||||
rmesa->hw.ATOM.cmd_size * 4)
|
||||
|
||||
static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa,
|
||||
struct r200_state_atom *atom)
|
||||
{
|
||||
if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) {
|
||||
int *tmp;
|
||||
R200_NEWPRIM(rmesa);
|
||||
atom->dirty = GL_TRUE;
|
||||
rmesa->hw.is_dirty = GL_TRUE;
|
||||
tmp = atom->cmd;
|
||||
atom->cmd = atom->lastcmd;
|
||||
atom->lastcmd = tmp;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fire the buffered vertices no matter what.
|
||||
*/
|
||||
#define R200_FIREVERTICES( r200 ) \
|
||||
do { \
|
||||
if ( (r200)->store.cmd_used || (r200)->dma.flush ) { \
|
||||
radeonFlush( (r200)->radeon.glCtx ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ
|
||||
* are available, you will also be adding an rmesa->state.max_state_size because
|
||||
* r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
|
||||
*/
|
||||
#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
|
||||
#define VERT_AOS_BUFSZ (5 * sizeof(int))
|
||||
#define ELTS_BUFSZ(nr) (12 + nr * 2)
|
||||
#define VBUF_BUFSZ (3 * sizeof(int))
|
||||
|
||||
/* Ensure that a minimum amount of space is available in the command buffer.
|
||||
* This is used to ensure atomicity of state updates with the rendering requests
|
||||
* that rely on them.
|
||||
*
|
||||
* An alternative would be to implement a "soft lock" such that when the buffer
|
||||
* wraps at an inopportune time, we grab the lock, flush the current buffer,
|
||||
* and hang on to the lock until the critical section is finished and we flush
|
||||
* the buffer again and unlock.
|
||||
*/
|
||||
static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes)
|
||||
{
|
||||
if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
|
||||
r200FlushCmdBuf(rmesa, __FUNCTION__);
|
||||
assert(bytes <= R200_CMD_BUF_SZ);
|
||||
}
|
||||
|
||||
/* Alloc space in the command buffer
|
||||
*/
|
||||
static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa,
|
||||
int bytes, const char *where)
|
||||
{
|
||||
char *head;
|
||||
|
||||
if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
|
||||
r200FlushCmdBuf(rmesa, where);
|
||||
|
||||
head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
|
||||
rmesa->store.cmd_used += bytes;
|
||||
assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ);
|
||||
return head;
|
||||
}
|
||||
|
||||
#endif /* __R200_IOCTL_H__ */
|
||||
1423
src/mesa/drivers/dri/r300/r200_reg.h
Normal file
1423
src/mesa/drivers/dri/r300/r200_reg.h
Normal file
File diff suppressed because it is too large
Load diff
7
src/mesa/drivers/dri/r300/r200_sanity.h
Normal file
7
src/mesa/drivers/dri/r300/r200_sanity.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef R200_SANITY_H
|
||||
#define R200_SANITY_H
|
||||
|
||||
extern int r200SanityCmdBuffer(r200ContextPtr rmesa,
|
||||
int nbox, drm_clip_rect_t * boxes);
|
||||
|
||||
#endif
|
||||
61
src/mesa/drivers/dri/r300/r200_state.h
Normal file
61
src/mesa/drivers/dri/r300/r200_state.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_state.h,v 1.2 2002/11/05 17:46:08 tsi 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 __R200_STATE_H__
|
||||
#define __R200_STATE_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200InitState(r200ContextPtr rmesa);
|
||||
extern void r200InitStateFuncs(struct dd_function_table *functions);
|
||||
extern void r200InitTnlFuncs(GLcontext * ctx);
|
||||
|
||||
extern void r200UpdateMaterial(GLcontext * ctx);
|
||||
|
||||
extern void r200SetCliprects(r200ContextPtr rmesa, GLenum mode);
|
||||
extern void r200RecalcScissorRects(r200ContextPtr rmesa);
|
||||
extern void r200UpdateViewportOffset(GLcontext * ctx);
|
||||
extern void r200UpdateWindow(GLcontext * ctx);
|
||||
|
||||
extern void r200ValidateState(GLcontext * ctx);
|
||||
|
||||
extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg);
|
||||
|
||||
extern void r200LightingSpaceChange(GLcontext * ctx);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
50
src/mesa/drivers/dri/r300/r200_tcl.h
Normal file
50
src/mesa/drivers/dri/r300/r200_tcl.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tcl.h,v 1.2 2002/12/16 16:18:55 dawes 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 __R200_TCL_H__
|
||||
#define __R200_TCL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "r200_context.h"
|
||||
|
||||
extern void r200TclPrimitive(GLcontext * ctx, GLenum prim, int hw_prim);
|
||||
extern void r200EmitEltPrimitive(GLcontext * ctx, GLuint first, GLuint last,
|
||||
GLuint flags);
|
||||
extern void r200EmitPrimitive(GLcontext * ctx, GLuint first, GLuint last,
|
||||
GLuint flags);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
51
src/mesa/drivers/dri/r300/r200_tex.h
Normal file
51
src/mesa/drivers/dri/r300/r200_tex.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_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 __R200_TEX_H__
|
||||
#define __R200_TEX_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void r200UpdateTextureState(GLcontext * ctx);
|
||||
|
||||
extern int r200UploadTexImages(r200ContextPtr rmesa, r200TexObjPtr t,
|
||||
GLuint face);
|
||||
|
||||
extern void r200DestroyTexObj(r200ContextPtr rmesa, r200TexObjPtr t);
|
||||
|
||||
extern void r200InitTextureFuncs(struct dd_function_table *functions);
|
||||
|
||||
#endif
|
||||
#endif /* __R200_TEX_H__ */
|
||||
489
src/mesa/drivers/dri/r300/r300_cmdbuf.c
Normal file
489
src/mesa/drivers/dri/r300/r300_cmdbuf.c
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
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:
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "state.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "simple_list.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
|
||||
|
||||
/**
|
||||
* Send the current command buffer via ioctl to the hardware.
|
||||
*/
|
||||
int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
drm_radeon_cmd_buffer_t cmd;
|
||||
int start;
|
||||
|
||||
if (r300->radeon.lost_context)
|
||||
start = 0;
|
||||
else
|
||||
start = r300->cmdbuf.count_reemit;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL) {
|
||||
fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERBOSE)
|
||||
for (i = start; i < r300->cmdbuf.count_used; ++i)
|
||||
fprintf(stderr, "%d: %08x\n", i,
|
||||
r300->cmdbuf.cmd_buf[i]);
|
||||
}
|
||||
|
||||
LOCK_HARDWARE(&r300->radeon);
|
||||
|
||||
cmd.buf = (char*)(r300->cmdbuf.cmd_buf + start);
|
||||
cmd.bufsz = (r300->cmdbuf.count_used - start) * 4;
|
||||
|
||||
#if 0 // TODO: scissors
|
||||
if (rmesa->state.scissor.enabled) {
|
||||
cmd.nbox = rmesa->state.scissor.numClipRects;
|
||||
cmd.boxes = (drm_clip_rect_t *) rmesa->state.scissor.pClipRects;
|
||||
} else {
|
||||
#endif
|
||||
cmd.nbox = r300->radeon.numClipRects;
|
||||
cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects;
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = drmCommandWrite(r300->radeon.dri.fd,
|
||||
DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
|
||||
if (ret) {
|
||||
UNLOCK_HARDWARE(&r300->radeon);
|
||||
fprintf(stderr, "drmCommandWrite: %d\n", ret);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "Syncing in %s\n\n", __FUNCTION__);
|
||||
radeonWaitForIdleLocked(&r300->radeon);
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE(&r300->radeon);
|
||||
|
||||
r300->cmdbuf.count_used = 0;
|
||||
r300->cmdbuf.count_reemit = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void print_state_atom(struct r300_state_atom *state, int dwords)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr, " emit %s/%d/%d\n", state->name, dwords, state->cmd_size);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERBOSE)
|
||||
for (i = 0; i < dwords; i++)
|
||||
fprintf(stderr, " %s[%d]: %08X\n", state->name, i,
|
||||
state->cmd[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit all atoms with a dirty field equal to dirty.
|
||||
*
|
||||
* The caller must have ensured that there is enough space in the command
|
||||
* buffer.
|
||||
*/
|
||||
static __inline__ void r300DoEmitState(r300ContextPtr r300, GLboolean dirty)
|
||||
{
|
||||
struct r300_state_atom* atom;
|
||||
uint32_t* dest;
|
||||
|
||||
dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_STATE) {
|
||||
foreach(atom, &r300->hw.atomlist) {
|
||||
if ((atom->dirty || r300->hw.all_dirty) == dirty) {
|
||||
int dwords = (*atom->check)(r300, atom);
|
||||
|
||||
if (dwords)
|
||||
print_state_atom(atom, dwords);
|
||||
else
|
||||
fprintf(stderr, " skip state %s\n",
|
||||
atom->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(atom, &r300->hw.atomlist) {
|
||||
if ((atom->dirty || r300->hw.all_dirty) == dirty) {
|
||||
int dwords = (*atom->check)(r300, atom);
|
||||
|
||||
if (dwords) {
|
||||
memcpy(dest, atom->cmd, dwords*4);
|
||||
dest += dwords;
|
||||
r300->cmdbuf.count_used += dwords;
|
||||
atom->dirty = GL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy dirty hardware state atoms into the command buffer.
|
||||
*
|
||||
* We also copy out clean state if we're at the start of a buffer. That makes
|
||||
* it easy to recover from lost contexts.
|
||||
*/
|
||||
void r300EmitState(r300ContextPtr r300)
|
||||
{
|
||||
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (r300->cmdbuf.count_used && !r300->hw.is_dirty && !r300->hw.all_dirty)
|
||||
return;
|
||||
|
||||
/* To avoid going across the entire set of states multiple times, just check
|
||||
* for enough space for the case of emitting all state, and inline the
|
||||
* r300AllocCmdBuf code here without all the checks.
|
||||
*/
|
||||
r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__);
|
||||
|
||||
if (!r300->cmdbuf.count_used) {
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "Begin reemit state\n");
|
||||
|
||||
r300DoEmitState(r300, GL_FALSE);
|
||||
r300->cmdbuf.count_reemit = r300->cmdbuf.count_used;
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "Begin dirty state\n");
|
||||
|
||||
r300DoEmitState(r300, GL_TRUE);
|
||||
|
||||
assert(r300->cmdbuf.count_used < r300->cmdbuf.size);
|
||||
|
||||
r300->hw.is_dirty = GL_FALSE;
|
||||
r300->hw.all_dirty = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#define CHECK( NM, COUNT ) \
|
||||
static int check_##NM( r300ContextPtr r300, \
|
||||
struct r300_state_atom* atom ) \
|
||||
{ \
|
||||
(void) atom; (void) r300; \
|
||||
return (COUNT); \
|
||||
}
|
||||
|
||||
#define ucscount(ptr) (((drm_r300_cmd_header_t*)(ptr))->unchecked_state.count)
|
||||
#define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
|
||||
|
||||
CHECK( always, atom->cmd_size )
|
||||
CHECK( never, 0 )
|
||||
CHECK( variable, ucscount(atom->cmd) ? (1 + ucscount(atom->cmd)) : 0 )
|
||||
CHECK( vpu, vpucount(atom->cmd) ? (1 + vpucount(atom->cmd)*4) : 0 )
|
||||
|
||||
#undef ucscount
|
||||
|
||||
#define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX ) \
|
||||
do { \
|
||||
r300->hw.ATOM.cmd_size = SZ; \
|
||||
r300->hw.ATOM.cmd = (uint32_t*)CALLOC(SZ * sizeof(uint32_t)); \
|
||||
r300->hw.ATOM.name = NM; \
|
||||
r300->hw.ATOM.idx = IDX; \
|
||||
r300->hw.ATOM.check = check_##CHK; \
|
||||
r300->hw.ATOM.dirty = GL_FALSE; \
|
||||
r300->hw.max_state_size += SZ; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Allocate memory for the command buffer and initialize the state atom
|
||||
* list. Note that the initial hardware state is set by r300InitState().
|
||||
*/
|
||||
void r300InitCmdBuf(r300ContextPtr r300)
|
||||
{
|
||||
int size;
|
||||
|
||||
r300->hw.max_state_size = 0;
|
||||
|
||||
/* Initialize state atoms */
|
||||
ALLOC_STATE( vpt, always, R300_VPT_CMDSIZE, "vpt", 0 );
|
||||
r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmducs(R300_SE_VPORT_XSCALE, 6);
|
||||
ALLOC_STATE( unk2080, always, 2, "unk2080", 0 );
|
||||
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( unk2134, always, 3, "unk2134", 0 );
|
||||
r300->hw.unk2134.cmd[0] = cmducs(0x2134, 2);
|
||||
ALLOC_STATE( unk2140, always, 2, "unk2140", 0 );
|
||||
r300->hw.unk2140.cmd[0] = cmducs(0x2140, 1);
|
||||
ALLOC_STATE( vir[0], variable, R300_VIR_CMDSIZE, "vir/0", 0 );
|
||||
r300->hw.vir[0].cmd[R300_VIR_CMD_0] = cmducs(R300_VAP_INPUT_ROUTE_0_0, 1);
|
||||
ALLOC_STATE( vir[1], variable, R300_VIR_CMDSIZE, "vir/1", 1 );
|
||||
r300->hw.vir[1].cmd[R300_VIR_CMD_0] = cmducs(R300_VAP_INPUT_ROUTE_1_0, 1);
|
||||
ALLOC_STATE( vic, always, R300_VIC_CMDSIZE, "vic", 0 );
|
||||
r300->hw.vic.cmd[R300_VIC_CMD_0] = cmducs(R300_VAP_INPUT_CNTL_0, 2);
|
||||
ALLOC_STATE( unk21DC, always, 2, "unk21DC", 0 );
|
||||
r300->hw.unk21DC.cmd[0] = cmducs(0x21DC, 1);
|
||||
ALLOC_STATE( unk221C, always, 2, "unk221C", 0 );
|
||||
r300->hw.unk221C.cmd[0] = cmducs(0x221C, 1);
|
||||
ALLOC_STATE( unk2220, always, 5, "unk2220", 0 );
|
||||
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( 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( 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 );
|
||||
r300->hw.unk4200.cmd[0] = cmducs(0x4200, 4);
|
||||
ALLOC_STATE( unk4214, always, 2, "unk4214", 0 );
|
||||
r300->hw.unk4214.cmd[0] = cmducs(0x4214, 1);
|
||||
ALLOC_STATE( unk4230, always, 4, "unk4230", 0 );
|
||||
r300->hw.unk4230.cmd[0] = cmducs(0x4230, 3);
|
||||
ALLOC_STATE( unk4260, always, 4, "unk4260", 0 );
|
||||
r300->hw.unk4260.cmd[0] = cmducs(0x4260, 3);
|
||||
ALLOC_STATE( unk4274, always, 5, "unk4274", 0 );
|
||||
r300->hw.unk4274.cmd[0] = cmducs(0x4274, 4);
|
||||
ALLOC_STATE( unk4288, always, 6, "unk4288", 0 );
|
||||
r300->hw.unk4288.cmd[0] = cmducs(0x4288, 5);
|
||||
ALLOC_STATE( unk42A0, always, 2, "unk42A0", 0 );
|
||||
r300->hw.unk42A0.cmd[0] = cmducs(0x42A0, 1);
|
||||
ALLOC_STATE( unk42B4, always, 3, "unk42B4", 0 );
|
||||
r300->hw.unk42B4.cmd[0] = cmducs(0x42B4, 2);
|
||||
ALLOC_STATE( unk42C0, always, 3, "unk42C0", 0 );
|
||||
r300->hw.unk42C0.cmd[0] = cmducs(0x42C0, 2);
|
||||
ALLOC_STATE( rc, always, R300_RC_CMDSIZE, "rc", 0 );
|
||||
r300->hw.rc.cmd[R300_RC_CMD_0] = cmducs(R300_RS_CNTL_0, 2);
|
||||
ALLOC_STATE( ri, always, R300_RI_CMDSIZE, "ri", 0 );
|
||||
r300->hw.ri.cmd[R300_RI_CMD_0] = cmducs(R300_RS_INTERP_0, 8);
|
||||
ALLOC_STATE( rr, variable, R300_RR_CMDSIZE, "rr", 0 );
|
||||
r300->hw.rr.cmd[R300_RR_CMD_0] = cmducs(R300_RS_ROUTE_0, 1);
|
||||
ALLOC_STATE( unk43A4, always, 3, "unk43A4", 0 );
|
||||
r300->hw.unk43A4.cmd[0] = cmducs(0x43A4, 2);
|
||||
ALLOC_STATE( unk43E0, always, 4, "unk43E0", 0 );
|
||||
r300->hw.unk43E0.cmd[0] = cmducs(0x43E0, 3);
|
||||
ALLOC_STATE( fp, always, R300_FP_CMDSIZE, "fp", 0 );
|
||||
r300->hw.fp.cmd[R300_FP_CMD_0] = cmducs(R300_PFS_CNTL_0, 3);
|
||||
r300->hw.fp.cmd[R300_FP_CMD_1] = cmducs(R300_PFS_NODE_0, 4);
|
||||
ALLOC_STATE( unk46A4, always, 6, "unk46A4", 0 );
|
||||
r300->hw.unk46A4.cmd[0] = cmducs(0x46A4, 5);
|
||||
ALLOC_STATE( fpi[0], variable, R300_FPI_CMDSIZE, "fpi/0", 0 );
|
||||
r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR0_0, 1);
|
||||
ALLOC_STATE( fpi[1], variable, R300_FPI_CMDSIZE, "fpi/1", 1 );
|
||||
r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR1_0, 1);
|
||||
ALLOC_STATE( fpi[2], variable, R300_FPI_CMDSIZE, "fpi/2", 2 );
|
||||
r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR2_0, 1);
|
||||
ALLOC_STATE( fpi[3], variable, R300_FPI_CMDSIZE, "fpi/3", 3 );
|
||||
r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR3_0, 1);
|
||||
ALLOC_STATE( unk4BC0, always, 2, "unk4BC0", 0 );
|
||||
r300->hw.unk4BC0.cmd[0] = cmducs(0x4BC0, 1);
|
||||
ALLOC_STATE( unk4BC8, always, 4, "unk4BC8", 0 );
|
||||
r300->hw.unk4BC8.cmd[0] = cmducs(0x4BC8, 3);
|
||||
ALLOC_STATE( at, always, R300_AT_CMDSIZE, "at", 0 );
|
||||
r300->hw.at.cmd[R300_AT_CMD_0] = cmducs(R300_PP_ALPHA_TEST, 1);
|
||||
ALLOC_STATE( unk4BD8, always, 2, "unk4BD8", 0 );
|
||||
r300->hw.unk4BD8.cmd[0] = cmducs(0x4BD8, 1);
|
||||
ALLOC_STATE( unk4E00, always, 2, "unk4E00", 0 );
|
||||
r300->hw.unk4E00.cmd[0] = cmducs(0x4E00, 1);
|
||||
ALLOC_STATE( bld, always, R300_BLD_CMDSIZE, "bld", 0 );
|
||||
r300->hw.bld.cmd[R300_BLD_CMD_0] = cmducs(R300_RB3D_CBLEND, 2);
|
||||
ALLOC_STATE( cmk, always, R300_CMK_CMDSIZE, "cmk", 0 );
|
||||
r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmducs(R300_RB3D_COLORMASK, 1);
|
||||
ALLOC_STATE( unk4E10, always, 4, "unk4E10", 0 );
|
||||
r300->hw.unk4E10.cmd[0] = cmducs(0x4E10, 3);
|
||||
ALLOC_STATE( cb, always, R300_CB_CMDSIZE, "cb", 0 );
|
||||
r300->hw.cb.cmd[R300_CB_CMD_0] = cmducs(R300_RB3D_COLOROFFSET0, 1);
|
||||
r300->hw.cb.cmd[R300_CB_CMD_1] = cmducs(R300_RB3D_COLORPITCH0, 1);
|
||||
ALLOC_STATE( unk4E50, always, 10, "unk4E50", 0 );
|
||||
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( 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, 6, "unk4F08", 0 );
|
||||
r300->hw.unk4F08.cmd[0] = cmducs(0x4F08, 5);
|
||||
ALLOC_STATE( zb, always, R300_ZB_CMDSIZE, "zb", 0 );
|
||||
r300->hw.zb.cmd[R300_ZB_CMD_0] = cmducs(R300_RB3D_DEPTHOFFSET, 2);
|
||||
ALLOC_STATE( unk4F28, always, 2, "unk4F28", 0 );
|
||||
r300->hw.unk4F28.cmd[0] = cmducs(0x4F28, 1);
|
||||
ALLOC_STATE( unk4F30, always, 3, "unk4F30", 0 );
|
||||
r300->hw.unk4F30.cmd[0] = cmducs(0x4F30, 2);
|
||||
ALLOC_STATE( unk4F44, always, 2, "unk4F44", 0 );
|
||||
r300->hw.unk4F44.cmd[0] = cmducs(0x4F44, 1);
|
||||
ALLOC_STATE( unk4F54, always, 2, "unk4F54", 0 );
|
||||
r300->hw.unk4F54.cmd[0] = cmducs(0x4F54, 1);
|
||||
|
||||
ALLOC_STATE( vpi, vpu, R300_VPI_CMDSIZE, "vpi", 0 );
|
||||
r300->hw.vpi.cmd[R300_VPI_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PROGRAM, 0);
|
||||
ALLOC_STATE( vpp, vpu, R300_VPP_CMDSIZE, "vpp", 0 );
|
||||
r300->hw.vpp.cmd[R300_VPP_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PARAMETERS, 0);
|
||||
|
||||
/* Setup the atom linked list */
|
||||
make_empty_list(&r300->hw.atomlist);
|
||||
r300->hw.atomlist.name = "atom-list";
|
||||
|
||||
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.unk2134);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2140);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[0]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[1]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vic);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk21DC);
|
||||
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.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.txe);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4200);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4214);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4230);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4260);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4274);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4288);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42A0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42B4);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42C0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.rc);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.ri);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.rr);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk43A4);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk43E0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.fp);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk46A4);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[0]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[1]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[2]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[3]);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC0);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC8);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.at);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BD8);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E00);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.bld);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.cmk);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E10);
|
||||
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.zc);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F08);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.zb);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F28);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F30);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F44);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F54);
|
||||
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vpi);
|
||||
insert_at_tail(&r300->hw.atomlist, &r300->hw.vpp);
|
||||
|
||||
r300->hw.is_dirty = GL_TRUE;
|
||||
r300->hw.all_dirty = GL_TRUE;
|
||||
|
||||
/* Initialize command buffer */
|
||||
size = 256 * driQueryOptioni(&r300->radeon.optionCache, "command_buffer_size");
|
||||
if (size < 2*r300->hw.max_state_size)
|
||||
size = 2*r300->hw.max_state_size;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr,
|
||||
"Allocating %d bytes command buffer (max state is %d bytes)\n",
|
||||
size*4, r300->hw.max_state_size*4);
|
||||
|
||||
r300->cmdbuf.size = size;
|
||||
r300->cmdbuf.cmd_buf = (uint32_t*)CALLOC(size*4);
|
||||
r300->cmdbuf.count_used = 0;
|
||||
r300->cmdbuf.count_reemit = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy the command buffer and state atoms.
|
||||
*/
|
||||
void r300DestroyCmdBuf(r300ContextPtr r300)
|
||||
{
|
||||
struct r300_state_atom* atom;
|
||||
|
||||
FREE(r300->cmdbuf.cmd_buf);
|
||||
|
||||
foreach(atom, &r300->hw.atomlist) {
|
||||
FREE(atom->cmd);
|
||||
}
|
||||
}
|
||||
|
||||
102
src/mesa/drivers/dri/r300/r300_cmdbuf.h
Normal file
102
src/mesa/drivers/dri/r300/r300_cmdbuf.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
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:
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __R300_CMDBUF_H__
|
||||
#define __R300_CMDBUF_H__
|
||||
|
||||
#include "r300_context.h"
|
||||
|
||||
|
||||
extern int r300FlushCmdBuf(r300ContextPtr r300, const char* caller);
|
||||
|
||||
extern void r300EmitState(r300ContextPtr r300);
|
||||
|
||||
extern void r300InitCmdBuf(r300ContextPtr r300);
|
||||
extern void r300DestroyCmdBuf(r300ContextPtr r300);
|
||||
|
||||
|
||||
/**
|
||||
* Make sure that enough space is available in the command buffer
|
||||
* by flushing if necessary.
|
||||
*/
|
||||
static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
|
||||
int dwords, const char* caller)
|
||||
{
|
||||
assert(dwords < r300->cmdbuf.size);
|
||||
|
||||
if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size)
|
||||
r300FlushCmdBuf(r300, caller);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate the given number of dwords in the command buffer and return
|
||||
* a pointer to the allocated area.
|
||||
* When necessary, these functions cause a flush. r300AllocCmdBuf() also
|
||||
* causes state reemission after a flush. This is necessary to ensure
|
||||
* correct hardware state after an unlock.
|
||||
*/
|
||||
static __inline__ uint32_t* r300RawAllocCmdBuf(r300ContextPtr r300,
|
||||
int dwords, const char* caller)
|
||||
{
|
||||
uint32_t* ptr;
|
||||
|
||||
r300EnsureCmdBufSpace(r300, dwords, caller);
|
||||
|
||||
ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
|
||||
r300->cmdbuf.count_used += dwords;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static __inline__ uint32_t* r300AllocCmdBuf(r300ContextPtr r300,
|
||||
int dwords, const char* caller)
|
||||
{
|
||||
uint32_t* ptr;
|
||||
|
||||
r300EnsureCmdBufSpace(r300, dwords, caller);
|
||||
|
||||
if (!r300->cmdbuf.count_used) {
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "Reemit state after flush (from %s)\n",
|
||||
caller);
|
||||
r300EmitState(r300);
|
||||
}
|
||||
|
||||
ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
|
||||
r300->cmdbuf.count_used += dwords;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __R300_CMDBUF_H__ */
|
||||
308
src/mesa/drivers/dri/r300/r300_context.c
Normal file
308
src/mesa/drivers/dri/r300/r300_context.c
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
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>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "api_arrayelt.h"
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "imports.h"
|
||||
#include "matrix.h"
|
||||
#include "extensions.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "array_cache/acache.h"
|
||||
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_span.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "r300_state.h"
|
||||
#include "r300_ioctl.h"
|
||||
|
||||
#include "vblank.h"
|
||||
#include "utils.h"
|
||||
#include "xmlpool.h" /* for symbolic values of enum-type options */
|
||||
|
||||
|
||||
/* Extension strings exported by the R300 driver.
|
||||
*/
|
||||
static const char *const card_extensions[] = {
|
||||
"GL_ARB_multisample",
|
||||
"GL_ARB_multitexture",
|
||||
"GL_ARB_texture_border_clamp",
|
||||
"GL_ARB_texture_compression",
|
||||
"GL_ARB_texture_cube_map",
|
||||
"GL_ARB_texture_env_add",
|
||||
"GL_ARB_texture_env_combine",
|
||||
"GL_ARB_texture_env_dot3",
|
||||
"GL_ARB_texture_mirrored_repeat",
|
||||
"GL_ARB_vertex_buffer_object",
|
||||
"GL_ARB_vertex_program",
|
||||
"GL_EXT_blend_equation_separate",
|
||||
"GL_EXT_blend_func_separate",
|
||||
"GL_EXT_blend_minmax",
|
||||
"GL_EXT_blend_subtract",
|
||||
"GL_EXT_secondary_color",
|
||||
"GL_EXT_stencil_wrap",
|
||||
"GL_EXT_texture_edge_clamp",
|
||||
"GL_EXT_texture_env_combine",
|
||||
"GL_EXT_texture_env_dot3",
|
||||
"GL_EXT_texture_filter_anisotropic",
|
||||
"GL_EXT_texture_lod_bias",
|
||||
"GL_EXT_texture_mirror_clamp",
|
||||
"GL_EXT_texture_rectangle",
|
||||
"GL_ATI_texture_env_combine3",
|
||||
"GL_ATI_texture_mirror_once",
|
||||
"GL_MESA_pack_invert",
|
||||
"GL_MESA_ycbcr_texture",
|
||||
"GL_NV_blend_square",
|
||||
"GL_NV_vertex_program",
|
||||
"GL_SGIS_generate_mipmap",
|
||||
NULL
|
||||
};
|
||||
|
||||
//extern const struct tnl_pipeline_stage _r300_render_stage;
|
||||
//extern const struct tnl_pipeline_stage _r300_tcl_stage;
|
||||
|
||||
static const struct tnl_pipeline_stage *r300_pipeline[] = {
|
||||
|
||||
/* Try and go straight to t&l
|
||||
*/
|
||||
//&_r200_tcl_stage,
|
||||
|
||||
/* Catch any t&l fallbacks
|
||||
*/
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
&_tnl_fog_coordinate_stage,
|
||||
&_tnl_texgen_stage,
|
||||
&_tnl_texture_transform_stage,
|
||||
&_tnl_vertex_program_stage,
|
||||
|
||||
/* Try again to go to tcl?
|
||||
* - no good for asymmetric-twoside (do with multipass)
|
||||
* - no good for asymmetric-unfilled (do with multipass)
|
||||
* - good for material
|
||||
* - good for texgen
|
||||
* - need to manipulate a bit of state
|
||||
*
|
||||
* - worth it/not worth it?
|
||||
*/
|
||||
|
||||
/* Else do them here.
|
||||
*/
|
||||
//&_r300_render_stage,
|
||||
&_tnl_render_stage, /* FALLBACK */
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
/* Create the device specific rendering context.
|
||||
*/
|
||||
GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
|
||||
struct dd_function_table functions;
|
||||
r300ContextPtr r300;
|
||||
GLcontext *ctx;
|
||||
int i;
|
||||
int tcl_mode;
|
||||
|
||||
assert(glVisual);
|
||||
assert(driContextPriv);
|
||||
assert(screen);
|
||||
|
||||
/* Allocate the R300 context */
|
||||
r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
|
||||
if (!r300)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Parse configuration files.
|
||||
* Do this here so that initialMaxAnisotropy is set before we create
|
||||
* the default textures.
|
||||
*/
|
||||
driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
|
||||
screen->driScreen->myNum, "r300");
|
||||
|
||||
/* Init default driver functions then plug in our R300-specific functions
|
||||
* (the texture functions are especially important)
|
||||
*/
|
||||
_mesa_init_driver_functions(&functions);
|
||||
r300InitIoctlFuncs(&functions);
|
||||
//r200InitStateFuncs(&functions);
|
||||
//r200InitTextureFuncs(&functions);
|
||||
|
||||
if (!radeonInitContext(&r300->radeon, &functions,
|
||||
glVisual, driContextPriv, sharedContextPrivate)) {
|
||||
FREE(r300);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Init r300 context data */
|
||||
|
||||
/* Set the maximum texture size small enough that we can guarentee that
|
||||
* all texture units can bind a maximal texture and have them both in
|
||||
* texturable memory at once.
|
||||
*/
|
||||
|
||||
ctx = r300->radeon.glCtx;
|
||||
ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
|
||||
"texture_image_units");
|
||||
ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
|
||||
"texture_coord_units");
|
||||
ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
|
||||
ctx->Const.MaxTextureCoordUnits);
|
||||
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
|
||||
|
||||
/* No wide points.
|
||||
*/
|
||||
ctx->Const.MinPointSize = 1.0;
|
||||
ctx->Const.MinPointSizeAA = 1.0;
|
||||
ctx->Const.MaxPointSize = 1.0;
|
||||
ctx->Const.MaxPointSizeAA = 1.0;
|
||||
|
||||
ctx->Const.MinLineWidth = 1.0;
|
||||
ctx->Const.MinLineWidthAA = 1.0;
|
||||
ctx->Const.MaxLineWidth = 1.0;
|
||||
ctx->Const.MaxLineWidthAA = 1.0;
|
||||
|
||||
/* Initialize the software rasterizer and helper modules.
|
||||
*/
|
||||
_swrast_CreateContext(ctx);
|
||||
_ac_CreateContext(ctx);
|
||||
_tnl_CreateContext(ctx);
|
||||
_swsetup_CreateContext(ctx);
|
||||
_ae_create_context(ctx);
|
||||
|
||||
#if 0
|
||||
/* Install the customized pipeline:
|
||||
*/
|
||||
_tnl_destroy_pipeline(ctx);
|
||||
_tnl_install_pipeline(ctx, r200_pipeline);
|
||||
ctx->Driver.FlushVertices = r200FlushVertices;
|
||||
#endif
|
||||
|
||||
/* Try and keep materials and vertices separate:
|
||||
*/
|
||||
_tnl_isolate_materials(ctx, GL_TRUE);
|
||||
|
||||
/* Configure swrast and TNL to match hardware characteristics:
|
||||
*/
|
||||
_swrast_allow_pixel_fog(ctx, GL_FALSE);
|
||||
_swrast_allow_vertex_fog(ctx, GL_TRUE);
|
||||
_tnl_allow_pixel_fog(ctx, GL_FALSE);
|
||||
_tnl_allow_vertex_fog(ctx, GL_TRUE);
|
||||
|
||||
driInitExtensions(ctx, card_extensions, GL_TRUE);
|
||||
|
||||
radeonInitSpanFuncs(ctx);
|
||||
r300InitCmdBuf(r300);
|
||||
r300InitState(r300);
|
||||
#if 0
|
||||
/* plug in a few more device driver functions */
|
||||
/* XXX these should really go right after _mesa_init_driver_functions() */
|
||||
r200InitPixelFuncs(ctx);
|
||||
r200InitTnlFuncs(ctx);
|
||||
r200InitSwtcl(ctx);
|
||||
#endif
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
|
||||
tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
|
||||
if (1 ||
|
||||
driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
|
||||
fprintf(stderr, "disabling 3D acceleration\n");
|
||||
FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
|
||||
}
|
||||
if (tcl_mode == DRI_CONF_TCL_SW ||
|
||||
!(r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
|
||||
if (r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) {
|
||||
r300->radeon.radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
|
||||
fprintf(stderr, "Disabling HW TCL support\n");
|
||||
}
|
||||
TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Destroy the device specific context.
|
||||
*/
|
||||
void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
|
||||
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
|
||||
|
||||
/* check if we're deleting the currently bound context */
|
||||
if (&r300->radeon == current) {
|
||||
radeonFlush(r300->radeon.glCtx);
|
||||
_mesa_make_current2(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Free r300 context resources */
|
||||
assert(r300); /* should never be null */
|
||||
|
||||
if (r300) {
|
||||
GLboolean release_texture_heaps;
|
||||
|
||||
release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
|
||||
_swsetup_DestroyContext(r300->radeon.glCtx);
|
||||
_tnl_DestroyContext(r300->radeon.glCtx);
|
||||
_ac_DestroyContext(r300->radeon.glCtx);
|
||||
_swrast_DestroyContext(r300->radeon.glCtx);
|
||||
|
||||
r300DestroyCmdBuf(r300);
|
||||
|
||||
/* free the Mesa context */
|
||||
r300->radeon.glCtx->DriverCtx = NULL;
|
||||
_mesa_destroy_context(r300->radeon.glCtx);
|
||||
|
||||
/* free the option cache */
|
||||
driDestroyOptionCache(&r300->radeon.optionCache);
|
||||
|
||||
FREE(r300);
|
||||
}
|
||||
}
|
||||
312
src/mesa/drivers/dri/r300/r300_context.h
Normal file
312
src/mesa/drivers/dri/r300/r300_context.h
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
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>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __R300_CONTEXT_H__
|
||||
#define __R300_CONTEXT_H__
|
||||
|
||||
#include "tnl/t_vertex.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "dri_util.h"
|
||||
#include "texmem.h"
|
||||
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
#include "radeon_context.h"
|
||||
|
||||
struct r300_context;
|
||||
typedef struct r300_context r300ContextRec;
|
||||
typedef struct r300_context *r300ContextPtr;
|
||||
|
||||
#include "radeon_lock.h"
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
static __inline__ uint32_t r300PackFloat32(float fl)
|
||||
{
|
||||
union { float fl; uint32_t u; } u;
|
||||
|
||||
u.fl = fl;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
/**
|
||||
* A block of hardware state.
|
||||
*
|
||||
* When check returns non-zero, the returned number of dwords must be
|
||||
* copied verbatim into the command buffer in order to update a state atom
|
||||
* when it is dirty.
|
||||
*/
|
||||
struct r300_state_atom {
|
||||
struct r300_state_atom *next, *prev;
|
||||
const char* name; /* for debug */
|
||||
int cmd_size; /* maximum size in dwords */
|
||||
GLuint idx; /* index in an array (e.g. textures) */
|
||||
uint32_t* cmd;
|
||||
GLboolean dirty;
|
||||
|
||||
int (*check)(r300ContextPtr, struct r300_state_atom* atom);
|
||||
};
|
||||
|
||||
|
||||
#define R300_VPT_CMD_0 0
|
||||
#define R300_VPT_XSCALE 1
|
||||
#define R300_VPT_XOFFSET 2
|
||||
#define R300_VPT_YSCALE 3
|
||||
#define R300_VPT_YOFFSET 4
|
||||
#define R300_VPT_ZSCALE 5
|
||||
#define R300_VPT_ZOFFSET 6
|
||||
#define R300_VPT_CMDSIZE 7
|
||||
|
||||
#define R300_OVF_CMD_0 0
|
||||
#define R300_OVF_FMT_0 1
|
||||
#define R300_OVF_FMT_1 2
|
||||
#define R300_OVF_CMDSIZE 3
|
||||
|
||||
#define R300_VIR_CMD_0 0 /* vir is variable size (at least 1) */
|
||||
#define R300_VIR_CNTL_0 1
|
||||
#define R300_VIR_CNTL_1 2
|
||||
#define R300_VIR_CNTL_2 3
|
||||
#define R300_VIR_CNTL_3 4
|
||||
#define R300_VIR_CNTL_4 5
|
||||
#define R300_VIR_CNTL_5 6
|
||||
#define R300_VIR_CNTL_6 7
|
||||
#define R300_VIR_CNTL_7 8
|
||||
#define R300_VIR_CMDSIZE 9
|
||||
|
||||
#define R300_VIC_CMD_0 0
|
||||
#define R300_VIC_CNTL_0 1
|
||||
#define R300_VIC_CNTL_1 2
|
||||
#define R300_VIC_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_TXE_CMD_0 0
|
||||
#define R300_TXE_ENABLE 1
|
||||
#define R300_TXE_CMDSIZE 2
|
||||
|
||||
#define R300_RC_CMD_0 0
|
||||
#define R300_RC_CNTL_0 1
|
||||
#define R300_RC_CNTL_1 2
|
||||
#define R300_RC_CMDSIZE 3
|
||||
|
||||
#define R300_RI_CMD_0 0
|
||||
#define R300_RI_INTERP_0 1
|
||||
#define R300_RI_INTERP_1 2
|
||||
#define R300_RI_INTERP_2 3
|
||||
#define R300_RI_INTERP_3 4
|
||||
#define R300_RI_INTERP_4 5
|
||||
#define R300_RI_INTERP_5 6
|
||||
#define R300_RI_INTERP_6 7
|
||||
#define R300_RI_INTERP_7 8
|
||||
#define R300_RI_CMDSIZE 9
|
||||
|
||||
#define R300_RR_CMD_0 0 /* rr is variable size (at least 1) */
|
||||
#define R300_RR_ROUTE_0 1
|
||||
#define R300_RR_ROUTE_1 2
|
||||
#define R300_RR_ROUTE_2 3
|
||||
#define R300_RR_ROUTE_3 4
|
||||
#define R300_RR_ROUTE_4 5
|
||||
#define R300_RR_ROUTE_5 6
|
||||
#define R300_RR_ROUTE_6 7
|
||||
#define R300_RR_ROUTE_7 8
|
||||
#define R300_RR_CMDSIZE 9
|
||||
|
||||
#define R300_FP_CMD_0 0
|
||||
#define R300_FP_CNTL0 1
|
||||
#define R300_FP_CNTL1 2
|
||||
#define R300_FP_CNTL2 3
|
||||
#define R300_FP_CMD_1 4
|
||||
#define R300_FP_NODE0 5
|
||||
#define R300_FP_NODE1 6
|
||||
#define R300_FP_NODE2 7
|
||||
#define R300_FP_NODE3 8
|
||||
#define R300_FP_CMDSIZE 9
|
||||
|
||||
#define R300_FPI_CMD_0 0
|
||||
#define R300_FPI_INSTR_0 1
|
||||
#define R300_FPI_CMDSIZE 65
|
||||
|
||||
#define R300_AT_CMD_0 0
|
||||
#define R300_AT_ALPHA_TEST 1
|
||||
#define R300_AT_CMDSIZE 2
|
||||
|
||||
#define R300_BLD_CMD_0 0
|
||||
#define R300_BLD_CBLEND 1
|
||||
#define R300_BLD_ABLEND 2
|
||||
#define R300_BLD_CMDSIZE 3
|
||||
|
||||
#define R300_CMK_CMD_0 0
|
||||
#define R300_CMK_COLORMASK 1
|
||||
#define R300_CMK_CMDSIZE 2
|
||||
|
||||
#define R300_CB_CMD_0 0
|
||||
#define R300_CB_OFFSET 1
|
||||
#define R300_CB_CMD_1 2
|
||||
#define R300_CB_PITCH 3
|
||||
#define R300_CB_CMDSIZE 4
|
||||
|
||||
#define R300_ZC_CMD_0 0
|
||||
#define R300_ZC_CNTL_0 1
|
||||
#define R300_ZC_CNTL_1 2
|
||||
#define R300_ZC_CMDSIZE 3
|
||||
|
||||
#define R300_ZB_CMD_0 0
|
||||
#define R300_ZB_OFFSET 1
|
||||
#define R300_ZB_PITCH 2
|
||||
#define R300_ZB_CMDSIZE 3
|
||||
|
||||
#define R300_VPI_CMD_0 0
|
||||
#define R300_VPI_INSTR_0 1
|
||||
#define R300_VPI_CMDSIZE 1025 /* 256 16 byte instructions */
|
||||
|
||||
#define R300_VPP_CMD_0 0
|
||||
#define R300_VPP_PARAM_0 1
|
||||
#define R300_VPP_CMDSIZE 1025 /* 256 4-component parameters */
|
||||
|
||||
/**
|
||||
* Cache for hardware register state.
|
||||
*/
|
||||
struct r300_hw_state {
|
||||
struct r300_state_atom atomlist;
|
||||
|
||||
GLboolean is_dirty;
|
||||
GLboolean all_dirty;
|
||||
int max_state_size; /* in dwords */
|
||||
|
||||
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 unk2134; /* (2134) */
|
||||
struct r300_state_atom unk2140; /* (2140) */
|
||||
struct r300_state_atom vir[2]; /* vap input route (2150/21E0) */
|
||||
struct r300_state_atom vic; /* vap input control (2180) */
|
||||
struct r300_state_atom unk21DC; /* (21DC) */
|
||||
struct r300_state_atom unk221C; /* (221C) */
|
||||
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 unk4200; /* (4200) */
|
||||
struct r300_state_atom unk4214; /* (4214) */
|
||||
// what about UNKNOWN_421C? (see r300_reg.h)
|
||||
struct r300_state_atom unk4230; /* (4230) */
|
||||
struct r300_state_atom unk4260; /* (4260) */
|
||||
struct r300_state_atom unk4274; /* (4274) */
|
||||
struct r300_state_atom unk4288; /* (4288) */
|
||||
struct r300_state_atom unk42A0; /* (42A0) */
|
||||
struct r300_state_atom unk42B4; /* (42B4) */
|
||||
struct r300_state_atom unk42C0; /* (42C0) */
|
||||
struct r300_state_atom rc; /* rs control (4300) */
|
||||
struct r300_state_atom ri; /* rs interpolators (4310) */
|
||||
struct r300_state_atom rr; /* rs route (4330) */
|
||||
struct r300_state_atom unk43A4; /* (43A4) */
|
||||
struct r300_state_atom unk43E0; /* (43E0) */
|
||||
struct r300_state_atom fp; /* fragment program cntl + nodes (4600) */
|
||||
struct r300_state_atom unk46A4; /* (46A4) */
|
||||
struct r300_state_atom fpi[4]; /* fp instructions (46C0/47C0/48C0/49C0) */
|
||||
struct r300_state_atom unk4BC0; /* (4BC0) */
|
||||
struct r300_state_atom unk4BC8; /* (4BC8) */
|
||||
struct r300_state_atom at; /* alpha test (4BD4) */
|
||||
struct r300_state_atom unk4BD8; /* (4BD8) */
|
||||
struct r300_state_atom unk4E00; /* (4E00) */
|
||||
struct r300_state_atom bld; /* blending (4E04) */
|
||||
struct r300_state_atom cmk; /* colormask (4E0C) */
|
||||
struct r300_state_atom unk4E10; /* (4E10) */
|
||||
struct r300_state_atom cb; /* colorbuffer (4E28) */
|
||||
struct r300_state_atom unk4E50; /* (4E50) */
|
||||
struct r300_state_atom unk4E88; /* (4E88) */
|
||||
struct r300_state_atom zc; /* z control (4F00) */
|
||||
struct r300_state_atom unk4F08; /* (4F08) */
|
||||
struct r300_state_atom zb; /* z buffer (4F20) */
|
||||
struct r300_state_atom unk4F28; /* (4F28) */
|
||||
struct r300_state_atom unk4F30; /* (4F30) */
|
||||
struct r300_state_atom unk4F44; /* (4F44) */
|
||||
struct r300_state_atom unk4F54; /* (4F54) */
|
||||
|
||||
struct r300_state_atom vpi; /* vp instructions */
|
||||
struct r300_state_atom vpp; /* vp parameters */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This structure holds the command buffer while it is being constructed.
|
||||
*
|
||||
* The first batch of commands in the buffer is always the state that needs
|
||||
* to be re-emitted when the context is lost. This batch can be skipped
|
||||
* otherwise.
|
||||
*/
|
||||
struct r300_cmdbuf {
|
||||
int size; /* DWORDs allocated for buffer */
|
||||
uint32_t* cmd_buf;
|
||||
int count_used; /* DWORDs filled so far */
|
||||
int count_reemit; /* size of re-emission batch */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* State cache
|
||||
*/
|
||||
struct r300_state {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* R300 context structure.
|
||||
*/
|
||||
struct r300_context {
|
||||
struct radeon_context radeon; /* parent class, must be first */
|
||||
|
||||
struct r300_hw_state hw;
|
||||
struct r300_cmdbuf cmdbuf;
|
||||
struct r300_state state;
|
||||
};
|
||||
|
||||
#define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx))
|
||||
|
||||
extern void r300DestroyContext(__DRIcontextPrivate * driContextPriv);
|
||||
extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPrivate);
|
||||
|
||||
#endif /* __R300_CONTEXT_H__ */
|
||||
236
src/mesa/drivers/dri/r300/r300_ioctl.c
Normal file
236
src/mesa/drivers/dri/r300/r300_ioctl.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
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>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r300_cmdbuf.h"
|
||||
#include "r300_state.h"
|
||||
#include "r300_program.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include "vblank.h"
|
||||
|
||||
|
||||
static void r300ClearColorBuffer(r300ContextPtr r300, int buffer)
|
||||
{
|
||||
GLcontext* ctx = r300->radeon.glCtx;
|
||||
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
||||
int i;
|
||||
GLuint cboffset, cbpitch;
|
||||
drm_r300_cmd_header_t* cmd;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s: %s buffer\n", __FUNCTION__,
|
||||
buffer ? "back" : "front");
|
||||
|
||||
if (buffer) {
|
||||
cboffset = r300->radeon.radeonScreen->backOffset;
|
||||
cbpitch = r300->radeon.radeonScreen->backPitch;
|
||||
} else {
|
||||
cboffset = r300->radeon.radeonScreen->frontOffset;
|
||||
cbpitch = r300->radeon.radeonScreen->frontPitch;
|
||||
}
|
||||
cboffset = r300->radeon.radeonScreen->fbLocation;
|
||||
|
||||
R300_STATECHANGE(r300, vpt);
|
||||
r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0);
|
||||
r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x);
|
||||
r300->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(1.0);
|
||||
r300->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(dPriv->y);
|
||||
r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0);
|
||||
r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.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;
|
||||
|
||||
R300_STATECHANGE(r300, unk221C);
|
||||
r300->hw.unk221C.cmd[1] = R300_221C_CLEAR;
|
||||
|
||||
R300_STATECHANGE(r300, ri);
|
||||
for(i = 1; i <= 8; ++i)
|
||||
r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
|
||||
|
||||
R300_STATECHANGE(r300, rr);
|
||||
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
|
||||
r300->hw.rr.cmd[1] = 0x00004000;
|
||||
|
||||
R300_STATECHANGE(r300, fp);
|
||||
r300->hw.fp.cmd[R300_FP_CNTL0] = 0; /* 1 pass, no textures */
|
||||
r300->hw.fp.cmd[R300_FP_CNTL1] = 0; /* no temporaries */
|
||||
r300->hw.fp.cmd[R300_FP_CNTL2] = 0; /* no offset, one ALU instr */
|
||||
r300->hw.fp.cmd[R300_FP_NODE0] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE1] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE2] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE3] = R300_PFS_NODE_LAST_NODE;
|
||||
|
||||
R300_STATECHANGE(r300, fpi[0]);
|
||||
R300_STATECHANGE(r300, fpi[1]);
|
||||
R300_STATECHANGE(r300, fpi[2]);
|
||||
R300_STATECHANGE(r300, fpi[3]);
|
||||
((drm_r300_cmd_header_t*)r300->hw.fpi[0].cmd)->unchecked_state.count = 1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.fpi[1].cmd)->unchecked_state.count = 1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.fpi[2].cmd)->unchecked_state.count = 1;
|
||||
((drm_r300_cmd_header_t*)r300->hw.fpi[3].cmd)->unchecked_state.count = 1;
|
||||
|
||||
/* MOV o0, t0 */
|
||||
r300->hw.fpi[0].cmd[1] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
|
||||
r300->hw.fpi[1].cmd[1] = FP_SELC(0,NO,XYZ,FP_TMP(0),0,0);
|
||||
r300->hw.fpi[2].cmd[1] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
|
||||
r300->hw.fpi[3].cmd[1] = FP_SELA(0,NO,W,FP_TMP(0),0,0);
|
||||
|
||||
R300_STATECHANGE(r300, pvs);
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_1] =
|
||||
(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
|
||||
(0 << R300_PVS_CNTL_1_UNKNOWN_SHIFT) |
|
||||
(1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0; /* no parameters */
|
||||
r300->hw.pvs.cmd[R300_PVS_CNTL_3] =
|
||||
(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
|
||||
|
||||
R300_STATECHANGE(r300, vpi);
|
||||
((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->unchecked_state.count = 8;
|
||||
|
||||
/* MOV o0, i0; */
|
||||
r300->hw.vpi.cmd[1] = VP_OUT(ADD,OUT,0,XYZW);
|
||||
r300->hw.vpi.cmd[2] = VP_IN(IN,0);
|
||||
r300->hw.vpi.cmd[3] = VP_ZERO();
|
||||
r300->hw.vpi.cmd[4] = 0;
|
||||
|
||||
/* MOV o1, i1; */
|
||||
r300->hw.vpi.cmd[5] = VP_OUT(ADD,OUT,1,XYZW);
|
||||
r300->hw.vpi.cmd[6] = VP_IN(IN,1);
|
||||
r300->hw.vpi.cmd[7] = VP_ZERO();
|
||||
r300->hw.vpi.cmd[8] = 0;
|
||||
|
||||
/* Make sure we have enough space */
|
||||
r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9, __FUNCTION__);
|
||||
|
||||
r300EmitState(r300);
|
||||
|
||||
cmd = (drm_r300_cmd_header_t*)r300AllocCmdBuf(r300, 9, __FUNCTION__);
|
||||
cmd[0].packet3.cmd_type = R300_CMD_PACKET3;
|
||||
cmd[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
|
||||
cmd[1].u = r300PackFloat32(dPriv->w / 2.0); /* my guess is as good as yours */
|
||||
cmd[2].u = r300PackFloat32(dPriv->h / 2.0);
|
||||
cmd[3].u = r300PackFloat32(0.0);
|
||||
cmd[4].u = r300PackFloat32(1.0);
|
||||
cmd[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
|
||||
cmd[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
|
||||
cmd[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
|
||||
cmd[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buffer clear
|
||||
*/
|
||||
static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
|
||||
GLint cx, GLint cy, GLint cw, GLint ch)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
||||
int flags = 0;
|
||||
int swapped;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
|
||||
__FUNCTION__, all, cx, cy, cw, ch);
|
||||
|
||||
{
|
||||
LOCK_HARDWARE(&r300->radeon);
|
||||
UNLOCK_HARDWARE(&r300->radeon);
|
||||
if (dPriv->numClipRects == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mask & DD_FRONT_LEFT_BIT) {
|
||||
flags |= DD_FRONT_LEFT_BIT;
|
||||
mask &= ~DD_FRONT_LEFT_BIT;
|
||||
}
|
||||
|
||||
if (mask & DD_BACK_LEFT_BIT) {
|
||||
flags |= DD_BACK_LEFT_BIT;
|
||||
mask &= ~DD_BACK_LEFT_BIT;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
if (RADEON_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "%s: swrast clear, mask: %x\n",
|
||||
__FUNCTION__, mask);
|
||||
_swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
|
||||
}
|
||||
|
||||
swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
|
||||
|
||||
if (flags & DD_FRONT_LEFT_BIT)
|
||||
r300ClearColorBuffer(r300, swapped);
|
||||
|
||||
if (flags & DD_BACK_LEFT_BIT)
|
||||
r300ClearColorBuffer(r300, swapped ^ 1);
|
||||
|
||||
/* Recalculate the hardware set. This could be done more efficiently,
|
||||
* but do keep it like this for now.
|
||||
*/
|
||||
r300ResetHwState(r300);
|
||||
}
|
||||
|
||||
void r300Flush(GLcontext * ctx)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
|
||||
r300FlushCmdBuf(r300, __FUNCTION__);
|
||||
}
|
||||
|
||||
void r300InitIoctlFuncs(struct dd_function_table *functions)
|
||||
{
|
||||
functions->Clear = r300Clear;
|
||||
functions->Finish = radeonFinish;
|
||||
functions->Flush = r300Flush;
|
||||
}
|
||||
42
src/mesa/drivers/dri/r300/r300_ioctl.h
Normal file
42
src/mesa/drivers/dri/r300/r300_ioctl.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
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>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __R300_IOCTL_H__
|
||||
#define __R300_IOCTL_H__
|
||||
|
||||
extern void r300Flush(GLcontext * ctx);
|
||||
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
|
||||
|
||||
#endif /* __R300_IOCTL_H__ */
|
||||
148
src/mesa/drivers/dri/r300/r300_program.h
Normal file
148
src/mesa/drivers/dri/r300/r300_program.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
Copyright (C) 2004 Nicolai Haehnle. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (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:
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __R300_PROGRAM_H__
|
||||
#define __R300_PROGRAM_H__
|
||||
|
||||
#include "r300_reg.h"
|
||||
|
||||
/**
|
||||
* Vertex program helper macros
|
||||
*/
|
||||
|
||||
/* Produce out dword */
|
||||
#define VP_OUTCLASS_TMP R300_VPI_OUT_REG_CLASS_TEMPORARY
|
||||
#define VP_OUTCLASS_OUT R300_VPI_OUT_REG_CLASS_RESULT
|
||||
|
||||
#define VP_OUTMASK_X R300_VPI_OUT_WRITE_X
|
||||
#define VP_OUTMASK_Y R300_VPI_OUT_WRITE_Y
|
||||
#define VP_OUTMASK_Z R300_VPI_OUT_WRITE_Z
|
||||
#define VP_OUTMASK_W R300_VPI_OUT_WRITE_W
|
||||
#define VP_OUTMASK_XY (VP_OUTMASK_X|VP_OUTMASK_Y)
|
||||
#define VP_OUTMASK_XZ (VP_OUTMASK_X|VP_OUTMASK_Z)
|
||||
#define VP_OUTMASK_XW (VP_OUTMASK_X|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_XYZ (VP_OUTMASK_XY|VP_OUTMASK_Z)
|
||||
#define VP_OUTMASK_XYW (VP_OUTMASK_XY|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_XZW (VP_OUTMASK_XZ|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_XYZW (VP_OUTMASK_XYZ|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_YZ (VP_OUTMASK_Y|VP_OUTMASK_Z)
|
||||
#define VP_OUTMASK_YW (VP_OUTMASK_Y|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_YZW (VP_OUTMASK_YZ|VP_OUTMASK_W)
|
||||
#define VP_OUTMASK_ZW (VP_OUTMASK_Z|VP_OUTMASK_W)
|
||||
|
||||
#define VP_OUT(instr,outclass,outidx,outmask) \
|
||||
(R300_VPI_OUT_OP_##instr | \
|
||||
((outidx) << R300_VPI_OUT_REG_INDEX_SHIFT) | \
|
||||
VP_OUTCLASS_##outclass | \
|
||||
VP_OUTMASK_##outmask)
|
||||
|
||||
/* Produce in dword */
|
||||
#define VP_INCLASS_TMP R300_VPI_IN_REG_CLASS_TEMPORARY
|
||||
#define VP_INCLASS_IN R300_VPI_IN_REG_CLASS_ATTRIBUTE
|
||||
#define VP_INCLASS_CONST R300_VPI_IN_REG_CLASS_PARAMETER
|
||||
|
||||
#define VP_IN(class,idx) \
|
||||
(((idx) << R300_VPI_IN_REG_INDEX_SHIFT) | \
|
||||
VP_INCLASS_##class | \
|
||||
(R300_VPI_IN_SELECT_X << R300_VPI_IN_X_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_Y << R300_VPI_IN_Y_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_Z << R300_VPI_IN_Z_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_W << R300_VPI_IN_W_SHIFT))
|
||||
#define VP_ZERO() \
|
||||
((R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_X_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Y_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Z_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_W_SHIFT))
|
||||
#define VP_ONE() \
|
||||
((R300_VPI_IN_SELECT_ONE << R300_VPI_IN_X_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Y_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Z_SHIFT) | \
|
||||
(R300_VPI_IN_SELECT_ONE << R300_VPI_IN_W_SHIFT))
|
||||
|
||||
#define VP_NEG(in,comp) ((in) ^ (R300_VPI_IN_NEG_##comp))
|
||||
#define VP_NEGALL(in,comp) VP_NEG(VP_NEG(VP_NEG(VP_NEG((in),X),Y),Z),W)
|
||||
|
||||
/**
|
||||
* Fragment program helper macros
|
||||
*/
|
||||
|
||||
/* Produce unshifted source selectors */
|
||||
#define FP_TMP(idx) (idx)
|
||||
#define FP_CONST(idx) ((idx) | (1 << 5))
|
||||
|
||||
/* Produce source/dest selector dword */
|
||||
#define FP_SELC_MASK_NO 0
|
||||
#define FP_SELC_MASK_X 1
|
||||
#define FP_SELC_MASK_Y 2
|
||||
#define FP_SELC_MASK_XY 3
|
||||
#define FP_SELC_MASK_Z 4
|
||||
#define FP_SELC_MASK_XZ 5
|
||||
#define FP_SELC_MASK_YZ 6
|
||||
#define FP_SELC_MASK_XYZ 7
|
||||
|
||||
#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
|
||||
(((destidx) << R300_FPI1_DSTC_SHIFT) | \
|
||||
(FP_SELC_MASK_##regmask << 23) | \
|
||||
(FP_SELC_MASK_##outmask << 26) | \
|
||||
((src0) << R300_FPI1_SRC0C_SHIFT) | \
|
||||
((src1) << R300_FPI1_SRC1C_SHIFT) | \
|
||||
((src2) << R300_FPI1_SRC2C_SHIFT))
|
||||
|
||||
#define FP_SELA_MASK_NO 0
|
||||
#define FP_SELA_MASK_W 1
|
||||
|
||||
#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
|
||||
(((destidx) << R300_FPI3_DSTA_SHIFT) | \
|
||||
(FP_SELA_MASK_##regmask << 23) | \
|
||||
(FP_SELA_MASK_##outmask << 24) | \
|
||||
((src0) << R300_FPI3_SRC0A_SHIFT) | \
|
||||
((src1) << R300_FPI3_SRC1A_SHIFT) | \
|
||||
((src2) << R300_FPI3_SRC2A_SHIFT))
|
||||
|
||||
/* Produce unshifted argument selectors */
|
||||
#define FP_ARGC(source) R300_FPI0_ARGC_##source
|
||||
#define FP_ARGA(source) R300_FPI2_ARGA_##source
|
||||
#define FP_ABS(arg) ((arg) | (1 << 6))
|
||||
#define FP_NEG(arg) ((arg) ^ (1 << 5))
|
||||
|
||||
/* Produce instruction dword */
|
||||
#define FP_INSTRC(opcode,arg0,arg1,arg2) \
|
||||
(R300_FPI0_OUTC_##opcode | \
|
||||
((arg0) << R300_FPI0_ARG0C_SHIFT) | \
|
||||
((arg1) << R300_FPI0_ARG1C_SHIFT) | \
|
||||
((arg2) << R300_FPI0_ARG2C_SHIFT))
|
||||
|
||||
#define FP_INSTRA(opcode,arg0,arg1,arg2) \
|
||||
(R300_FPI2_OUTA_##opcode | \
|
||||
((arg0) << R300_FPI2_ARG0A_SHIFT) | \
|
||||
((arg1) << R300_FPI2_ARG1A_SHIFT) | \
|
||||
((arg2) << R300_FPI2_ARG2A_SHIFT))
|
||||
|
||||
#endif /* __R300_PROGRAM_H__ */
|
||||
847
src/mesa/drivers/dri/r300/r300_reg.h
Normal file
847
src/mesa/drivers/dri/r300/r300_reg.h
Normal file
|
|
@ -0,0 +1,847 @@
|
|||
#ifndef _R300_REG_H
|
||||
#define _R300_REG_H
|
||||
|
||||
/*
|
||||
This file contains registers and constants for the R300. They have been
|
||||
found mostly by examining command buffers captured using glxtest, as well
|
||||
as by extrapolating some known registers and constants from the R200.
|
||||
|
||||
I am fairly certain that they are correct unless stated otherwise in comments.
|
||||
*/
|
||||
|
||||
#define R300_SE_VPORT_XSCALE 0x1D98
|
||||
#define R300_SE_VPORT_XOFFSET 0x1D9C
|
||||
#define R300_SE_VPORT_YSCALE 0x1DA0
|
||||
#define R300_SE_VPORT_YOFFSET 0x1DA4
|
||||
#define R300_SE_VPORT_ZSCALE 0x1DA8
|
||||
#define R300_SE_VPORT_ZOFFSET 0x1DAC
|
||||
|
||||
|
||||
// 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_1 0x2094
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
|
||||
# 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
|
||||
|
||||
// BEGIN: Vertex data assembly - lots of uncertainties
|
||||
/* gap */
|
||||
// Where do we get our vertex data?
|
||||
//
|
||||
// Vertex data either comes either from immediate mode registers or from
|
||||
// vertex arrays.
|
||||
// There appears to be no mixed mode (though we can force the pitch of
|
||||
// vertex arrays to 0, effectively reusing the same element over and over
|
||||
// again).
|
||||
//
|
||||
// Immediate mode is controlled by the INPUT_CNTL registers. I am not sure
|
||||
// if these registers influence vertex array processing.
|
||||
//
|
||||
// Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3.
|
||||
//
|
||||
// In both cases, vertex attributes are then passed through INPUT_ROUTE.
|
||||
|
||||
// Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data
|
||||
// into the vertex processor's input registers.
|
||||
// The first word routes the first input, the second word the second, etc.
|
||||
// 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.
|
||||
#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_VAP_INPUT_ROUTE_IDX_SHIFT 8
|
||||
# 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_VAP_INPUT_ROUTE_0_1 0x2154
|
||||
#define R300_VAP_INPUT_ROUTE_0_2 0x2158
|
||||
#define R300_VAP_INPUT_ROUTE_0_3 0x215C
|
||||
|
||||
/* gap */
|
||||
// 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
|
||||
#define R300_VAP_INPUT_CNTL_0 0x2180
|
||||
# define R300_INPUT_CNTL_0_COLOR 0x00000001
|
||||
#define R300_VAP_INPUT_CNTL_1 0x2184
|
||||
# define R300_INPUT_CNTL_POS 0x00000001
|
||||
# define R300_INPUT_CNTL_NORMAL 0x00000002
|
||||
# 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
|
||||
|
||||
/* gap */
|
||||
// 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.
|
||||
#define R300_VAP_INPUT_ROUTE_1_0 0x21E0
|
||||
# define R300_INPUT_ROUTE_SELECT_X 0
|
||||
# define R300_INPUT_ROUTE_SELECT_Y 1
|
||||
# define R300_INPUT_ROUTE_SELECT_Z 2
|
||||
# define R300_INPUT_ROUTE_SELECT_W 3
|
||||
# define R300_INPUT_ROUTE_SELECT_ZERO 4
|
||||
# define R300_INPUT_ROUTE_SELECT_ONE 5
|
||||
# define R300_INPUT_ROUTE_SELECT_MASK 7
|
||||
# define R300_INPUT_ROUTE_X_SHIFT 0
|
||||
# define R300_INPUT_ROUTE_Y_SHIFT 3
|
||||
# define R300_INPUT_ROUTE_Z_SHIFT 6
|
||||
# define R300_INPUT_ROUTE_W_SHIFT 9
|
||||
# define R300_INPUT_ROUTE_ENABLE (15 << 12)
|
||||
#define R300_VAP_INPUT_ROUTE_1_1 0x21E4
|
||||
#define R300_VAP_INPUT_ROUTE_1_2 0x21E8
|
||||
#define R300_VAP_INPUT_ROUTE_1_3 0x21EC
|
||||
|
||||
// END
|
||||
|
||||
/* gap */
|
||||
// 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).
|
||||
//
|
||||
// Pointers into the memory bank are always in multiples of 16 bytes.
|
||||
//
|
||||
// The memory bank is divided into areas with fixed meaning.
|
||||
//
|
||||
// Starting at address UPLOAD_PROGRAM: Vertex program instructions.
|
||||
// Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB),
|
||||
// whereas the difference between known addresses suggests size 512.
|
||||
//
|
||||
// Starting at address UPLOAD_PARAMETERS: Vertex program parameters.
|
||||
// Native reported limits and the VPI layout suggest size 256, whereas
|
||||
// difference between known addresses suggests size 512.
|
||||
//
|
||||
// Multiple vertex programs and parameter sets can be loaded at once,
|
||||
// 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_UNKNOWN 0x00000400
|
||||
/* gap */
|
||||
#define R300_VAP_PVS_UPLOAD_DATA 0x2208
|
||||
// END
|
||||
|
||||
/* gap */
|
||||
// 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.
|
||||
#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
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
/* gap */
|
||||
// Addresses are relative to the vertex program instruction area of the
|
||||
// memory bank. PROGRAM_END points to the last instruction of the active
|
||||
// program
|
||||
//
|
||||
// The meaning of the two UNKNOWN fields is obviously not known. However,
|
||||
// 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.
|
||||
#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.
|
||||
#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
|
||||
|
||||
// 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_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_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?
|
||||
|
||||
/* 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
|
||||
|
||||
/* gap */
|
||||
// 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)
|
||||
# define R300_TX_ENABLE_2 (1 << 2)
|
||||
# define R300_TX_ENABLE_3 (1 << 3)
|
||||
# define R300_TX_ENABLE_4 (1 << 4)
|
||||
# define R300_TX_ENABLE_5 (1 << 5)
|
||||
# define R300_TX_ENABLE_6 (1 << 6)
|
||||
# define R300_TX_ENABLE_7 (1 << 7)
|
||||
# define R300_TX_ENABLE_8 (1 << 8)
|
||||
# define R300_TX_ENABLE_9 (1 << 9)
|
||||
# define R300_TX_ENABLE_10 (1 << 10)
|
||||
# define R300_TX_ENABLE_11 (1 << 11)
|
||||
# define R300_TX_ENABLE_12 (1 << 12)
|
||||
# define R300_TX_ENABLE_13 (1 << 13)
|
||||
# define R300_TX_ENABLE_14 (1 << 14)
|
||||
# define R300_TX_ENABLE_15 (1 << 15)
|
||||
|
||||
// No idea what the purpose is, but it is set to 421C_CLEAR just before
|
||||
// issuing the clear command and then reset to 421C_NORMAL afterwards.
|
||||
#define R300_UNKNOWN_421C 0x421C
|
||||
# define R300_421C_NORMAL 0x00060006
|
||||
# define R300_421C_CLEAR 0x0F000B40
|
||||
|
||||
// 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)
|
||||
#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.
|
||||
#define R300_RS_CNTL_1 0x4304
|
||||
|
||||
/* gap */
|
||||
// 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
|
||||
// texcoord[1], this will be source index 0.
|
||||
// Set INTERP_USED on all interpolators that produce data used by the
|
||||
// fragment program. INTERP_USED looks like a swizzling mask, but
|
||||
// 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.
|
||||
#define R300_RS_INTERP_0 0x4310
|
||||
#define R300_RS_INTERP_1 0x4314
|
||||
# define R300_RS_INTERP_1_UNKNOWN 0x40
|
||||
#define R300_RS_INTERP_2 0x4318
|
||||
# define R300_RS_INTERP_2_UNKNOWN 0x80
|
||||
#define R300_RS_INTERP_3 0x431C
|
||||
# define R300_RS_INTERP_3_UNKNOWN 0xC0
|
||||
#define R300_RS_INTERP_4 0x4320
|
||||
#define R300_RS_INTERP_5 0x4324
|
||||
#define R300_RS_INTERP_6 0x4328
|
||||
#define R300_RS_INTERP_7 0x432C
|
||||
# define R300_RS_INTERP_SRC_SHIFT 2
|
||||
# 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.
|
||||
#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_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_DEST_SHIFT 6
|
||||
# define R300_RS_ROUTE_DEST_MASK (31 << 6) // GUESS
|
||||
|
||||
// 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.
|
||||
# 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
|
||||
|
||||
// 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)
|
||||
#define R300_TX_FILTER_0 0x4400
|
||||
# define R300_TX_REPEAT 0
|
||||
# define R300_TX_CLAMP_TO_EDGE 1
|
||||
# define R300_TX_CLAMP 2
|
||||
# define R300_TX_CLAMP_TO_BORDER 3
|
||||
|
||||
# define R300_TX_WRAP_S_SHIFT 1
|
||||
# define R300_TX_WRAP_S_MASK (3 << 1)
|
||||
# define R300_TX_WRAP_T_SHIFT 4
|
||||
# define R300_TX_WRAP_T_MASK (3 << 4)
|
||||
# define R300_TX_MAG_FILTER_NEAREST (1 << 9)
|
||||
# define R300_TX_MAG_FILTER_LINEAR (2 << 9)
|
||||
# define R300_TX_MAG_FILTER_MASK (3 << 9)
|
||||
# define R300_TX_MIN_FILTER_NEAREST (1 << 11)
|
||||
# define R300_TX_MIN_FILTER_LINEAR (2 << 11)
|
||||
#define R300_TX_UNK1_0 0x4440
|
||||
#define R300_TX_SIZE_0 0x4480
|
||||
# define R300_TX_WIDTHMASK_SHIFT 0
|
||||
# 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_MASK (15 << 26)
|
||||
#define R300_TX_FORMAT_0 0x44C0
|
||||
#define R300_TX_OFFSET_0 0x4540
|
||||
// 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
|
||||
#define R300_TX_UNK4_0 0x4580
|
||||
#define R300_TX_UNK5_0 0x45C0
|
||||
// END
|
||||
|
||||
// BEGIN: Fragment program instruction set
|
||||
// Fragment programs are written directly into register space.
|
||||
// There are separate instruction streams for texture instructions and ALU
|
||||
// instructions.
|
||||
// In order to synchronize these streams, the program is divided into up
|
||||
// to 4 nodes. Each node begins with a number of TEX operations, followed
|
||||
// by a number of ALU operations.
|
||||
// The first node can have zero TEX ops, all subsequent nodes must have at least
|
||||
// one TEX ops.
|
||||
// All nodes must have at least one ALU op.
|
||||
//
|
||||
// The index of the last node is stored in PFS_CNTL_0: A value of 0 means
|
||||
// 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.
|
||||
#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.
|
||||
#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_END_SHIFT 18
|
||||
# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) // GUESS
|
||||
|
||||
/* gap */
|
||||
// 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.
|
||||
#define R300_PFS_NODE_0 0x4610
|
||||
#define R300_PFS_NODE_1 0x4614
|
||||
#define R300_PFS_NODE_2 0x4618
|
||||
#define R300_PFS_NODE_3 0x461C
|
||||
# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0
|
||||
# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0)
|
||||
# define R300_PFS_NODE_ALU_END_SHIFT 6
|
||||
# define R300_PFS_NODE_ALU_END_MASK (63 << 6)
|
||||
# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12
|
||||
# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
|
||||
# define R300_PFS_NODE_TEX_END_SHIFT 17
|
||||
# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
|
||||
# define R300_PFS_NODE_LAST_NODE (1 << 22)
|
||||
|
||||
// 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
|
||||
#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_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
|
||||
|
||||
// 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
|
||||
// native limits.
|
||||
//
|
||||
// The basic functional block seems to be one MAD for each color and alpha,
|
||||
// and an adder that adds all components after the MUL.
|
||||
// - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
|
||||
// - DP4: Use OUTC_DP4, OUTA_DP4
|
||||
// - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
|
||||
// - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
|
||||
// - CMP: If ARG2 < 0, return ARG1, else return ARG0
|
||||
// - FLR: use FRC+MAD
|
||||
// - XPD: use MAD+MAD
|
||||
// - SGE, SLT: use MAD+CMP
|
||||
// - RSQ: use ABS modifier for argument
|
||||
// - Use OUTC_REPL_ALPHA to write results of an alpha-only operation (e.g. RCP)
|
||||
// into color register
|
||||
// - apparently, there's no quick DST operation
|
||||
// - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2"
|
||||
// - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0"
|
||||
// - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1"
|
||||
//
|
||||
// Operand selection
|
||||
// First stage selects three sources from the available registers and
|
||||
// constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha).
|
||||
// fglrx sorts the three source fields: Registers before constants,
|
||||
// lower indices before higher indices; I do not know whether this is necessary.
|
||||
// fglrx fills unused sources with "read constant 0"
|
||||
// According to specs, you cannot select more than two different constants.
|
||||
//
|
||||
// Second stage selects the operands from the sources. This is defined in
|
||||
// INSTR0 (color) and INSTR2 (alpha). You can also select the special constants
|
||||
// zero and one.
|
||||
// Swizzling and negation happens in this stage, as well.
|
||||
//
|
||||
// Important: Color and alpha seem to be mostly separate, i.e. their sources
|
||||
// selection appears to be fully independent (the register storage is probably
|
||||
// physically split into a color and an alpha section).
|
||||
// However (because of the apparent physical split), there is some interaction
|
||||
// WRT swizzling. If, for example, you want to load an R component into an
|
||||
// Alpha operand, this R component is taken from a *color* source, not from
|
||||
// an alpha source. The corresponding register doesn't even have to appear in
|
||||
// the alpha sources list. (I hope this alll makes sense to you)
|
||||
//
|
||||
// Destination selection
|
||||
// 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).
|
||||
// You can write to both at once, or not write at all (the same index
|
||||
// must be used for both).
|
||||
//
|
||||
// Note: There is a special form for LRP
|
||||
// - Argument order is the same as in ARB_fragment_program.
|
||||
// - 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
|
||||
#define R300_PFS_INSTR1_0 0x46C0
|
||||
# define R300_FPI1_SRC0C_SHIFT 0
|
||||
# define R300_FPI1_SRC0C_MASK (31 << 0)
|
||||
# define R300_FPI1_SRC0C_CONST (1 << 5)
|
||||
# define R300_FPI1_SRC1C_SHIFT 6
|
||||
# define R300_FPI1_SRC1C_MASK (31 << 6)
|
||||
# define R300_FPI1_SRC1C_CONST (1 << 11)
|
||||
# define R300_FPI1_SRC2C_SHIFT 12
|
||||
# define R300_FPI1_SRC2C_MASK (31 << 12)
|
||||
# define R300_FPI1_SRC2C_CONST (1 << 17)
|
||||
# define R300_FPI1_DSTC_SHIFT 18
|
||||
# define R300_FPI1_DSTC_MASK (31 << 18)
|
||||
# define R300_FPI1_DSTC_REG_X (1 << 23)
|
||||
# define R300_FPI1_DSTC_REG_Y (1 << 24)
|
||||
# define R300_FPI1_DSTC_REG_Z (1 << 25)
|
||||
# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
|
||||
# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
|
||||
# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
|
||||
|
||||
#define R300_PFS_INSTR3_0 0x47C0
|
||||
# define R300_FPI3_SRC0A_SHIFT 0
|
||||
# define R300_FPI3_SRC0A_MASK (31 << 0)
|
||||
# define R300_FPI3_SRC0A_CONST (1 << 5)
|
||||
# define R300_FPI3_SRC1A_SHIFT 6
|
||||
# define R300_FPI3_SRC1A_MASK (31 << 6)
|
||||
# define R300_FPI3_SRC1A_CONST (1 << 11)
|
||||
# define R300_FPI3_SRC2A_SHIFT 12
|
||||
# define R300_FPI3_SRC2A_MASK (31 << 12)
|
||||
# define R300_FPI3_SRC2A_CONST (1 << 17)
|
||||
# define R300_FPI3_DSTA_SHIFT 18
|
||||
# define R300_FPI3_DSTA_MASK (31 << 18)
|
||||
# define R300_FPI3_DSTA_REG (1 << 23)
|
||||
# define R300_FPI3_DSTA_OUTPUT (1 << 24)
|
||||
|
||||
#define R300_PFS_INSTR0_0 0x48C0
|
||||
# define R300_FPI0_ARGC_SRC0C_XYZ 0
|
||||
# define R300_FPI0_ARGC_SRC0C_XXX 1
|
||||
# define R300_FPI0_ARGC_SRC0C_YYY 2
|
||||
# define R300_FPI0_ARGC_SRC0C_ZZZ 3
|
||||
# define R300_FPI0_ARGC_SRC1C_XYZ 4
|
||||
# define R300_FPI0_ARGC_SRC1C_XXX 5
|
||||
# define R300_FPI0_ARGC_SRC1C_YYY 6
|
||||
# define R300_FPI0_ARGC_SRC1C_ZZZ 7
|
||||
# define R300_FPI0_ARGC_SRC2C_XYZ 8
|
||||
# define R300_FPI0_ARGC_SRC2C_XXX 9
|
||||
# define R300_FPI0_ARGC_SRC2C_YYY 10
|
||||
# define R300_FPI0_ARGC_SRC2C_ZZZ 11
|
||||
# define R300_FPI0_ARGC_SRC0A 12
|
||||
# define R300_FPI0_ARGC_SRC1A 13
|
||||
# define R300_FPI0_ARGC_SRC2A 14
|
||||
# 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_SRC0C_YZX 23
|
||||
# define R300_FPI0_ARGC_SRC1C_YZX 24
|
||||
# define R300_FPI0_ARGC_SRC2C_YZX 25
|
||||
# define R300_FPI0_ARGC_SRC0C_ZXY 26
|
||||
# define R300_FPI0_ARGC_SRC1C_ZXY 27
|
||||
# define R300_FPI0_ARGC_SRC2C_ZXY 28
|
||||
# define R300_FPI0_ARGC_SRC0CA_WZY 29
|
||||
# define R300_FPI0_ARGC_SRC1CA_WZY 30
|
||||
# define R300_FPI0_ARGC_SRC2CA_WZY 31
|
||||
|
||||
# define R300_FPI0_ARG0C_SHIFT 0
|
||||
# define R300_FPI0_ARG0C_MASK (31 << 0)
|
||||
# define R300_FPI0_ARG0C_NEG (1 << 5)
|
||||
# define R300_FPI0_ARG0C_ABS (1 << 6)
|
||||
# define R300_FPI0_ARG1C_SHIFT 7
|
||||
# define R300_FPI0_ARG1C_MASK (31 << 7)
|
||||
# define R300_FPI0_ARG1C_NEG (1 << 12)
|
||||
# define R300_FPI0_ARG1C_ABS (1 << 13)
|
||||
# define R300_FPI0_ARG2C_SHIFT 14
|
||||
# define R300_FPI0_ARG2C_MASK (31 << 14)
|
||||
# define R300_FPI0_ARG2C_NEG (1 << 19)
|
||||
# define R300_FPI0_ARG2C_ABS (1 << 20)
|
||||
# define R300_FPI0_SPECIAL_LRP (1 << 21)
|
||||
# define R300_FPI0_OUTC_MAD (0 << 23)
|
||||
# define R300_FPI0_OUTC_DP3 (1 << 23)
|
||||
# define R300_FPI0_OUTC_DP4 (2 << 23)
|
||||
# define R300_FPI0_OUTC_MIN (4 << 23)
|
||||
# define R300_FPI0_OUTC_MAX (5 << 23)
|
||||
# define R300_FPI0_OUTC_CMP (8 << 23)
|
||||
# define R300_FPI0_OUTC_FRC (9 << 23)
|
||||
# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
|
||||
# define R300_FPI0_OUTC_SAT (1 << 30)
|
||||
# define R300_FPI0_UNKNOWN_31 (1 << 31)
|
||||
|
||||
#define R300_PFS_INSTR2_0 0x49C0
|
||||
# define R300_FPI2_ARGA_SRC0C_X 0
|
||||
# define R300_FPI2_ARGA_SRC0C_Y 1
|
||||
# define R300_FPI2_ARGA_SRC0C_Z 2
|
||||
# define R300_FPI2_ARGA_SRC1C_X 3
|
||||
# define R300_FPI2_ARGA_SRC1C_Y 4
|
||||
# define R300_FPI2_ARGA_SRC1C_Z 5
|
||||
# define R300_FPI2_ARGA_SRC2C_X 6
|
||||
# define R300_FPI2_ARGA_SRC2C_Y 7
|
||||
# define R300_FPI2_ARGA_SRC2C_Z 8
|
||||
# define R300_FPI2_ARGA_SRC0A 9
|
||||
# define R300_FPI2_ARGA_SRC1A 10
|
||||
# define R300_FPI2_ARGA_SRC2A 11
|
||||
# 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_ARG0A_SHIFT 0
|
||||
# define R300_FPI2_ARG0A_MASK (31 << 0)
|
||||
# define R300_FPI2_ARG0A_NEG (1 << 5)
|
||||
# define R300_FPI2_ARG1A_SHIFT 7
|
||||
# define R300_FPI2_ARG1A_MASK (31 << 7)
|
||||
# define R300_FPI2_ARG1A_NEG (1 << 12)
|
||||
# define R300_FPI2_ARG2A_SHIFT 14
|
||||
# define R300_FPI2_AEG2A_MASK (31 << 14)
|
||||
# define R300_FPI2_ARG2A_NEG (1 << 19)
|
||||
# define R300_FPI2_SPECIAL_LRP (1 << 21)
|
||||
# define R300_FPI2_OUTA_MAD (0 << 23)
|
||||
# define R300_FPI2_OUTA_DP4 (1 << 23)
|
||||
# define R300_RPI2_OUTA_MIN (2 << 23)
|
||||
# define R300_RPI2_OUTA_MAX (3 << 23)
|
||||
# define R300_FPI2_OUTA_CMP (6 << 23)
|
||||
# define R300_FPI2_OUTA_FRC (7 << 23)
|
||||
# define R300_FPI2_OUTA_EX2 (8 << 23)
|
||||
# define R300_FPI2_OUTA_LG2 (9 << 23)
|
||||
# define R300_FPI2_OUTA_RCP (10 << 23)
|
||||
# define R300_FPI2_OUTA_RSQ (11 << 23)
|
||||
# define R300_FPI2_OUTA_SAT (1 << 30)
|
||||
# define R300_FPI2_UNKNOWN_31 (1 << 31)
|
||||
// END
|
||||
|
||||
/* gap */
|
||||
#define R300_PP_ALPHA_TEST 0x4BD4
|
||||
# define R300_REF_ALPHA_MASK 0x000000ff
|
||||
# define R300_ALPHA_TEST_FAIL (0 << 8)
|
||||
# define R300_ALPHA_TEST_LESS (1 << 8)
|
||||
# define R300_ALPHA_TEST_LEQUAL (2 << 8)
|
||||
# define R300_ALPHA_TEST_EQUAL (3 << 8)
|
||||
# define R300_ALPHA_TEST_GEQUAL (4 << 8)
|
||||
# define R300_ALPHA_TEST_GREATER (5 << 8)
|
||||
# define R300_ALPHA_TEST_NEQUAL (6 << 8)
|
||||
# define R300_ALPHA_TEST_PASS (7 << 8)
|
||||
# define R300_ALPHA_TEST_OP_MASK (7 << 8)
|
||||
# define R300_ALPHA_TEST_ENABLE (1 << 11)
|
||||
|
||||
/* gap */
|
||||
// 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
|
||||
#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:
|
||||
// - 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
|
||||
#define R300_RB3D_CBLEND 0x4E04
|
||||
#define R300_RB3D_ABLEND 0x4E08
|
||||
/* the following only appear in CBLEND */
|
||||
# define R300_BLEND_ENABLE (1 << 0)
|
||||
# define R300_BLEND_UNKNOWN (3 << 1)
|
||||
# define R300_BLEND_NO_SEPARATE (1 << 3)
|
||||
/* the following are shared between CBLEND and ABLEND */
|
||||
# define R300_FCN_MASK (3 << 12)
|
||||
# define R300_COMB_FCN_ADD_CLAMP (0 << 12)
|
||||
# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12)
|
||||
# define R300_COMB_FCN_SUB_CLAMP (2 << 12)
|
||||
# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12)
|
||||
# define R300_SRC_BLEND_GL_ZERO (32 << 16)
|
||||
# define R300_SRC_BLEND_GL_ONE (33 << 16)
|
||||
# define R300_SRC_BLEND_GL_SRC_COLOR (34 << 16)
|
||||
# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16)
|
||||
# define R300_SRC_BLEND_GL_DST_COLOR (36 << 16)
|
||||
# define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16)
|
||||
# define R300_SRC_BLEND_GL_SRC_ALPHA (38 << 16)
|
||||
# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16)
|
||||
# define R300_SRC_BLEND_GL_DST_ALPHA (40 << 16)
|
||||
# define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16)
|
||||
# define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16)
|
||||
# define R300_SRC_BLEND_MASK (63 << 16)
|
||||
# define R300_DST_BLEND_GL_ZERO (32 << 24)
|
||||
# define R300_DST_BLEND_GL_ONE (33 << 24)
|
||||
# define R300_DST_BLEND_GL_SRC_COLOR (34 << 24)
|
||||
# define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24)
|
||||
# define R300_DST_BLEND_GL_DST_COLOR (36 << 24)
|
||||
# define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24)
|
||||
# define R300_DST_BLEND_GL_SRC_ALPHA (38 << 24)
|
||||
# define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24)
|
||||
# define R300_DST_BLEND_GL_DST_ALPHA (40 << 24)
|
||||
# define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24)
|
||||
# define R300_DST_BLEND_MASK (63 << 24)
|
||||
#define R300_RB3D_COLORMASK 0x4E0C
|
||||
# define R300_COLORMASK0_B (1<<0)
|
||||
# define R300_COLORMASK0_G (1<<1)
|
||||
# define R300_COLORMASK0_R (1<<2)
|
||||
# define R300_COLORMASK0_A (1<<3)
|
||||
|
||||
/* 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
|
||||
/* gap */
|
||||
// Bit 16: Larger tiles
|
||||
// Bit 17: 4x2 tiles
|
||||
// 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
|
||||
|
||||
/* gap */
|
||||
// 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.
|
||||
#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_TEST 0x00000012
|
||||
# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
|
||||
#define R300_RB3D_ZCNTL_1 0x4F04
|
||||
# define R300_RB3D_Z_TEST_NEVER (0 << 0) // GUESS (based on R200)
|
||||
# define R300_RB3D_Z_TEST_LESS (1 << 0)
|
||||
# define R300_RB3D_Z_TEST_LEQUAL (2 << 0)
|
||||
# define R300_RB3D_Z_TEST_EQUAL (3 << 0) // GUESS
|
||||
# define R300_RB3D_Z_TEST_GEQUAL (4 << 0) // GUESS
|
||||
# define R300_RB3D_Z_TEST_GREATER (5 << 0) // GUESS
|
||||
# define R300_RB3D_Z_TEST_NEQUAL (6 << 0)
|
||||
# define R300_RB3D_Z_TEST_ALWAYS (7 << 0)
|
||||
# define R300_RB3D_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
|
||||
|
||||
// BEGIN: Vertex program instruction set
|
||||
// Every instruction is four dwords long:
|
||||
// DWORD 0: output and opcode
|
||||
// DWORD 1: first argument
|
||||
// DWORD 2: second argument
|
||||
// DWORD 3: third argument
|
||||
//
|
||||
// Notes:
|
||||
// - ABS r, a is implemented as MAX r, a, -a
|
||||
// - MOV is implemented as ADD to zero
|
||||
// - XPD is implemented as MUL + MAD
|
||||
// - FLR is implemented as FRC + ADD
|
||||
// - apparently, fglrx tries to schedule instructions so that there is at least
|
||||
// one instruction between the write to a temporary and the first read
|
||||
// from said temporary; however, violations of this scheduling are allowed
|
||||
// - register indices seem to be unrelated with OpenGL aliasing to conventional state
|
||||
// - only one attribute and one parameter can be loaded at a time; however, the
|
||||
// same attribute/parameter can be used for more than one argument
|
||||
// - the second software argument for POW is the third hardware argument (no idea why)
|
||||
// - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
|
||||
//
|
||||
// There is some magic surrounding LIT:
|
||||
// The single argument is replicated across all three inputs, but swizzled:
|
||||
// First argument: xyzy
|
||||
// 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
|
||||
#define R300_VPI_OUT_OP_DOT (1 << 0)
|
||||
#define R300_VPI_OUT_OP_MUL (2 << 0)
|
||||
#define R300_VPI_OUT_OP_ADD (3 << 0)
|
||||
#define R300_VPI_OUT_OP_MAD (4 << 0)
|
||||
#define R300_VPI_OUT_OP_FRC (6 << 0)
|
||||
#define R300_VPI_OUT_OP_MAX (7 << 0)
|
||||
#define R300_VPI_OUT_OP_MIN (8 << 0)
|
||||
#define R300_VPI_OUT_OP_SGE (9 << 0)
|
||||
#define R300_VPI_OUT_OP_SLT (10 << 0)
|
||||
#define R300_VPI_OUT_OP_EXP (65 << 0)
|
||||
#define R300_VPI_OUT_OP_LOG (66 << 0)
|
||||
#define R300_VPI_OUT_OP_LIT (68 << 0)
|
||||
#define R300_VPI_OUT_OP_POW (69 << 0)
|
||||
#define R300_VPI_OUT_OP_RCP (70 << 0)
|
||||
#define R300_VPI_OUT_OP_RSQ (72 << 0)
|
||||
#define R300_VPI_OUT_OP_EX2 (75 << 0)
|
||||
#define R300_VPI_OUT_OP_LG2 (76 << 0)
|
||||
#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
|
||||
|
||||
#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
|
||||
#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
|
||||
#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_WRITE_X (1 << 20)
|
||||
#define R300_VPI_OUT_WRITE_Y (1 << 21)
|
||||
#define R300_VPI_OUT_WRITE_Z (1 << 22)
|
||||
#define R300_VPI_OUT_WRITE_W (1 << 23)
|
||||
|
||||
#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0)
|
||||
#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_INDEX_SHIFT 5
|
||||
#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.
|
||||
// Use the following constants, shifted by the component shift you
|
||||
// want to select
|
||||
#define R300_VPI_IN_SELECT_X 0
|
||||
#define R300_VPI_IN_SELECT_Y 1
|
||||
#define R300_VPI_IN_SELECT_Z 2
|
||||
#define R300_VPI_IN_SELECT_W 3
|
||||
#define R300_VPI_IN_SELECT_ZERO 4
|
||||
#define R300_VPI_IN_SELECT_ONE 5
|
||||
#define R300_VPI_IN_SELECT_MASK 7
|
||||
|
||||
#define R300_VPI_IN_X_SHIFT 13
|
||||
#define R300_VPI_IN_Y_SHIFT 16
|
||||
#define R300_VPI_IN_Z_SHIFT 19
|
||||
#define R300_VPI_IN_W_SHIFT 22
|
||||
|
||||
#define R300_VPI_IN_NEG_X (1 << 25)
|
||||
#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
|
||||
|
||||
#endif // _R300_REG_H
|
||||
329
src/mesa/drivers/dri/r300/r300_state.c
Normal file
329
src/mesa/drivers/dri/r300/r300_state.c
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002.
|
||||
Copyright (C) 2004 Nicolai Haehnle.
|
||||
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:
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "state.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "dd.h"
|
||||
#include "simple_list.h"
|
||||
|
||||
#include "api_arrayelt.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r300_state.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_program.h"
|
||||
|
||||
|
||||
/**
|
||||
* Called by Mesa after an internal state update.
|
||||
*/
|
||||
static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
_swrast_InvalidateState(ctx, new_state);
|
||||
_swsetup_InvalidateState(ctx, new_state);
|
||||
_ac_InvalidateState(ctx, new_state);
|
||||
_tnl_InvalidateState(ctx, new_state);
|
||||
_ae_invalidate_state(ctx, new_state);
|
||||
|
||||
/* Go inefficiency! */
|
||||
r300ResetHwState(r300);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Completely recalculates hardware state based on the Mesa state.
|
||||
*/
|
||||
void r300ResetHwState(r300ContextPtr r300)
|
||||
{
|
||||
int i;
|
||||
|
||||
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 = r300->radeon.glCtx->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_YSCALE] =
|
||||
r300PackFloat32(v[MAT_SZ]);
|
||||
r300->hw.vpt.cmd[R300_VPT_YOFFSET] =
|
||||
r300PackFloat32(v[MAT_TZ]);
|
||||
}
|
||||
|
||||
//BEGIN: TODO
|
||||
r300->hw.unk2080.cmd[1] = 0x0030045A;
|
||||
|
||||
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.unk2134.cmd[1] = 0x00FFFFFF;
|
||||
r300->hw.unk2134.cmd[2] = 0x00000000;
|
||||
|
||||
r300->hw.unk2140.cmd[1] = 0x00000000;
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
|
||||
r300->hw.vir[0].cmd[1] = 0x21030003;
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
|
||||
r300->hw.vir[1].cmd[1] = 0xF688F688;
|
||||
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
|
||||
r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
|
||||
|
||||
r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
|
||||
|
||||
r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
|
||||
|
||||
r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
|
||||
r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
|
||||
r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
|
||||
r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
|
||||
|
||||
if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
|
||||
r300->hw.unk2288.cmd[1] = R300_2288_R300;
|
||||
else
|
||||
r300->hw.unk2288.cmd[1] = R300_2288_RV350;
|
||||
|
||||
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.unk4010.cmd[1] = 0x66666666;
|
||||
r300->hw.unk4010.cmd[2] = 0x06666666;
|
||||
if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
|
||||
r300->hw.unk4010.cmd[3] = 0x00000017;
|
||||
else
|
||||
r300->hw.unk4010.cmd[3] = 0x00000011;
|
||||
r300->hw.unk4010.cmd[4] = 0x00000000;
|
||||
r300->hw.unk4010.cmd[5] = 0x00000000;
|
||||
|
||||
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
|
||||
|
||||
r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
|
||||
r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
|
||||
r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
|
||||
r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
|
||||
|
||||
r300->hw.unk4214.cmd[1] = 0x00050005;
|
||||
|
||||
r300->hw.unk4230.cmd[1] = 0x01800000;
|
||||
r300->hw.unk4230.cmd[2] = 0x00020006;
|
||||
r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
|
||||
|
||||
r300->hw.unk4260.cmd[1] = 0;
|
||||
r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
|
||||
r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
|
||||
|
||||
r300->hw.unk4274.cmd[1] = 0x00000002;
|
||||
r300->hw.unk4274.cmd[2] = 0x0003AAAA;
|
||||
r300->hw.unk4274.cmd[3] = 0x00000000;
|
||||
r300->hw.unk4274.cmd[4] = 0x00000000;
|
||||
|
||||
r300->hw.unk4288.cmd[1] = 0x00000000;
|
||||
r300->hw.unk4288.cmd[2] = 0x00000001;
|
||||
r300->hw.unk4288.cmd[3] = 0x00000000;
|
||||
r300->hw.unk4288.cmd[4] = 0x00000000;
|
||||
r300->hw.unk4288.cmd[5] = 0x00000000;
|
||||
|
||||
r300->hw.unk42A0.cmd[1] = 0x00000000;
|
||||
|
||||
r300->hw.unk42B4.cmd[1] = 0x00000000;
|
||||
r300->hw.unk42B4.cmd[2] = 0x00000000;
|
||||
|
||||
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;
|
||||
|
||||
r300->hw.unk43E0.cmd[1] = 0x00000000;
|
||||
r300->hw.unk43E0.cmd[2] = 0x03FFFFFF;
|
||||
r300->hw.unk43E0.cmd[3] = 0x00FFFFFF;
|
||||
|
||||
r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE0] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE1] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE2] = 0;
|
||||
r300->hw.fp.cmd[R300_FP_NODE3] = 0;
|
||||
|
||||
r300->hw.unk46A4.cmd[1] = 0x00001B01;
|
||||
r300->hw.unk46A4.cmd[2] = 0x00001B0F;
|
||||
r300->hw.unk46A4.cmd[3] = 0x00001B0F;
|
||||
r300->hw.unk46A4.cmd[4] = 0x00001B0F;
|
||||
r300->hw.unk46A4.cmd[5] = 0x00000001;
|
||||
|
||||
for(i = 1; i <= 64; ++i) {
|
||||
/* create NOP instructions */
|
||||
r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
|
||||
r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
|
||||
r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
|
||||
r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
|
||||
}
|
||||
|
||||
r300->hw.unk4BC0.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4BC8.cmd[1] = 0;
|
||||
r300->hw.unk4BC8.cmd[2] = 0;
|
||||
r300->hw.unk4BC8.cmd[3] = 0;
|
||||
|
||||
r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
|
||||
|
||||
r300->hw.unk4BD8.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4E00.cmd[1] = 0;
|
||||
|
||||
r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
|
||||
r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
|
||||
|
||||
r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0xF;
|
||||
|
||||
r300->hw.unk4E10.cmd[1] = 0;
|
||||
r300->hw.unk4E10.cmd[2] = 0;
|
||||
r300->hw.unk4E10.cmd[3] = 0;
|
||||
|
||||
r300->hw.cb.cmd[R300_CB_OFFSET] =
|
||||
r300->radeon.radeonScreen->backOffset +
|
||||
r300->radeon.radeonScreen->fbLocation;
|
||||
r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
|
||||
| R300_COLOR_UNKNOWN_22_23;
|
||||
|
||||
r300->hw.unk4E50.cmd[1] = 0;
|
||||
r300->hw.unk4E50.cmd[2] = 0;
|
||||
r300->hw.unk4E50.cmd[3] = 0;
|
||||
r300->hw.unk4E50.cmd[4] = 0;
|
||||
r300->hw.unk4E50.cmd[5] = 0;
|
||||
r300->hw.unk4E50.cmd[6] = 0;
|
||||
r300->hw.unk4E50.cmd[7] = 0;
|
||||
r300->hw.unk4E50.cmd[8] = 0;
|
||||
r300->hw.unk4E50.cmd[9] = 0;
|
||||
|
||||
r300->hw.unk4E88.cmd[1] = 0;
|
||||
|
||||
r300->hw.zc.cmd[R300_ZC_CNTL_0] = 0;
|
||||
r300->hw.zc.cmd[R300_ZC_CNTL_1] = 0;
|
||||
|
||||
r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
|
||||
r300->hw.unk4F08.cmd[2] = 0x00000002;
|
||||
r300->hw.unk4F08.cmd[3] = 0x00000000;
|
||||
r300->hw.unk4F08.cmd[4] = 0x00000003;
|
||||
r300->hw.unk4F08.cmd[5] = 0x00000000;
|
||||
|
||||
r300->hw.zb.cmd[R300_ZB_OFFSET] =
|
||||
r300->radeon.radeonScreen->depthOffset +
|
||||
r300->radeon.radeonScreen->fbLocation;
|
||||
r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
|
||||
|
||||
r300->hw.unk4F28.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4F30.cmd[1] = 0;
|
||||
r300->hw.unk4F30.cmd[2] = 0;
|
||||
|
||||
r300->hw.unk4F44.cmd[1] = 0;
|
||||
|
||||
r300->hw.unk4F54.cmd[1] = 0;
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
|
||||
for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
|
||||
/* MOV t0, t0 */
|
||||
r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
|
||||
r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
|
||||
r300->hw.vpi.cmd[i+2] = VP_ZERO();
|
||||
r300->hw.vpi.cmd[i+3] = VP_ZERO();
|
||||
}
|
||||
|
||||
((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
|
||||
for(i = 1; i < R300_VPP_CMDSIZE; ++i)
|
||||
r300->hw.vpp.cmd[i] = 0;
|
||||
//END: TODO
|
||||
|
||||
r300->hw.all_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate initial hardware state and register state functions.
|
||||
* Assumes that the command buffer and state atoms have been
|
||||
* initialized already.
|
||||
*/
|
||||
void r300InitState(r300ContextPtr r300)
|
||||
{
|
||||
struct dd_function_table* functions;
|
||||
|
||||
r300ResetHwState(r300);
|
||||
|
||||
/* Setup state functions */
|
||||
functions = &r300->radeon.glCtx->Driver;
|
||||
functions->UpdateState = r300InvalidateState;
|
||||
}
|
||||
|
||||
49
src/mesa/drivers/dri/r300/r300_state.h
Normal file
49
src/mesa/drivers/dri/r300/r300_state.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
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:
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __R300_STATE_H__
|
||||
#define __R300_STATE_H__
|
||||
|
||||
#include "r300_context.h"
|
||||
|
||||
#define R300_STATECHANGE(r300, atom) \
|
||||
do { \
|
||||
r300->hw.atom.dirty = GL_TRUE; \
|
||||
r300->hw.is_dirty = GL_TRUE; \
|
||||
} while(0)
|
||||
|
||||
extern void r300ResetHwState(r300ContextPtr r300);
|
||||
extern void r300InitState(r300ContextPtr r300);
|
||||
|
||||
#endif /* __R300_STATE_H__ */
|
||||
302
src/mesa/drivers/dri/r300/radeon_context.c
Normal file
302
src/mesa/drivers/dri/r300/radeon_context.c
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \file radeon_context.c
|
||||
* Common context initialization.
|
||||
*
|
||||
* \author Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
#include "state.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "radeon_screen.h"
|
||||
#include "r200_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_macros.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "r200_state.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "vblank.h"
|
||||
#include "xmlpool.h" /* for symbolic values of enum-type options */
|
||||
|
||||
#define DRIVER_DATE "20040924"
|
||||
|
||||
|
||||
/* Return various strings for glGetString().
|
||||
*/
|
||||
static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
static char buffer[128];
|
||||
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *) "Tungsten Graphics, Inc.";
|
||||
|
||||
case GL_RENDERER:
|
||||
{
|
||||
unsigned offset;
|
||||
GLuint agp_mode = radeon->radeonScreen->IsPCI ? 0 :
|
||||
radeon->radeonScreen->AGPMode;
|
||||
const char* chipname;
|
||||
|
||||
if (IS_FAMILY_R300(radeon))
|
||||
chipname = "R300";
|
||||
else
|
||||
chipname = "R200";
|
||||
|
||||
offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
|
||||
agp_mode);
|
||||
|
||||
sprintf(&buffer[offset], " %sTCL",
|
||||
!(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
|
||||
? "" : "NO-");
|
||||
|
||||
return (GLubyte *) buffer;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return the width and height of the given buffer.
|
||||
*/
|
||||
static void radeonGetBufferSize(GLframebuffer * buffer,
|
||||
GLuint * width, GLuint * height)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
LOCK_HARDWARE(radeon);
|
||||
*width = radeon->dri.drawable->w;
|
||||
*height = radeon->dri.drawable->h;
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the driver's misc functions.
|
||||
*/
|
||||
static void radeonInitDriverFuncs(struct dd_function_table *functions)
|
||||
{
|
||||
functions->GetBufferSize = radeonGetBufferSize;
|
||||
functions->ResizeBuffers = _swrast_alloc_buffers;
|
||||
functions->GetString = radeonGetString;
|
||||
}
|
||||
|
||||
|
||||
static int get_ust_nop(int64_t * ust)
|
||||
{
|
||||
*ust = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize all common fields of the context,
|
||||
* including the Mesa context itself.
|
||||
*/
|
||||
GLboolean radeonInitContext(radeonContextPtr radeon,
|
||||
struct dd_function_table* functions,
|
||||
const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
|
||||
GLcontext* ctx;
|
||||
GLcontext* shareCtx;
|
||||
int fthrottle_mode;
|
||||
|
||||
/* Fill in additional standard functions. */
|
||||
radeonInitDriverFuncs(functions);
|
||||
|
||||
/* Allocate and initialize the Mesa context */
|
||||
if (sharedContextPrivate)
|
||||
shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
|
||||
else
|
||||
shareCtx = NULL;
|
||||
radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
|
||||
functions, (void *)radeon);
|
||||
if (!radeon->glCtx)
|
||||
return GL_FALSE;
|
||||
|
||||
ctx = radeon->glCtx;
|
||||
driContextPriv->driverPrivate = radeon;
|
||||
|
||||
/* DRI fields */
|
||||
radeon->dri.context = driContextPriv;
|
||||
radeon->dri.screen = sPriv;
|
||||
radeon->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
|
||||
radeon->dri.hwContext = driContextPriv->hHWContext;
|
||||
radeon->dri.hwLock = &sPriv->pSAREA->lock;
|
||||
radeon->dri.fd = sPriv->fd;
|
||||
radeon->dri.drmMinor = sPriv->drmMinor;
|
||||
|
||||
radeon->radeonScreen = screen;
|
||||
radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
|
||||
screen->sarea_priv_offset);
|
||||
|
||||
/* Setup IRQs */
|
||||
fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
|
||||
radeon->iw.irq_seq = -1;
|
||||
radeon->irqsEmitted = 0;
|
||||
radeon->do_irqs = (radeon->dri.drmMinor >= 6 &&
|
||||
fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
|
||||
radeon->radeonScreen->irq);
|
||||
|
||||
radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
|
||||
|
||||
if (!radeon->do_irqs)
|
||||
fprintf(stderr,
|
||||
"IRQ's not enabled, falling back to %s: %d %d %d\n",
|
||||
radeon->do_usleeps ? "usleeps" : "busy waits",
|
||||
radeon->dri.drmMinor,
|
||||
fthrottle_mode, radeon->radeonScreen->irq);
|
||||
|
||||
radeon->vblank_flags = (radeon->radeonScreen->irq != 0)
|
||||
? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ;
|
||||
|
||||
radeon->get_ust =
|
||||
(PFNGLXGETUSTPROC) glXGetProcAddress((const GLubyte *)
|
||||
"__glXGetUST");
|
||||
if (radeon->get_ust == NULL) {
|
||||
radeon->get_ust = get_ust_nop;
|
||||
}
|
||||
(*radeon->get_ust) (&radeon->swap_ust);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swap front and back buffer.
|
||||
*/
|
||||
void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
|
||||
{
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
radeonContextPtr radeon;
|
||||
GLcontext *ctx;
|
||||
|
||||
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
ctx = radeon->glCtx;
|
||||
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
|
||||
if (radeon->doPageFlip) {
|
||||
radeonPageFlip(dPriv);
|
||||
} else {
|
||||
radeonCopyBuffer(dPriv);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* XXX this shouldn't be an error but we can't handle it for now */
|
||||
_mesa_problem(NULL, "%s: drawable has no context!",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Force the context `c' to be the current context and associate with it
|
||||
* buffer `b'.
|
||||
*/
|
||||
GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
|
||||
__DRIdrawablePrivate * driDrawPriv,
|
||||
__DRIdrawablePrivate * driReadPriv)
|
||||
{
|
||||
if (driContextPriv) {
|
||||
radeonContextPtr radeon =
|
||||
(radeonContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
|
||||
radeon->glCtx);
|
||||
|
||||
if (radeon->dri.drawable != driDrawPriv) {
|
||||
driDrawableInitVBlank(driDrawPriv,
|
||||
radeon->vblank_flags);
|
||||
radeon->dri.drawable = driDrawPriv;
|
||||
|
||||
if (IS_FAMILY_R200(radeon)) {
|
||||
r200UpdateWindow(radeon->glCtx);
|
||||
r200UpdateViewportOffset(radeon->glCtx);
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_make_current2(radeon->glCtx,
|
||||
(GLframebuffer *) driDrawPriv->
|
||||
driverPrivate,
|
||||
(GLframebuffer *) driReadPriv->
|
||||
driverPrivate);
|
||||
|
||||
if (!radeon->glCtx->Viewport.Width) {
|
||||
_mesa_set_viewport(radeon->glCtx, 0, 0,
|
||||
driDrawPriv->w, driDrawPriv->h);
|
||||
}
|
||||
|
||||
_mesa_update_state(radeon->glCtx);
|
||||
|
||||
if (IS_FAMILY_R200(radeon))
|
||||
r200ValidateState(radeon->glCtx);
|
||||
|
||||
} else {
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
|
||||
_mesa_make_current(0, 0);
|
||||
}
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "End %s\n", __FUNCTION__);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Force the context `c' to be unbound from its buffer.
|
||||
*/
|
||||
GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
|
||||
{
|
||||
radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
|
||||
radeon->glCtx);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
222
src/mesa/drivers/dri/r300/radeon_context.h
Normal file
222
src/mesa/drivers/dri/r300/radeon_context.h
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
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>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_CONTEXT_H__
|
||||
#define __RADEON_CONTEXT_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "radeon_screen.h"
|
||||
#include "drm.h"
|
||||
#include "dri_util.h"
|
||||
|
||||
struct radeon_context;
|
||||
typedef struct radeon_context radeonContextRec;
|
||||
typedef struct radeon_context* radeonContextPtr;
|
||||
|
||||
static __inline GLuint radeonPackColor(GLuint cpp,
|
||||
GLubyte r, GLubyte g, GLubyte b, GLubyte a)
|
||||
{
|
||||
switch (cpp) {
|
||||
case 2:
|
||||
return PACK_COLOR_565(r, g, b);
|
||||
case 4:
|
||||
return PACK_COLOR_8888(a, r, g, b);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Rasterizing fallbacks */
|
||||
/* See correponding strings in r200_swtcl.c */
|
||||
#define RADEON_FALLBACK_TEXTURE 0x01
|
||||
#define RADEON_FALLBACK_DRAW_BUFFER 0x02
|
||||
#define RADEON_FALLBACK_STENCIL 0x04
|
||||
#define RADEON_FALLBACK_RENDER_MODE 0x08
|
||||
#define RADEON_FALLBACK_BLEND_EQ 0x10
|
||||
#define RADEON_FALLBACK_BLEND_FUNC 0x20
|
||||
#define RADEON_FALLBACK_DISABLE 0x40
|
||||
#define RADEON_FALLBACK_BORDER_MODE 0x80
|
||||
|
||||
extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
|
||||
|
||||
#define FALLBACK( radeon, bit, mode ) do { \
|
||||
if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
|
||||
__FUNCTION__, bit, mode ); \
|
||||
radeonFallback( (radeon)->glCtx, bit, mode ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* TCL fallbacks */
|
||||
extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
|
||||
|
||||
#define RADEON_TCL_FALLBACK_RASTER 0x0001 /* rasterization */
|
||||
#define RADEON_TCL_FALLBACK_UNFILLED 0x0002 /* unfilled tris */
|
||||
#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x0004 /* twoside tris */
|
||||
#define RADEON_TCL_FALLBACK_MATERIAL 0x0008 /* material in vb */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_0 0x0010 /* texgen, unit 0 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_1 0x0020 /* texgen, unit 1 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_2 0x0040 /* texgen, unit 2 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_3 0x0080 /* texgen, unit 3 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_4 0x0100 /* texgen, unit 4 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_5 0x0200 /* texgen, unit 5 */
|
||||
#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x0400 /* user disable */
|
||||
#define RADEON_TCL_FALLBACK_BITMAP 0x0800 /* draw bitmap with points */
|
||||
#define RADEON_TCL_FALLBACK_VERTEX_PROGRAM 0x1000 /* vertex program active */
|
||||
|
||||
#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode )
|
||||
|
||||
|
||||
struct radeon_dri_mirror {
|
||||
__DRIcontextPrivate *context; /* DRI context */
|
||||
__DRIscreenPrivate *screen; /* DRI screen */
|
||||
__DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
|
||||
|
||||
drm_context_t hwContext;
|
||||
drm_hw_lock_t *hwLock;
|
||||
int fd;
|
||||
int drmMinor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derived state for internal purposes.
|
||||
*/
|
||||
struct radeon_colorbuffer_state {
|
||||
GLuint clear;
|
||||
GLint drawOffset, drawPitch;
|
||||
};
|
||||
|
||||
struct radeon_pixel_state {
|
||||
GLint readOffset, readPitch;
|
||||
};
|
||||
|
||||
struct radeon_state {
|
||||
struct radeon_colorbuffer_state color;
|
||||
struct radeon_pixel_state pixel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Common per-context variables shared by R200 and R300.
|
||||
* R200- and R300-specific code "derive" their own context from this
|
||||
* structure.
|
||||
*/
|
||||
struct radeon_context {
|
||||
GLcontext *glCtx; /* Mesa context */
|
||||
radeonScreenPtr radeonScreen; /* Screen private DRI data */
|
||||
|
||||
/* Fallback state */
|
||||
GLuint Fallback;
|
||||
GLuint TclFallback;
|
||||
|
||||
/* Page flipping */
|
||||
GLuint doPageFlip;
|
||||
|
||||
/* Drawable, cliprect and scissor information */
|
||||
GLuint numClipRects; /* Cliprects for the draw buffer */
|
||||
drm_clip_rect_t *pClipRects;
|
||||
unsigned int lastStamp;
|
||||
GLboolean lost_context;
|
||||
drm_radeon_sarea_t *sarea; /* Private SAREA data */
|
||||
|
||||
/* Mirrors of some DRI state */
|
||||
struct radeon_dri_mirror dri;
|
||||
|
||||
/* Busy waiting */
|
||||
GLuint do_usleeps;
|
||||
GLuint do_irqs;
|
||||
GLuint irqsEmitted;
|
||||
drm_radeon_irq_wait_t iw;
|
||||
|
||||
/* VBI / buffer swap */
|
||||
GLuint vbl_seq;
|
||||
GLuint vblank_flags;
|
||||
|
||||
int64_t swap_ust;
|
||||
int64_t swap_missed_ust;
|
||||
|
||||
GLuint swap_count;
|
||||
GLuint swap_missed_count;
|
||||
|
||||
PFNGLXGETUSTPROC get_ust;
|
||||
|
||||
/* Derived state */
|
||||
struct radeon_state state;
|
||||
|
||||
/* Configuration cache
|
||||
*/
|
||||
driOptionCache optionCache;
|
||||
};
|
||||
|
||||
#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx))
|
||||
|
||||
extern void radeonSwapBuffers(__DRIdrawablePrivate * dPriv);
|
||||
extern GLboolean radeonInitContext(radeonContextPtr radeon,
|
||||
struct dd_function_table* functions,
|
||||
const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPrivate);
|
||||
extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
|
||||
__DRIdrawablePrivate * driDrawPriv,
|
||||
__DRIdrawablePrivate * driReadPriv);
|
||||
extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv);
|
||||
|
||||
/* ================================================================
|
||||
* Debugging:
|
||||
*/
|
||||
#define DO_DEBUG 1
|
||||
|
||||
#if DO_DEBUG
|
||||
extern int RADEON_DEBUG;
|
||||
#else
|
||||
#define RADEON_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define DEBUG_TEXTURE 0x0001
|
||||
#define DEBUG_STATE 0x0002
|
||||
#define DEBUG_IOCTL 0x0004
|
||||
#define DEBUG_PRIMS 0x0008
|
||||
#define DEBUG_VERTS 0x0010
|
||||
#define DEBUG_FALLBACKS 0x0020
|
||||
#define DEBUG_VFMT 0x0040
|
||||
#define DEBUG_CODEGEN 0x0080
|
||||
#define DEBUG_VERBOSE 0x0100
|
||||
#define DEBUG_DRI 0x0200
|
||||
#define DEBUG_DMA 0x0400
|
||||
#define DEBUG_SANITY 0x0800
|
||||
#define DEBUG_SYNC 0x1000
|
||||
#define DEBUG_PIXEL 0x2000
|
||||
#define DEBUG_MEMORY 0x4000
|
||||
|
||||
#endif /* __RADEON_CONTEXT_H__ */
|
||||
348
src/mesa/drivers/dri/r300/radeon_ioctl.c
Normal file
348
src/mesa/drivers/dri/r300/radeon_ioctl.c
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "context.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "r200_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "r200_tcl.h"
|
||||
#include "r200_sanity.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include "vblank.h"
|
||||
|
||||
static void radeonWaitForIdle(radeonContextPtr radeon);
|
||||
|
||||
/* ================================================================
|
||||
* SwapBuffers with client-side throttling
|
||||
*/
|
||||
|
||||
static uint32_t radeonGetLastFrame(radeonContextPtr radeon)
|
||||
{
|
||||
drm_radeon_getparam_t gp;
|
||||
int ret;
|
||||
uint32_t frame;
|
||||
|
||||
gp.param = RADEON_PARAM_LAST_FRAME;
|
||||
gp.value = (int *)&frame;
|
||||
ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
|
||||
ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void radeonEmitIrqLocked(radeonContextPtr radeon)
|
||||
{
|
||||
drm_radeon_irq_emit_t ie;
|
||||
int ret;
|
||||
|
||||
ie.irq_seq = &radeon->iw.irq_seq;
|
||||
ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT,
|
||||
&ie, sizeof(ie));
|
||||
if (ret) {
|
||||
fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__,
|
||||
ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonWaitIrq(radeonContextPtr radeon)
|
||||
{
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT,
|
||||
&radeon->iw, sizeof(radeon->iw));
|
||||
} while (ret && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__,
|
||||
ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
|
||||
{
|
||||
drm_radeon_sarea_t *sarea = radeon->sarea;
|
||||
|
||||
if (radeon->do_irqs) {
|
||||
if (radeonGetLastFrame(radeon) < sarea->last_frame) {
|
||||
if (!radeon->irqsEmitted) {
|
||||
while (radeonGetLastFrame(radeon) <
|
||||
sarea->last_frame) ;
|
||||
} else {
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
radeonWaitIrq(radeon);
|
||||
LOCK_HARDWARE(radeon);
|
||||
}
|
||||
radeon->irqsEmitted = 10;
|
||||
}
|
||||
|
||||
if (radeon->irqsEmitted) {
|
||||
radeonEmitIrqLocked(radeon);
|
||||
radeon->irqsEmitted--;
|
||||
}
|
||||
} else {
|
||||
while (radeonGetLastFrame(radeon) < sarea->last_frame) {
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
if (radeon->do_usleeps)
|
||||
DO_USLEEP(1);
|
||||
LOCK_HARDWARE(radeon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the back color buffer to the front color buffer.
|
||||
*/
|
||||
void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
|
||||
{
|
||||
radeonContextPtr radeon;
|
||||
GLint nbox, i, ret;
|
||||
GLboolean missed_target;
|
||||
int64_t ust;
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
assert(dPriv->driContextPriv->driverPrivate);
|
||||
|
||||
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL) {
|
||||
fprintf(stderr, "\n%s( %p )\n\n", __FUNCTION__,
|
||||
(void *)radeon->glCtx);
|
||||
}
|
||||
|
||||
if (IS_FAMILY_R200(radeon))
|
||||
R200_FIREVERTICES((r200ContextPtr)radeon);
|
||||
|
||||
LOCK_HARDWARE(radeon);
|
||||
|
||||
/* Throttle the frame rate -- only allow one pending swap buffers
|
||||
* request at a time.
|
||||
*/
|
||||
radeonWaitForFrameCompletion(radeon);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
|
||||
&missed_target);
|
||||
LOCK_HARDWARE(radeon);
|
||||
|
||||
nbox = dPriv->numClipRects; /* must be in locked region */
|
||||
|
||||
for (i = 0; i < nbox;) {
|
||||
GLint nr = MIN2(i + RADEON_NR_SAREA_CLIPRECTS, nbox);
|
||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||
drm_clip_rect_t *b = radeon->sarea->boxes;
|
||||
GLint n = 0;
|
||||
|
||||
for (; i < nr; i++) {
|
||||
*b++ = box[i];
|
||||
n++;
|
||||
}
|
||||
radeon->sarea->nbox = n;
|
||||
|
||||
ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP);
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n",
|
||||
ret);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
|
||||
if (IS_FAMILY_R200(radeon))
|
||||
((r200ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
|
||||
|
||||
radeon->swap_count++;
|
||||
(*radeon->get_ust) (&ust);
|
||||
if (missed_target) {
|
||||
radeon->swap_missed_count++;
|
||||
radeon->swap_missed_ust = ust - radeon->swap_ust;
|
||||
}
|
||||
|
||||
radeon->swap_ust = ust;
|
||||
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
|
||||
{
|
||||
radeonContextPtr radeon;
|
||||
GLint ret;
|
||||
GLboolean missed_target;
|
||||
|
||||
assert(dPriv);
|
||||
assert(dPriv->driContextPriv);
|
||||
assert(dPriv->driContextPriv->driverPrivate);
|
||||
|
||||
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL) {
|
||||
fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
|
||||
radeon->sarea->pfCurrentPage);
|
||||
}
|
||||
|
||||
if (IS_FAMILY_R200(radeon))
|
||||
R200_FIREVERTICES((r200ContextPtr)radeon);
|
||||
LOCK_HARDWARE(radeon);
|
||||
|
||||
if (!dPriv->numClipRects) {
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
usleep(10000); /* throttle invisible client 10ms */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to do this for the perf box placement:
|
||||
*/
|
||||
{
|
||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||
drm_clip_rect_t *b = radeon->sarea->boxes;
|
||||
b[0] = box[0];
|
||||
radeon->sarea->nbox = 1;
|
||||
}
|
||||
|
||||
/* Throttle the frame rate -- only allow a few pending swap buffers
|
||||
* request at a time.
|
||||
*/
|
||||
radeonWaitForFrameCompletion(radeon);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
|
||||
&missed_target);
|
||||
if (missed_target) {
|
||||
radeon->swap_missed_count++;
|
||||
(void)(*radeon->get_ust) (&radeon->swap_missed_ust);
|
||||
}
|
||||
LOCK_HARDWARE(radeon);
|
||||
|
||||
ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_FLIP);
|
||||
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "DRM_RADEON_FLIP: return = %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
radeon->swap_count++;
|
||||
(void)(*radeon->get_ust) (&radeon->swap_ust);
|
||||
|
||||
if (radeon->sarea->pfCurrentPage == 1) {
|
||||
radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
|
||||
radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
|
||||
} else {
|
||||
radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
|
||||
radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
|
||||
}
|
||||
|
||||
if (IS_FAMILY_R200(radeon)) {
|
||||
r200ContextPtr r200 = (r200ContextPtr)radeon;
|
||||
|
||||
R200_STATECHANGE(r200, ctx);
|
||||
r200->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = radeon->state.color.drawOffset
|
||||
+ radeon->radeonScreen->fbLocation;
|
||||
r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = radeon->state.color.drawPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void radeonWaitForIdleLocked(radeonContextPtr radeon)
|
||||
{
|
||||
int ret;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE);
|
||||
if (ret)
|
||||
DO_USLEEP(1);
|
||||
} while (ret && ++i < 100);
|
||||
|
||||
if (ret < 0) {
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
fprintf(stderr, "Error: R200 timed out... exiting\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonWaitForIdle(radeonContextPtr radeon)
|
||||
{
|
||||
LOCK_HARDWARE(radeon);
|
||||
radeonWaitForIdleLocked(radeon);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
}
|
||||
|
||||
void radeonFlush(GLcontext * ctx)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (IS_FAMILY_R300(radeon))
|
||||
r300Flush(ctx);
|
||||
else
|
||||
r200Flush(ctx);
|
||||
}
|
||||
|
||||
|
||||
/* Make sure all commands have been sent to the hardware and have
|
||||
* completed processing.
|
||||
*/
|
||||
void radeonFinish(GLcontext * ctx)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
radeonFlush(ctx);
|
||||
|
||||
if (radeon->do_irqs) {
|
||||
LOCK_HARDWARE(radeon);
|
||||
radeonEmitIrqLocked(radeon);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
radeonWaitIrq(radeon);
|
||||
} else
|
||||
radeonWaitForIdle(radeon);
|
||||
}
|
||||
53
src/mesa/drivers/dri/r300/radeon_ioctl.h
Normal file
53
src/mesa/drivers/dri/r300/radeon_ioctl.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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 __RADEON_IOCTL_H__
|
||||
#define __RADEON_IOCTL_H__
|
||||
|
||||
#include "simple_list.h"
|
||||
#include "radeon_dri.h"
|
||||
#include "radeon_lock.h"
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
#include "r200_context.h"
|
||||
#include "radeon_drm.h"
|
||||
|
||||
extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable);
|
||||
extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
|
||||
extern void radeonFlush(GLcontext * ctx);
|
||||
extern void radeonFinish(GLcontext * ctx);
|
||||
extern void radeonWaitForIdleLocked(radeonContextPtr radeon);
|
||||
|
||||
#endif /* __RADEON_IOCTL_H__ */
|
||||
159
src/mesa/drivers/dri/r300/radeon_lock.c
Normal file
159
src/mesa/drivers/dri/r300/radeon_lock.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "radeon_lock.h"
|
||||
#include "r200_tex.h"
|
||||
#include "r200_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
|
||||
#if DEBUG_LOCKING
|
||||
char *prevLockFile = NULL;
|
||||
int prevLockLine = 0;
|
||||
#endif
|
||||
|
||||
/* Turn on/off page flipping according to the flags in the sarea:
|
||||
*/
|
||||
static void radeonUpdatePageFlipping(radeonContextPtr radeon)
|
||||
{
|
||||
int use_back;
|
||||
|
||||
radeon->doPageFlip = radeon->sarea->pfState;
|
||||
|
||||
use_back = (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT);
|
||||
use_back ^= (radeon->sarea->pfCurrentPage == 1);
|
||||
|
||||
if (use_back) {
|
||||
radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
|
||||
radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
|
||||
} else {
|
||||
radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
|
||||
radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by radeonGetLock() after the lock has been obtained.
|
||||
*/
|
||||
static void r200RegainedLock(r200ContextPtr r200)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = r200->radeon.dri.drawable;
|
||||
__DRIscreenPrivate *sPriv = r200->radeon.dri.screen;
|
||||
int i;
|
||||
|
||||
if (r200->radeon.lastStamp != dPriv->lastStamp) {
|
||||
radeonUpdatePageFlipping(&r200->radeon);
|
||||
R200_STATECHANGE(r200, ctx);
|
||||
r200->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] =
|
||||
r200->radeon.state.color.drawOffset
|
||||
+ r200->radeon.radeonScreen->fbLocation;
|
||||
r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] =
|
||||
r200->radeon.state.color.drawPitch;
|
||||
|
||||
if (r200->radeon.glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
|
||||
r200SetCliprects(r200, GL_BACK_LEFT);
|
||||
else
|
||||
r200SetCliprects(r200, GL_FRONT_LEFT);
|
||||
r200UpdateViewportOffset(r200->radeon.glCtx);
|
||||
r200->radeon.lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
for (i = 0; i < r200->nr_heaps; i++) {
|
||||
DRI_AGE_TEXTURES(r200->texture_heaps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void r300RegainedLock(radeonContextPtr radeon)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = radeon->dri.drawable;
|
||||
__DRIscreenPrivate *sPriv = radeon->dri.screen;
|
||||
int i;
|
||||
|
||||
if (radeon->lastStamp != dPriv->lastStamp) {
|
||||
radeonUpdatePageFlipping(radeon);
|
||||
|
||||
#if 0
|
||||
if (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
|
||||
r200SetCliprects(r200, GL_BACK_LEFT);
|
||||
else
|
||||
r200SetCliprects(r200, GL_FRONT_LEFT);
|
||||
r200UpdateViewportOffset(r200->radeon.glCtx);
|
||||
#endif
|
||||
radeon->lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < r200->nr_heaps; i++) {
|
||||
DRI_AGE_TEXTURES(r200->texture_heaps[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Update the hardware state. This is called if another context has
|
||||
* grabbed the hardware lock, which includes the X server. This
|
||||
* function also updates the driver's window state after the X server
|
||||
* moves, resizes or restacks a window -- the change will be reflected
|
||||
* in the drawable position and clip rects. Since the X server grabs
|
||||
* the hardware lock when it changes the window state, this routine will
|
||||
* automatically be called after such a change.
|
||||
*/
|
||||
void radeonGetLock(radeonContextPtr radeon, GLuint flags)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = radeon->dri.drawable;
|
||||
__DRIscreenPrivate *sPriv = radeon->dri.screen;
|
||||
drm_radeon_sarea_t *sarea = radeon->sarea;
|
||||
|
||||
drmGetLock(radeon->dri.fd, radeon->dri.hwContext, flags);
|
||||
|
||||
/* The window might have moved, so we might need to get new clip
|
||||
* rects.
|
||||
*
|
||||
* NOTE: This releases and regrabs the hw lock to allow the X server
|
||||
* to respond to the DRI protocol request for new drawable info.
|
||||
* Since the hardware state depends on having the latest drawable
|
||||
* clip rects, all state checking must be done _after_ this call.
|
||||
*/
|
||||
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
|
||||
|
||||
if (sarea->ctx_owner != radeon->dri.hwContext)
|
||||
sarea->ctx_owner = radeon->dri.hwContext;
|
||||
|
||||
if (IS_FAMILY_R300(radeon))
|
||||
r300RegainedLock(radeon);
|
||||
else
|
||||
r200RegainedLock((r200ContextPtr)radeon);
|
||||
|
||||
radeon->lost_context = GL_TRUE;
|
||||
}
|
||||
113
src/mesa/drivers/dri/r300/radeon_lock.h
Normal file
113
src/mesa/drivers/dri/r300/radeon_lock.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
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 __RADEON_LOCK_H__
|
||||
#define __RADEON_LOCK_H__
|
||||
|
||||
#include "r200_ioctl.h"
|
||||
|
||||
extern void radeonGetLock(radeonContextPtr radeon, GLuint flags);
|
||||
|
||||
/* Turn DEBUG_LOCKING on to find locking conflicts.
|
||||
*/
|
||||
#define DEBUG_LOCKING 0
|
||||
|
||||
#if DEBUG_LOCKING
|
||||
extern char *prevLockFile;
|
||||
extern int prevLockLine;
|
||||
|
||||
#define DEBUG_LOCK() \
|
||||
do { \
|
||||
prevLockFile = (__FILE__); \
|
||||
prevLockLine = (__LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_RESET() \
|
||||
do { \
|
||||
prevLockFile = 0; \
|
||||
prevLockLine = 0; \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_CHECK_LOCK() \
|
||||
do { \
|
||||
if ( prevLockFile ) { \
|
||||
fprintf( stderr, \
|
||||
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
|
||||
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
|
||||
exit( 1 ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG_LOCK()
|
||||
#define DEBUG_RESET()
|
||||
#define DEBUG_CHECK_LOCK()
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !!! We may want to separate locks from locks with validation. This
|
||||
* could be used to improve performance for those things commands that
|
||||
* do not do any drawing !!!
|
||||
*/
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
#define LOCK_HARDWARE( radeon ) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DEBUG_CHECK_LOCK(); \
|
||||
DRM_CAS( (radeon)->dri.hwLock, (radeon)->dri.hwContext, \
|
||||
(DRM_LOCK_HELD | (radeon)->dri.hwContext), __ret ); \
|
||||
if ( __ret ) \
|
||||
radeonGetLock( (radeon), 0 ); \
|
||||
DEBUG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_HARDWARE( radeon ) \
|
||||
do { \
|
||||
DRM_UNLOCK( (radeon)->dri.fd, \
|
||||
(radeon)->dri.hwLock, \
|
||||
(radeon)->dri.hwContext ); \
|
||||
DEBUG_RESET(); \
|
||||
if (IS_FAMILY_R200((radeon))) { \
|
||||
r200ContextPtr __r200 = (r200ContextPtr)(radeon); \
|
||||
if (__r200->save_on_next_unlock) \
|
||||
r200SaveHwState( __r200 ); \
|
||||
__r200->save_on_next_unlock = GL_FALSE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* __RADEON_LOCK_H__ */
|
||||
817
src/mesa/drivers/dri/r300/radeon_screen.c
Normal file
817
src/mesa/drivers/dri/r300/radeon_screen.c
Normal file
|
|
@ -0,0 +1,817 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \file radeon_screen.c
|
||||
* Screen initialization functions for the R200 driver.
|
||||
*
|
||||
* \author Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
|
||||
#define STANDALONE_MMIO
|
||||
#include "radeon_screen.h"
|
||||
#include "r200_context.h"
|
||||
#include "r300_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "radeon_macros.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "vblank.h"
|
||||
#include "GL/internal/dri_interface.h"
|
||||
|
||||
/* R200 configuration
|
||||
*/
|
||||
#include "xmlpool.h"
|
||||
|
||||
const char __driR200ConfigOptions[] =
|
||||
DRI_CONF_BEGIN
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
|
||||
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
|
||||
DRI_CONF_MAX_TEXTURE_UNITS(4, 2, 6)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_QUALITY
|
||||
DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
|
||||
DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
|
||||
DRI_CONF_NO_NEG_LOD_BIAS(false)
|
||||
DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
|
||||
DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
|
||||
DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_DEBUG
|
||||
DRI_CONF_NO_RAST(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_SOFTWARE
|
||||
DRI_CONF_ARB_VERTEX_PROGRAM(true)
|
||||
DRI_CONF_NV_VERTEX_PROGRAM(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
static const GLuint __driR200NConfigOptions = 13;
|
||||
|
||||
/* TODO: integrate these into xmlpool.h! */
|
||||
#define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
|
||||
DRI_CONF_OPT_BEGIN_V(texture_image_units,int,def, # min ":" # max ) \
|
||||
DRI_CONF_DESC(en,"Number of texture image units") \
|
||||
DRI_CONF_DESC(de,"Anzahl der Textureinheiten") \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_MAX_TEXTURE_COORD_UNITS(def,min,max) \
|
||||
DRI_CONF_OPT_BEGIN_V(texture_coord_units,int,def, # min ":" # max ) \
|
||||
DRI_CONF_DESC(en,"Number of texture coordinate units") \
|
||||
DRI_CONF_DESC(de,"Anzahl der Texturkoordinateneinheiten") \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
|
||||
DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
|
||||
DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
|
||||
DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
|
||||
const char __driR300ConfigOptions[] =
|
||||
DRI_CONF_BEGIN
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
|
||||
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
|
||||
DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(16, 2, 16)
|
||||
DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
|
||||
DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_QUALITY
|
||||
DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
|
||||
DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
|
||||
DRI_CONF_NO_NEG_LOD_BIAS(false)
|
||||
DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
|
||||
DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
|
||||
DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_DEBUG
|
||||
DRI_CONF_NO_RAST(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
static const GLuint __driR300NConfigOptions = 13;
|
||||
|
||||
|
||||
#ifndef RADEON_DEBUG
|
||||
int RADEON_DEBUG = 0;
|
||||
#endif
|
||||
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{"fall", DEBUG_FALLBACKS},
|
||||
{"tex", DEBUG_TEXTURE},
|
||||
{"ioctl", DEBUG_IOCTL},
|
||||
{"prim", DEBUG_PRIMS},
|
||||
{"vert", DEBUG_VERTS},
|
||||
{"state", DEBUG_STATE},
|
||||
{"code", DEBUG_CODEGEN},
|
||||
{"vfmt", DEBUG_VFMT},
|
||||
{"vtxf", DEBUG_VFMT},
|
||||
{"verb", DEBUG_VERBOSE},
|
||||
{"dri", DEBUG_DRI},
|
||||
{"dma", DEBUG_DMA},
|
||||
{"san", DEBUG_SANITY},
|
||||
{"sync", DEBUG_SYNC},
|
||||
{"pix", DEBUG_PIXEL},
|
||||
{"mem", DEBUG_MEMORY},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
#if 1
|
||||
/* Including xf86PciInfo.h introduces a bunch of errors...
|
||||
*/
|
||||
#define PCI_CHIP_R200_QD 0x5144 /* why do they have r200 names? */
|
||||
#define PCI_CHIP_R200_QE 0x5145 /* Those are all standard radeons */
|
||||
#define PCI_CHIP_R200_QF 0x5146
|
||||
#define PCI_CHIP_R200_QG 0x5147
|
||||
#define PCI_CHIP_R200_QY 0x5159
|
||||
#define PCI_CHIP_R200_QZ 0x515A
|
||||
#define PCI_CHIP_R200_LW 0x4C57
|
||||
#define PCI_CHIP_R200_LY 0x4C59
|
||||
#define PCI_CHIP_R200_LZ 0x4C5A
|
||||
#define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
|
||||
#define PCI_CHIP_RV200_QX 0x5158
|
||||
#define PCI_CHIP_RS100_4136 0x4136 /* IGP RS100, RS200, RS250 are not R200 */
|
||||
#define PCI_CHIP_RS200_4137 0x4137
|
||||
#define PCI_CHIP_RS250_4237 0x4237
|
||||
#define PCI_CHIP_RS100_4336 0x4336
|
||||
#define PCI_CHIP_RS200_4337 0x4337
|
||||
#define PCI_CHIP_RS250_4437 0x4437
|
||||
#define PCI_CHIP_RS300_5834 0x5834 /* All RS300's are R200 */
|
||||
#define PCI_CHIP_RS300_5835 0x5835
|
||||
#define PCI_CHIP_RS300_5836 0x5836
|
||||
#define PCI_CHIP_RS300_5837 0x5837
|
||||
#define PCI_CHIP_R200_BB 0x4242 /* r200 (non-derived) start */
|
||||
#define PCI_CHIP_R200_BC 0x4243
|
||||
#define PCI_CHIP_R200_QH 0x5148
|
||||
#define PCI_CHIP_R200_QI 0x5149
|
||||
#define PCI_CHIP_R200_QJ 0x514A
|
||||
#define PCI_CHIP_R200_QK 0x514B
|
||||
#define PCI_CHIP_R200_QL 0x514C
|
||||
#define PCI_CHIP_R200_QM 0x514D
|
||||
#define PCI_CHIP_R200_QN 0x514E
|
||||
#define PCI_CHIP_R200_QO 0x514F /* r200 (non-derived) end */
|
||||
/* are the R200 Qh (0x5168) and following needed too? They are not in xf86PciInfo.h
|
||||
but in the pci database. Maybe just secondary ports or something ? */
|
||||
|
||||
#define PCI_CHIP_R300_AD 0x4144
|
||||
#define PCI_CHIP_R300_AE 0x4145
|
||||
#define PCI_CHIP_R300_AF 0x4146
|
||||
#define PCI_CHIP_R300_AG 0x4147
|
||||
#define PCI_CHIP_RV350_AP 0x4150
|
||||
#define PCI_CHIP_RV350_NP 0x4E50
|
||||
#define PCI_CHIP_R300_ND 0x4E44
|
||||
#define PCI_CHIP_R300_NE 0x4E45
|
||||
#define PCI_CHIP_R300_NF 0x4E46
|
||||
#define PCI_CHIP_R300_NG 0x4E47
|
||||
#define PCI_CHIP_R350_NH 0x4E48
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_INTERFACE
|
||||
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
|
||||
#endif /* USE_NEW_INTERFACE */
|
||||
|
||||
static radeonScreenPtr __radeonScreen;
|
||||
|
||||
static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo);
|
||||
|
||||
#ifdef USE_NEW_INTERFACE
|
||||
static __GLcontextModes *radeonFillInModes(unsigned pixel_bits,
|
||||
unsigned depth_bits,
|
||||
unsigned stencil_bits,
|
||||
GLboolean have_back_buffer)
|
||||
{
|
||||
__GLcontextModes *modes;
|
||||
__GLcontextModes *m;
|
||||
unsigned num_modes;
|
||||
unsigned depth_buffer_factor;
|
||||
unsigned back_buffer_factor;
|
||||
GLenum fb_format;
|
||||
GLenum fb_type;
|
||||
|
||||
/* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
|
||||
* enough to add support. Basically, if a context is created with an
|
||||
* fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
|
||||
* will never be used.
|
||||
*/
|
||||
static const GLenum back_buffer_modes[] = {
|
||||
GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
|
||||
};
|
||||
|
||||
uint8_t depth_bits_array[2];
|
||||
uint8_t stencil_bits_array[2];
|
||||
|
||||
depth_bits_array[0] = depth_bits;
|
||||
depth_bits_array[1] = depth_bits;
|
||||
|
||||
/* Just like with the accumulation buffer, always provide some modes
|
||||
* with a stencil buffer. It will be a sw fallback, but some apps won't
|
||||
* care about that.
|
||||
*/
|
||||
stencil_bits_array[0] = 0;
|
||||
stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
|
||||
|
||||
depth_buffer_factor = ((depth_bits != 0)
|
||||
|| (stencil_bits != 0)) ? 2 : 1;
|
||||
back_buffer_factor = (have_back_buffer) ? 2 : 1;
|
||||
|
||||
num_modes = depth_buffer_factor * back_buffer_factor * 4;
|
||||
|
||||
if (pixel_bits == 16) {
|
||||
fb_format = GL_RGB;
|
||||
fb_type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
} else {
|
||||
fb_format = GL_BGRA;
|
||||
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
modes = (*create_context_modes) (num_modes, sizeof(__GLcontextModes));
|
||||
m = modes;
|
||||
if (!driFillInModes(&m, fb_format, fb_type,
|
||||
depth_bits_array, stencil_bits_array,
|
||||
depth_buffer_factor, back_buffer_modes,
|
||||
back_buffer_factor, GLX_TRUE_COLOR)) {
|
||||
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
|
||||
__LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!driFillInModes(&m, fb_format, fb_type,
|
||||
depth_bits_array, stencil_bits_array,
|
||||
depth_buffer_factor, back_buffer_modes,
|
||||
back_buffer_factor, GLX_DIRECT_COLOR)) {
|
||||
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
|
||||
__LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Mark the visual as slow if there are "fake" stencil bits.
|
||||
*/
|
||||
for (m = modes; m != NULL; m = m->next) {
|
||||
if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
|
||||
m->visualRating = GLX_SLOW_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
#endif /* USE_NEW_INTERFACE */
|
||||
|
||||
/* Create the device specific screen private data struct.
|
||||
*/
|
||||
static radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate * sPriv)
|
||||
{
|
||||
radeonScreenPtr screen;
|
||||
RADEONDRIPtr dri_priv = (RADEONDRIPtr) sPriv->pDevPriv;
|
||||
unsigned char *RADEONMMIO;
|
||||
|
||||
/* Allocate the private area */
|
||||
screen = (radeonScreenPtr) CALLOC(sizeof(*screen));
|
||||
if (!screen) {
|
||||
__driUtilMessage
|
||||
("%s: Could not allocate memory for screen structure",
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if DO_DEBUG
|
||||
RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
|
||||
#endif
|
||||
|
||||
/* Get family and potential quirks from the PCI device ID.
|
||||
*/
|
||||
switch (dri_priv->deviceID) {
|
||||
case PCI_CHIP_R200_QD:
|
||||
case PCI_CHIP_R200_QE:
|
||||
case PCI_CHIP_R200_QF:
|
||||
case PCI_CHIP_R200_QG:
|
||||
case PCI_CHIP_R200_QY:
|
||||
case PCI_CHIP_R200_QZ:
|
||||
case PCI_CHIP_RV200_QW:
|
||||
case PCI_CHIP_RV200_QX:
|
||||
case PCI_CHIP_R200_LW:
|
||||
case PCI_CHIP_R200_LY:
|
||||
case PCI_CHIP_R200_LZ:
|
||||
case PCI_CHIP_RS100_4136:
|
||||
case PCI_CHIP_RS200_4137:
|
||||
case PCI_CHIP_RS250_4237:
|
||||
case PCI_CHIP_RS100_4336:
|
||||
case PCI_CHIP_RS200_4337:
|
||||
case PCI_CHIP_RS250_4437:
|
||||
__driUtilMessage("radeonCreateScreen(): Device isn't an r200!\n");
|
||||
FREE(screen);
|
||||
return NULL;
|
||||
|
||||
case PCI_CHIP_RS300_5834:
|
||||
case PCI_CHIP_RS300_5835:
|
||||
case PCI_CHIP_RS300_5836:
|
||||
case PCI_CHIP_RS300_5837:
|
||||
screen->chipset = RADEON_CHIP_UNREAL_R200;
|
||||
break;
|
||||
|
||||
case PCI_CHIP_R200_BB:
|
||||
case PCI_CHIP_R200_BC:
|
||||
case PCI_CHIP_R200_QH:
|
||||
case PCI_CHIP_R200_QI:
|
||||
case PCI_CHIP_R200_QJ:
|
||||
case PCI_CHIP_R200_QK:
|
||||
case PCI_CHIP_R200_QL:
|
||||
case PCI_CHIP_R200_QM:
|
||||
case PCI_CHIP_R200_QN:
|
||||
case PCI_CHIP_R200_QO:
|
||||
screen->chipset = RADEON_CHIP_REAL_R200 | RADEON_CHIPSET_TCL;
|
||||
break;
|
||||
|
||||
/* TODO: Check all those chips for the exact flags required.
|
||||
*/
|
||||
case PCI_CHIP_R300_AD:
|
||||
case PCI_CHIP_R300_AE:
|
||||
case PCI_CHIP_R300_AF:
|
||||
case PCI_CHIP_R300_AG:
|
||||
case PCI_CHIP_RV350_AP:
|
||||
case PCI_CHIP_RV350_NP:
|
||||
screen->chipset = RADEON_CHIP_RV350;
|
||||
break;
|
||||
|
||||
case PCI_CHIP_R300_ND: /* confirmed -- nh */
|
||||
case PCI_CHIP_R300_NE:
|
||||
case PCI_CHIP_R300_NF:
|
||||
case PCI_CHIP_R300_NG:
|
||||
case PCI_CHIP_R350_NH:
|
||||
screen->chipset = RADEON_CHIP_R300;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Unknown device ID %04X, please report. Assuming plain R300.\n",
|
||||
dri_priv->deviceID);
|
||||
screen->chipset = RADEON_CHIP_R300;
|
||||
}
|
||||
|
||||
/* Parse configuration */
|
||||
if (GET_CHIP(screen) >= RADEON_CHIP_R300) {
|
||||
driParseOptionInfo(&screen->optionCache,
|
||||
__driR300ConfigOptions, __driR300NConfigOptions);
|
||||
} else {
|
||||
driParseOptionInfo(&screen->optionCache,
|
||||
__driR200ConfigOptions, __driR200NConfigOptions);
|
||||
}
|
||||
|
||||
/* This is first since which regions we map depends on whether or
|
||||
* not we are using a PCI card.
|
||||
*/
|
||||
screen->IsPCI = dri_priv->IsPCI;
|
||||
|
||||
{
|
||||
int ret;
|
||||
drm_radeon_getparam_t gp;
|
||||
|
||||
gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
|
||||
gp.value = &screen->gart_buffer_offset;
|
||||
|
||||
ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE(screen);
|
||||
fprintf(stderr,
|
||||
"drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n",
|
||||
ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sPriv->drmMinor >= 6) {
|
||||
gp.param = RADEON_PARAM_GART_BASE;
|
||||
gp.value = &screen->gart_base;
|
||||
|
||||
ret =
|
||||
drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE(screen);
|
||||
fprintf(stderr,
|
||||
"drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n",
|
||||
ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gp.param = RADEON_PARAM_IRQ_NR;
|
||||
gp.value = &screen->irq;
|
||||
|
||||
ret =
|
||||
drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
FREE(screen);
|
||||
fprintf(stderr,
|
||||
"drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n",
|
||||
ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if kernel module is new enough to support cube maps */
|
||||
screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
|
||||
/* Check if kernel module is new enough to support blend color and
|
||||
separate blend functions/equations */
|
||||
screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
screen->mmio.handle = dri_priv->registerHandle;
|
||||
screen->mmio.size = dri_priv->registerSize;
|
||||
if (drmMap(sPriv->fd,
|
||||
screen->mmio.handle, screen->mmio.size, &screen->mmio.map)) {
|
||||
FREE(screen);
|
||||
__driUtilMessage("%s: drmMap failed\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RADEONMMIO = screen->mmio.map;
|
||||
|
||||
screen->status.handle = dri_priv->statusHandle;
|
||||
screen->status.size = dri_priv->statusSize;
|
||||
if (drmMap(sPriv->fd,
|
||||
screen->status.handle,
|
||||
screen->status.size, &screen->status.map)) {
|
||||
drmUnmap(screen->mmio.map, screen->mmio.size);
|
||||
FREE(screen);
|
||||
__driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
screen->scratch = (__volatile__ uint32_t *)
|
||||
((GLubyte *) screen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
||||
|
||||
screen->buffers = drmMapBufs(sPriv->fd);
|
||||
if (!screen->buffers) {
|
||||
drmUnmap(screen->status.map, screen->status.size);
|
||||
drmUnmap(screen->mmio.map, screen->mmio.size);
|
||||
FREE(screen);
|
||||
__driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dri_priv->gartTexHandle && dri_priv->gartTexMapSize) {
|
||||
|
||||
screen->gartTextures.handle = dri_priv->gartTexHandle;
|
||||
screen->gartTextures.size = dri_priv->gartTexMapSize;
|
||||
if (drmMap(sPriv->fd,
|
||||
screen->gartTextures.handle,
|
||||
screen->gartTextures.size,
|
||||
(drmAddressPtr) & screen->gartTextures.map)) {
|
||||
drmUnmapBufs(screen->buffers);
|
||||
drmUnmap(screen->status.map, screen->status.size);
|
||||
drmUnmap(screen->mmio.map, screen->mmio.size);
|
||||
FREE(screen);
|
||||
__driUtilMessage
|
||||
("%s: drmMAP failed for GART texture area\n",
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->gart_texture_offset =
|
||||
dri_priv->gartTexOffset +
|
||||
(screen->IsPCI ? INREG(RADEON_AIC_LO_ADDR)
|
||||
: ((INREG(RADEON_MC_AGP_LOCATION) & 0x0ffffU) << 16));
|
||||
}
|
||||
|
||||
screen->cpp = dri_priv->bpp / 8;
|
||||
screen->AGPMode = dri_priv->AGPMode;
|
||||
|
||||
screen->fbLocation = (INREG(RADEON_MC_FB_LOCATION) & 0xffff) << 16;
|
||||
|
||||
if (sPriv->drmMinor >= 10) {
|
||||
drm_radeon_setparam_t sp;
|
||||
|
||||
sp.param = RADEON_SETPARAM_FB_LOCATION;
|
||||
sp.value = screen->fbLocation;
|
||||
|
||||
drmCommandWrite(sPriv->fd, DRM_RADEON_SETPARAM,
|
||||
&sp, sizeof(sp));
|
||||
}
|
||||
|
||||
screen->frontOffset = dri_priv->frontOffset;
|
||||
screen->frontPitch = dri_priv->frontPitch;
|
||||
screen->backOffset = dri_priv->backOffset;
|
||||
screen->backPitch = dri_priv->backPitch;
|
||||
screen->depthOffset = dri_priv->depthOffset;
|
||||
screen->depthPitch = dri_priv->depthPitch;
|
||||
|
||||
screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
|
||||
+ screen->fbLocation;
|
||||
screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
|
||||
screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
|
||||
dri_priv->log2TexGran;
|
||||
|
||||
if (!screen->gartTextures.map) {
|
||||
screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
|
||||
screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
|
||||
screen->texSize[RADEON_GART_TEX_HEAP] = 0;
|
||||
screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
|
||||
} else {
|
||||
screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
|
||||
screen->texOffset[RADEON_GART_TEX_HEAP] =
|
||||
screen->gart_texture_offset;
|
||||
screen->texSize[RADEON_GART_TEX_HEAP] =
|
||||
dri_priv->gartTexMapSize;
|
||||
screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
|
||||
dri_priv->log2GARTTexGran;
|
||||
}
|
||||
|
||||
screen->driScreen = sPriv;
|
||||
screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
|
||||
|
||||
if (driCompareGLXAPIVersion(20030813) >= 0) {
|
||||
PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
|
||||
(PFNGLXSCRENABLEEXTENSIONPROC)
|
||||
glXGetProcAddress((const GLubyte *)
|
||||
"__glXScrEnableExtension");
|
||||
void *const psc = sPriv->psc->screenConfigs;
|
||||
|
||||
if (glx_enable_extension != NULL) {
|
||||
if (screen->irq != 0) {
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_SGI_swap_control");
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_SGI_video_sync");
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_MESA_swap_control");
|
||||
}
|
||||
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_MESA_swap_frame_usage");
|
||||
|
||||
if (driCompareGLXAPIVersion(20030818) >= 0) {
|
||||
sPriv->psc->allocateMemory =
|
||||
(void *)r200AllocateMemoryMESA;
|
||||
sPriv->psc->freeMemory =
|
||||
(void *)r200FreeMemoryMESA;
|
||||
sPriv->psc->memoryOffset =
|
||||
(void *)r200GetMemoryOffsetMESA;
|
||||
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_MESA_allocate_memory");
|
||||
}
|
||||
|
||||
if (driCompareGLXAPIVersion(20030915) >= 0) {
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_SGIX_fbconfig");
|
||||
(*glx_enable_extension) (psc,
|
||||
"GLX_OML_swap_method");
|
||||
}
|
||||
}
|
||||
}
|
||||
return screen;
|
||||
}
|
||||
|
||||
/* Destroy the device specific screen private data struct.
|
||||
*/
|
||||
static void radeonDestroyScreen(__DRIscreenPrivate * sPriv)
|
||||
{
|
||||
radeonScreenPtr screen = (radeonScreenPtr) sPriv->private;
|
||||
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
if (screen->gartTextures.map) {
|
||||
drmUnmap(screen->gartTextures.map, screen->gartTextures.size);
|
||||
}
|
||||
drmUnmapBufs(screen->buffers);
|
||||
drmUnmap(screen->status.map, screen->status.size);
|
||||
drmUnmap(screen->mmio.map, screen->mmio.size);
|
||||
|
||||
/* free all option information */
|
||||
driDestroyOptionInfo(&screen->optionCache);
|
||||
|
||||
FREE(screen);
|
||||
sPriv->private = NULL;
|
||||
}
|
||||
|
||||
/* Initialize the driver specific screen private data.
|
||||
*/
|
||||
static GLboolean radeonInitDriver(__DRIscreenPrivate * sPriv)
|
||||
{
|
||||
__radeonScreen = radeonCreateScreen(sPriv);
|
||||
|
||||
sPriv->private = (void *)__radeonScreen;
|
||||
|
||||
return sPriv->private ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize the Mesa and driver specific pixmap buffer
|
||||
* data.
|
||||
*
|
||||
* \todo This function (and its interface) will need to be updated to support
|
||||
* pbuffers.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonCreateBuffer(__DRIscreenPrivate * driScrnPriv,
|
||||
__DRIdrawablePrivate * driDrawPriv,
|
||||
const __GLcontextModes * mesaVis, GLboolean isPixmap)
|
||||
{
|
||||
if (isPixmap) {
|
||||
return GL_FALSE; /* not implemented */
|
||||
} else {
|
||||
const GLboolean swDepth = GL_FALSE;
|
||||
const GLboolean swAlpha = GL_FALSE;
|
||||
const GLboolean swAccum = mesaVis->accumRedBits > 0;
|
||||
const GLboolean swStencil = mesaVis->stencilBits > 0 &&
|
||||
mesaVis->depthBits != 24;
|
||||
driDrawPriv->driverPrivate = (void *)
|
||||
_mesa_create_framebuffer(mesaVis,
|
||||
swDepth,
|
||||
swStencil, swAccum, swAlpha);
|
||||
return (driDrawPriv->driverPrivate != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
|
||||
{
|
||||
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->
|
||||
driverPrivate));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Choose the appropriate CreateContext function based on the chipset.
|
||||
*/
|
||||
static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
|
||||
__DRIcontextPrivate * driContextPriv,
|
||||
void *sharedContextPriv)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
|
||||
int chip = GET_CHIP(screen);
|
||||
|
||||
if (chip >= RADEON_CHIP_R300)
|
||||
return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
|
||||
else
|
||||
return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Choose the appropriate DestroyContext function based on the chipset.
|
||||
*/
|
||||
static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
|
||||
{
|
||||
radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
|
||||
int chip = GET_CHIP(radeon->radeonScreen);
|
||||
|
||||
if (chip >= RADEON_CHIP_R300)
|
||||
return r300DestroyContext(driContextPriv);
|
||||
else
|
||||
return r200DestroyContext(driContextPriv);
|
||||
}
|
||||
|
||||
|
||||
static const struct __DriverAPIRec radeonAPI = {
|
||||
.InitDriver = radeonInitDriver,
|
||||
.DestroyScreen = radeonDestroyScreen,
|
||||
.CreateContext = radeonCreateContext,
|
||||
.DestroyContext = radeonDestroyContext,
|
||||
.CreateBuffer = radeonCreateBuffer,
|
||||
.DestroyBuffer = radeonDestroyBuffer,
|
||||
.SwapBuffers = radeonSwapBuffers,
|
||||
.MakeCurrent = radeonMakeCurrent,
|
||||
.UnbindContext = radeonUnbindContext,
|
||||
.GetSwapInfo = getSwapInfo,
|
||||
.GetMSC = driGetMSC32,
|
||||
.WaitForMSC = driWaitForMSC32,
|
||||
.WaitForSBC = NULL,
|
||||
.SwapBuffersMSC = NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
* Return: pointer to a __DRIscreenPrivate.
|
||||
*
|
||||
*/
|
||||
#if !defined(DRI_NEW_INTERFACE_ONLY)
|
||||
void *__driCreateScreen(Display * dpy, int scrn, __DRIscreen * psc,
|
||||
int numConfigs, __GLXvisualConfig * config)
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
psp =
|
||||
__driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
|
||||
return (void *)psp;
|
||||
}
|
||||
#endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
|
||||
|
||||
/**
|
||||
* This is the bootstrap function for the driver. libGL supplies all of the
|
||||
* requisite information about the system, and the driver initializes itself.
|
||||
* This routine also fills in the linked list pointed to by \c driver_modes
|
||||
* with the \c __GLcontextModes that the driver can support for windows or
|
||||
* pbuffers.
|
||||
*
|
||||
* \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
|
||||
* failure.
|
||||
*/
|
||||
#ifdef USE_NEW_INTERFACE
|
||||
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;
|
||||
static const __DRIversion ddx_expected = { 4, 0, 0 };
|
||||
static const __DRIversion dri_expected = { 4, 0, 0 };
|
||||
static const __DRIversion drm_expected = { 1, 11, 1 };
|
||||
|
||||
if (!driCheckDriDdxDrmVersions2("R300",
|
||||
dri_version, &dri_expected,
|
||||
ddx_version, &ddx_expected,
|
||||
drm_version, &drm_expected)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
|
||||
ddx_version, dri_version, drm_version,
|
||||
frame_buffer, pSAREA, fd,
|
||||
internal_api_version, &radeonAPI);
|
||||
if (psp != NULL) {
|
||||
create_context_modes = (PFNGLXCREATECONTEXTMODES)
|
||||
glXGetProcAddress((const GLubyte *)
|
||||
"__glXCreateContextModes");
|
||||
if (create_context_modes != NULL) {
|
||||
RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
|
||||
*driver_modes = radeonFillInModes(dri_priv->bpp,
|
||||
(dri_priv->bpp ==
|
||||
16) ? 16 : 24,
|
||||
(dri_priv->bpp ==
|
||||
16) ? 0 : 8,
|
||||
(dri_priv->backOffset !=
|
||||
dri_priv->
|
||||
depthOffset));
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)psp;
|
||||
}
|
||||
#endif /* USE_NEW_INTERFACE */
|
||||
|
||||
/**
|
||||
* Get information about previous buffer swaps.
|
||||
*/
|
||||
static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
|
||||
{
|
||||
radeonContextPtr radeon;
|
||||
|
||||
if ((dPriv == NULL) || (dPriv->driContextPriv == NULL)
|
||||
|| (dPriv->driContextPriv->driverPrivate == NULL)
|
||||
|| (sInfo == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
sInfo->swap_count = radeon->swap_count;
|
||||
sInfo->swap_ust = radeon->swap_ust;
|
||||
sInfo->swap_missed_count = radeon->swap_missed_count;
|
||||
|
||||
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
|
||||
? driCalculateSwapUsage(dPriv, 0, radeon->swap_missed_ust)
|
||||
: 0.0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
111
src/mesa/drivers/dri/r300/radeon_screen.h
Normal file
111
src/mesa/drivers/dri/r300/radeon_screen.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
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 __RADEON_SCREEN_H__
|
||||
#define __RADEON_SCREEN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "dri_util.h"
|
||||
#include "xmlconfig.h"
|
||||
|
||||
typedef struct {
|
||||
drm_handle_t handle; /* Handle to the DRM region */
|
||||
drmSize size; /* Size of the DRM region */
|
||||
drmAddress map; /* Mapping of the DRM region */
|
||||
} radeonRegionRec, *radeonRegionPtr;
|
||||
|
||||
/* chipset features */
|
||||
#define RADEON_CHIP_UNREAL_R200 0
|
||||
#define RADEON_CHIP_REAL_R200 1
|
||||
#define RADEON_CHIP_R300 2
|
||||
#define RADEON_CHIP_RV350 3
|
||||
#define RADEON_CHIP_MASK 0x0f
|
||||
|
||||
#define RADEON_CHIPSET_TCL (1 << 8)
|
||||
|
||||
#define GET_CHIP(screen) ((screen)->chipset & RADEON_CHIP_MASK)
|
||||
#define IS_FAMILY_R200(radeon) (GET_CHIP((radeon)->radeonScreen) < RADEON_CHIP_R300)
|
||||
#define IS_FAMILY_R300(radeon) (GET_CHIP((radeon)->radeonScreen) >= RADEON_CHIP_R300)
|
||||
|
||||
#define R200_NR_TEX_HEAPS 2
|
||||
|
||||
typedef struct {
|
||||
int chipset;
|
||||
int cpp;
|
||||
int IsPCI; /* Current card is a PCI card */
|
||||
int AGPMode;
|
||||
unsigned int irq; /* IRQ number (0 means none) */
|
||||
|
||||
unsigned int fbLocation;
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int backOffset;
|
||||
unsigned int backPitch;
|
||||
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthPitch;
|
||||
|
||||
/* Shared texture data */
|
||||
int numTexHeaps;
|
||||
int texOffset[R200_NR_TEX_HEAPS];
|
||||
int texSize[R200_NR_TEX_HEAPS];
|
||||
int logTexGranularity[R200_NR_TEX_HEAPS];
|
||||
|
||||
radeonRegionRec mmio;
|
||||
radeonRegionRec status;
|
||||
radeonRegionRec gartTextures;
|
||||
|
||||
drmBufMapPtr buffers;
|
||||
|
||||
__volatile__ int32_t *scratch;
|
||||
|
||||
__DRIscreenPrivate *driScreen;
|
||||
unsigned int sarea_priv_offset;
|
||||
unsigned int gart_buffer_offset; /* offset in card memory space */
|
||||
unsigned int gart_texture_offset; /* offset in card memory space */
|
||||
unsigned int gart_base;
|
||||
|
||||
GLboolean drmSupportsCubeMaps; /* need radeon kernel module >=1.7 */
|
||||
GLboolean drmSupportsBlendColor; /* need radeon kernel module >= 1.11 */
|
||||
|
||||
/* Configuration cache with default values for all contexts */
|
||||
driOptionCache optionCache;
|
||||
} radeonScreenRec, *radeonScreenPtr;
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_SCREEN_H__ */
|
||||
520
src/mesa/drivers/dri/r300/radeon_span.c
Normal file
520
src/mesa/drivers/dri/r300/radeon_span.c
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "colormac.h"
|
||||
|
||||
#include "r200_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "r300_ioctl.h"
|
||||
#include "radeon_span.h"
|
||||
|
||||
#define DBG 0
|
||||
|
||||
#define LOCAL_VARS \
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx); \
|
||||
radeonScreenPtr radeonScreen = radeon->radeonScreen; \
|
||||
__DRIscreenPrivate *sPriv = radeon->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = radeon->dri.drawable; \
|
||||
GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(sPriv->pFB + \
|
||||
radeon->state.color.drawOffset + \
|
||||
(dPriv->x * radeonScreen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
char *read_buf = (char *)(sPriv->pFB + \
|
||||
radeon->state.pixel.readOffset + \
|
||||
(dPriv->x * radeonScreen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
GLuint p; \
|
||||
(void) read_buf; (void) buf; (void) p
|
||||
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx); \
|
||||
radeonScreenPtr radeonScreen = radeon->radeonScreen; \
|
||||
__DRIscreenPrivate *sPriv = radeon->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = radeon->dri.drawable; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLuint xo = dPriv->x; \
|
||||
GLuint yo = dPriv->y; \
|
||||
char *buf = (char *)(sPriv->pFB + radeon->radeonScreen->depthOffset); \
|
||||
GLuint pitch = radeon->radeonScreen->depthPitch; \
|
||||
(void) buf; (void) pitch
|
||||
|
||||
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
|
||||
|
||||
#define CLIPPIXEL( _x, _y ) \
|
||||
((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
|
||||
|
||||
#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
|
||||
if ( _y < miny || _y >= maxy ) { \
|
||||
_n1 = 0, _x1 = x; \
|
||||
} else { \
|
||||
_n1 = _n; \
|
||||
_x1 = _x; \
|
||||
if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
|
||||
if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
|
||||
}
|
||||
|
||||
#define Y_FLIP( _y ) (height - _y - 1)
|
||||
|
||||
#define HW_LOCK()
|
||||
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = radeon->dri.drawable; \
|
||||
int _nc = dPriv->numClipRects; \
|
||||
\
|
||||
while ( _nc-- ) { \
|
||||
int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
|
||||
int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
|
||||
int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
|
||||
int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
|
||||
|
||||
#define HW_ENDCLIPLOOP() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HW_UNLOCK()
|
||||
|
||||
/* ================================================================
|
||||
* Color buffer
|
||||
*/
|
||||
|
||||
/* 16 bit, RGB565 color spanline and pixel functions
|
||||
*/
|
||||
#define INIT_MONO_PIXEL(p, color) \
|
||||
p = PACK_COLOR_565( color[0], color[1], color[2] )
|
||||
|
||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
|
||||
(((int)g & 0xfc) << 3) | \
|
||||
(((int)b & 0xf8) >> 3))
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = p
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
|
||||
rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
|
||||
rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[3] = 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) radeon##x##_RGB565
|
||||
#include "spantmp.h"
|
||||
|
||||
/* 32 bit, ARGB8888 color spanline and pixel functions
|
||||
*/
|
||||
#undef INIT_MONO_PIXEL
|
||||
#define INIT_MONO_PIXEL(p, color) \
|
||||
p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
|
||||
|
||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
||||
do { \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
|
||||
(g << 8) | \
|
||||
(r << 16) | \
|
||||
(a << 24) ); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
do { \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = p; \
|
||||
} while (0)
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \
|
||||
GLuint p = *ptr; \
|
||||
rgba[0] = (p >> 16) & 0xff; \
|
||||
rgba[1] = (p >> 8) & 0xff; \
|
||||
rgba[2] = (p >> 0) & 0xff; \
|
||||
rgba[3] = (p >> 24) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) radeon##x##_ARGB8888
|
||||
#include "spantmp.h"
|
||||
|
||||
/* ================================================================
|
||||
* Depth buffer
|
||||
*/
|
||||
|
||||
/* The Radeon family has depth tiling on all the time, so we have to convert
|
||||
* the x,y coordinates into the memory bus address (mba) in the same
|
||||
* manner as the engine. In each case, the linear block address (ba)
|
||||
* is calculated, and then wired with x and y to produce the final
|
||||
* memory address.
|
||||
*/
|
||||
|
||||
#define BIT(x,b) ((x & (1<<b))>>b)
|
||||
static GLuint radeon_mba_z32(radeonContextPtr radeon, GLint x, GLint y)
|
||||
{
|
||||
GLuint pitch = radeon->radeonScreen->depthPitch;
|
||||
GLuint b =
|
||||
((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x3FF) >> 5);
|
||||
GLuint a =
|
||||
(BIT(x, 0) << 2) | (BIT(y, 0) << 3) | (BIT(x, 1) << 4) | (BIT(y, 1)
|
||||
<< 5) |
|
||||
(BIT(x, 3) << 6) | (BIT(x, 4) << 7) | (BIT(x, 2) << 8) | (BIT(y, 2)
|
||||
<< 9) |
|
||||
(BIT(y, 3) << 10) |
|
||||
(((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y, 4)))) << 11) |
|
||||
((b >> 1) << 12);
|
||||
return a;
|
||||
}
|
||||
|
||||
static GLuint radeon_mba_z16(radeonContextPtr radeon, GLint x, GLint y)
|
||||
{
|
||||
GLuint pitch = radeon->radeonScreen->depthPitch;
|
||||
GLuint b =
|
||||
((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x3FF) >> 6);
|
||||
GLuint a =
|
||||
(BIT(x, 0) << 1) | (BIT(y, 0) << 2) | (BIT(x, 1) << 3) | (BIT(y, 1)
|
||||
<< 4) |
|
||||
(BIT(x, 2) << 5) | (BIT(x, 4) << 6) | (BIT(x, 5) << 7) | (BIT(x, 3)
|
||||
<< 8) |
|
||||
(BIT(y, 2) << 9) | (BIT(y, 3) << 10) |
|
||||
(((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y, 4)))) << 11) |
|
||||
((b >> 1) << 12);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/* 16-bit depth buffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
*(GLushort *)(buf + radeon_mba_z16( radeon, _x + xo, _y + yo )) = d;
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLushort *)(buf + radeon_mba_z16( radeon, _x + xo, _y + yo ));
|
||||
|
||||
#define TAG(x) radeon##x##_16_TILE
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
tmp |= ((d) & 0x00ffffff); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + radeon_mba_z32( radeon, _x + xo, \
|
||||
_y + yo )) & 0x00ffffff;
|
||||
|
||||
#define TAG(x) radeon##x##_24_8_TILE
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 16-bit depth buffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
*(GLushort *)(buf + (_x + xo)*2 + (_y + yo)*pitch ) = d;
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLushort *)(buf + (_x + xo)*2 + (_y + yo)*pitch );
|
||||
|
||||
#define TAG(x) radeon##x##_16_LINEAR
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = (_x + xo)*4 + (_y + yo)*pitch; \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
tmp |= ((d) & 0x00ffffff); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + (_x + xo)*4 + (_y + yo)*pitch) & 0x00ffffff;
|
||||
|
||||
#define TAG(x) radeon##x##_24_8_LINEAR
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* ================================================================
|
||||
* Stencil buffer
|
||||
*/
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_STENCIL( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0x00ffffff; \
|
||||
tmp |= (((d) & 0xff) << 24); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
d = tmp >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) radeon##x##_24_8_TILE
|
||||
#include "stenciltmp.h"
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_STENCIL( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = (_x + xo)*4 + (_y + yo)*pitch; \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0x00ffffff; \
|
||||
tmp |= (((d) & 0xff) << 24); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
do { \
|
||||
GLuint offset = (_x + xo)*4 + (_y + yo)*pitch; \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
d = tmp >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) radeon##x##_24_8_LINEAR
|
||||
#include "stenciltmp.h"
|
||||
|
||||
/*
|
||||
* This function is called to specify which buffer to read and write
|
||||
* for software rasterization (swrast) fallbacks. This doesn't necessarily
|
||||
* correspond to glDrawBuffer() or glReadBuffer() calls.
|
||||
*/
|
||||
static void radeonSetBuffer(GLcontext * ctx,
|
||||
GLframebuffer * colorBuffer, GLuint bufferBit)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
switch (bufferBit) {
|
||||
case DD_FRONT_LEFT_BIT:
|
||||
if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
|
||||
radeon->state.pixel.readOffset =
|
||||
radeon->radeonScreen->backOffset;
|
||||
radeon->state.pixel.readPitch =
|
||||
radeon->radeonScreen->backPitch;
|
||||
radeon->state.color.drawOffset =
|
||||
radeon->radeonScreen->backOffset;
|
||||
radeon->state.color.drawPitch =
|
||||
radeon->radeonScreen->backPitch;
|
||||
} else {
|
||||
radeon->state.pixel.readOffset =
|
||||
radeon->radeonScreen->frontOffset;
|
||||
radeon->state.pixel.readPitch =
|
||||
radeon->radeonScreen->frontPitch;
|
||||
radeon->state.color.drawOffset =
|
||||
radeon->radeonScreen->frontOffset;
|
||||
radeon->state.color.drawPitch =
|
||||
radeon->radeonScreen->frontPitch;
|
||||
}
|
||||
break;
|
||||
case DD_BACK_LEFT_BIT:
|
||||
if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
|
||||
radeon->state.pixel.readOffset =
|
||||
radeon->radeonScreen->frontOffset;
|
||||
radeon->state.pixel.readPitch =
|
||||
radeon->radeonScreen->frontPitch;
|
||||
radeon->state.color.drawOffset =
|
||||
radeon->radeonScreen->frontOffset;
|
||||
radeon->state.color.drawPitch =
|
||||
radeon->radeonScreen->frontPitch;
|
||||
} else {
|
||||
radeon->state.pixel.readOffset =
|
||||
radeon->radeonScreen->backOffset;
|
||||
radeon->state.pixel.readPitch =
|
||||
radeon->radeonScreen->backPitch;
|
||||
radeon->state.color.drawOffset =
|
||||
radeon->radeonScreen->backOffset;
|
||||
radeon->state.color.drawPitch =
|
||||
radeon->radeonScreen->backPitch;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move locking out to get reasonable span performance (10x better
|
||||
* than doing this in HW_LOCK above). WaitForIdle() is the main
|
||||
* culprit.
|
||||
*/
|
||||
|
||||
static void radeonSpanRenderStart(GLcontext * ctx)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (IS_FAMILY_R200(radeon))
|
||||
R200_FIREVERTICES((r200ContextPtr)radeon);
|
||||
else
|
||||
r300Flush(ctx);
|
||||
|
||||
LOCK_HARDWARE(radeon);
|
||||
radeonWaitForIdleLocked(radeon);
|
||||
|
||||
/* Read & rewrite the first pixel in the frame buffer. This should
|
||||
* be a noop, right? In fact without this conform fails as reading
|
||||
* from the framebuffer sometimes produces old results -- the
|
||||
* on-card read cache gets mixed up and doesn't notice that the
|
||||
* framebuffer has been updated.
|
||||
*
|
||||
* In the worst case this is buggy too as p might get the wrong
|
||||
* value first time, so really need a hidden pixel somewhere for this.
|
||||
*/
|
||||
{
|
||||
int p;
|
||||
volatile int *read_buf =
|
||||
(volatile int *)(radeon->dri.screen->pFB +
|
||||
radeon->state.pixel.readOffset);
|
||||
p = *read_buf;
|
||||
*read_buf = p;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonSpanRenderFinish(GLcontext * ctx)
|
||||
{
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
|
||||
_swrast_flush(ctx);
|
||||
UNLOCK_HARDWARE(radeon);
|
||||
}
|
||||
|
||||
void radeonInitSpanFuncs(GLcontext * ctx)
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
|
||||
struct swrast_device_driver *swdd =
|
||||
_swrast_GetDeviceDriverReference(ctx);
|
||||
|
||||
swdd->SetBuffer = radeonSetBuffer;
|
||||
|
||||
switch (radeon->radeonScreen->cpp) {
|
||||
case 2:
|
||||
swdd->WriteRGBASpan = radeonWriteRGBASpan_RGB565;
|
||||
swdd->WriteRGBSpan = radeonWriteRGBSpan_RGB565;
|
||||
swdd->WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565;
|
||||
swdd->WriteRGBAPixels = radeonWriteRGBAPixels_RGB565;
|
||||
swdd->WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565;
|
||||
swdd->ReadRGBASpan = radeonReadRGBASpan_RGB565;
|
||||
swdd->ReadRGBAPixels = radeonReadRGBAPixels_RGB565;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
swdd->WriteRGBASpan = radeonWriteRGBASpan_ARGB8888;
|
||||
swdd->WriteRGBSpan = radeonWriteRGBSpan_ARGB8888;
|
||||
swdd->WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888;
|
||||
swdd->WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888;
|
||||
swdd->WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888;
|
||||
swdd->ReadRGBASpan = radeonReadRGBASpan_ARGB8888;
|
||||
swdd->ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_FAMILY_R300(radeon))
|
||||
{
|
||||
switch (radeon->glCtx->Visual.depthBits) {
|
||||
case 16:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_16_LINEAR;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_16_LINEAR;
|
||||
swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_16_LINEAR;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_16_LINEAR;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_16_LINEAR;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_24_8_LINEAR;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_24_8_LINEAR;
|
||||
swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_24_8_LINEAR;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_24_8_LINEAR;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_24_8_LINEAR;
|
||||
|
||||
swdd->ReadStencilSpan = radeonReadStencilSpan_24_8_LINEAR;
|
||||
swdd->WriteStencilSpan = radeonWriteStencilSpan_24_8_LINEAR;
|
||||
swdd->ReadStencilPixels = radeonReadStencilPixels_24_8_LINEAR;
|
||||
swdd->WriteStencilPixels = radeonWriteStencilPixels_24_8_LINEAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (radeon->glCtx->Visual.depthBits) {
|
||||
case 16:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_16_TILE;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_16_TILE;
|
||||
swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_16_TILE;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_16_TILE;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_16_TILE;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_24_8_TILE;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_24_8_TILE;
|
||||
swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_24_8_TILE;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_24_8_TILE;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_24_8_TILE;
|
||||
|
||||
swdd->ReadStencilSpan = radeonReadStencilSpan_24_8_TILE;
|
||||
swdd->WriteStencilSpan = radeonWriteStencilSpan_24_8_TILE;
|
||||
swdd->ReadStencilPixels = radeonReadStencilPixels_24_8_TILE;
|
||||
swdd->WriteStencilPixels = radeonWriteStencilPixels_24_8_TILE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
swdd->SpanRenderStart = radeonSpanRenderStart;
|
||||
swdd->SpanRenderFinish = radeonSpanRenderFinish;
|
||||
}
|
||||
43
src/mesa/drivers/dri/r300/radeon_span.h
Normal file
43
src/mesa/drivers/dri/r300/radeon_span.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
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 __RADEON_SPAN_H__
|
||||
#define __RADEON_SPAN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void radeonInitSpanFuncs(GLcontext * ctx);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue