mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
A full radeon driver, seems to build ok, haven't run yet
This commit is contained in:
parent
702b2802a0
commit
40af4d7662
39 changed files with 19353 additions and 0 deletions
82
src/mesa/drivers/dri/radeon/Makefile
Normal file
82
src/mesa/drivers/dri/radeon/Makefile
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# $Id: Makefile,v 1.1.2.1 2002/12/04 15:31:04 keithw Exp $
|
||||
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 5.0
|
||||
# Copyright (C) 1995-2002 Brian Paul
|
||||
|
||||
|
||||
|
||||
MESA = ../../..
|
||||
MESABUILDDIR = $(MESA)/src
|
||||
INCLUDES = -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -I$(MESABUILDDIR)/miniglx
|
||||
CFLAGS = $(INCLUDES) -g -MD -DGLX_DIRECT_RENDERING
|
||||
|
||||
# The .a files for each mesa module required by this driver:
|
||||
#
|
||||
COREMESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \
|
||||
$(MESABUILDDIR)/tnl/tnl.a \
|
||||
$(MESABUILDDIR)/math/math.a \
|
||||
$(MESABUILDDIR)/array_cache/array_cache.a \
|
||||
$(MESABUILDDIR)/swrast/swrast.a \
|
||||
$(MESABUILDDIR)/mesa.a
|
||||
|
||||
DRIVER_SOURCES = radeon_compat.c \
|
||||
radeon_context.c \
|
||||
radeon_ioctl.c \
|
||||
radeon_lock.c \
|
||||
radeon_maos.c \
|
||||
radeon_sanity.c \
|
||||
radeon_screen.c \
|
||||
radeon_span.c \
|
||||
radeon_state.c \
|
||||
radeon_state_init.c \
|
||||
radeon_swtcl.c \
|
||||
radeon_tcl.c \
|
||||
radeon_tex.c \
|
||||
radeon_texmem.c \
|
||||
radeon_texstate.c \
|
||||
radeon_vtxfmt.c \
|
||||
radeon_vtxfmt_c.c \
|
||||
radeon_vtxfmt_sse.c \
|
||||
radeon_vtxfmt_x86.c \
|
||||
../common/mm.c
|
||||
|
||||
C_SOURCES = $(DRIVER_SOURCES) \
|
||||
$(DRI_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
OBJECTS = $(C_SOURCES:.c=.o) \
|
||||
$(ASM_SOURCES:.S=.o)
|
||||
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default: radeon_dri.so
|
||||
|
||||
radeon_dri.so: $(COREMESA) $(OBJECTS) Makefile
|
||||
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(COREMESA) -L$(MESA)/src/miniglx -lGL -lc -lm
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ *.d .\#* *.so
|
||||
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` `find ../include`
|
||||
|
||||
##### DEPENDENCIES #####
|
||||
|
||||
include $(C_SOURCES:.c=.d)
|
||||
|
||||
.SUFFIXES: .c .d
|
||||
|
||||
.c.d:
|
||||
$(CC) -M $(INCLUDES) $< -o $@
|
||||
444
src/mesa/drivers/dri/radeon/radeon_common.h
Normal file
444
src/mesa/drivers/dri/radeon/radeon_common.h
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/* radeon_common.h -- common header definitions for Radeon 2D/3D/DRM suite
|
||||
*
|
||||
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
|
||||
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* 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
|
||||
* PRECISION INSIGHT 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.
|
||||
*
|
||||
* Author:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
* Converted to common header format:
|
||||
* Jens Owen <jens@tungstengraphics.com>
|
||||
*
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h,v 1.6 2001/04/16 15:02:13 tsi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RADEON_COMMON_H_
|
||||
#define _RADEON_COMMON_H_
|
||||
|
||||
#include "xf86drm.h"
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change
|
||||
* the kernel include file as well (radeon_drm.h)
|
||||
*/
|
||||
|
||||
/* Driver specific DRM command indices
|
||||
* NOTE: these are not OS specific, but they are driver specific
|
||||
*/
|
||||
#define DRM_RADEON_CP_INIT 0x00
|
||||
#define DRM_RADEON_CP_START 0x01
|
||||
#define DRM_RADEON_CP_STOP 0x02
|
||||
#define DRM_RADEON_CP_RESET 0x03
|
||||
#define DRM_RADEON_CP_IDLE 0x04
|
||||
#define DRM_RADEON_RESET 0x05
|
||||
#define DRM_RADEON_FULLSCREEN 0x06
|
||||
#define DRM_RADEON_SWAP 0x07
|
||||
#define DRM_RADEON_CLEAR 0x08
|
||||
#define DRM_RADEON_VERTEX 0x09
|
||||
#define DRM_RADEON_INDICES 0x0a
|
||||
#define DRM_RADEON_STIPPLE 0x0c
|
||||
#define DRM_RADEON_INDIRECT 0x0d
|
||||
#define DRM_RADEON_TEXTURE 0x0e
|
||||
#define DRM_RADEON_VERTEX2 0x0f
|
||||
#define DRM_RADEON_CMDBUF 0x10
|
||||
#define DRM_RADEON_GETPARAM 0x11
|
||||
#define DRM_RADEON_FLIP 0x12
|
||||
#define DRM_RADEON_ALLOC 0x13
|
||||
#define DRM_RADEON_FREE 0x14
|
||||
#define DRM_RADEON_INIT_HEAP 0x15
|
||||
#define DRM_RADEON_IRQ_EMIT 0x16
|
||||
#define DRM_RADEON_IRQ_WAIT 0x17
|
||||
#define DRM_RADEON_MAX_DRM_COMMAND_INDEX 0x39
|
||||
|
||||
|
||||
#define RADEON_FRONT 0x1
|
||||
#define RADEON_BACK 0x2
|
||||
#define RADEON_DEPTH 0x4
|
||||
#define RADEON_STENCIL 0x8
|
||||
|
||||
#define RADEON_CLEAR_X1 0
|
||||
#define RADEON_CLEAR_Y1 1
|
||||
#define RADEON_CLEAR_X2 2
|
||||
#define RADEON_CLEAR_Y2 3
|
||||
#define RADEON_CLEAR_DEPTH 4
|
||||
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
DRM_RADEON_INIT_CP = 0x01,
|
||||
DRM_RADEON_CLEANUP_CP = 0x02,
|
||||
DRM_RADEON_INIT_R200_CP = 0x03
|
||||
} func;
|
||||
unsigned long sarea_priv_offset;
|
||||
int is_pci;
|
||||
int cp_mode;
|
||||
int agp_size;
|
||||
int ring_size;
|
||||
int usec_timeout;
|
||||
|
||||
unsigned int fb_bpp;
|
||||
unsigned int front_offset, front_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int depth_bpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
|
||||
unsigned long fb_offset;
|
||||
unsigned long mmio_offset;
|
||||
unsigned long ring_offset;
|
||||
unsigned long ring_rptr_offset;
|
||||
unsigned long buffers_offset;
|
||||
unsigned long agp_textures_offset;
|
||||
} drmRadeonInit;
|
||||
|
||||
typedef struct {
|
||||
int flush;
|
||||
int idle;
|
||||
} drmRadeonCPStop;
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
int start;
|
||||
int end;
|
||||
int discard;
|
||||
} drmRadeonIndirect;
|
||||
|
||||
typedef union drmRadeonClearR {
|
||||
float f[5];
|
||||
unsigned int ui[5];
|
||||
} drmRadeonClearRect;
|
||||
|
||||
typedef struct drmRadeonClearT {
|
||||
unsigned int flags;
|
||||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
unsigned int color_mask;
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
drmRadeonClearRect *depth_boxes;
|
||||
} drmRadeonClearType;
|
||||
|
||||
typedef struct drmRadeonFullscreenT {
|
||||
enum {
|
||||
RADEON_INIT_FULLSCREEN = 0x01,
|
||||
RADEON_CLEANUP_FULLSCREEN = 0x02
|
||||
} func;
|
||||
} drmRadeonFullscreenType;
|
||||
|
||||
typedef struct {
|
||||
unsigned int *mask;
|
||||
} drmRadeonStipple;
|
||||
|
||||
typedef struct {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
const void *data;
|
||||
} drmRadeonTexImage;
|
||||
|
||||
typedef struct {
|
||||
int offset;
|
||||
int pitch;
|
||||
int format;
|
||||
int width; /* Texture image coordinates */
|
||||
int height;
|
||||
drmRadeonTexImage *image;
|
||||
} drmRadeonTexture;
|
||||
|
||||
|
||||
#define RADEON_MAX_TEXTURE_UNITS 3
|
||||
|
||||
/* Layout matches drm_radeon_state_t in linux drm_radeon.h.
|
||||
*/
|
||||
typedef struct {
|
||||
struct {
|
||||
unsigned int pp_misc; /* 0x1c14 */
|
||||
unsigned int pp_fog_color;
|
||||
unsigned int re_solid_color;
|
||||
unsigned int rb3d_blendcntl;
|
||||
unsigned int rb3d_depthoffset;
|
||||
unsigned int rb3d_depthpitch;
|
||||
unsigned int rb3d_zstencilcntl;
|
||||
unsigned int pp_cntl; /* 0x1c38 */
|
||||
unsigned int rb3d_cntl;
|
||||
unsigned int rb3d_coloroffset;
|
||||
unsigned int re_width_height;
|
||||
unsigned int rb3d_colorpitch;
|
||||
} context;
|
||||
struct {
|
||||
unsigned int se_cntl;
|
||||
} setup1;
|
||||
struct {
|
||||
unsigned int se_coord_fmt; /* 0x1c50 */
|
||||
} vertex;
|
||||
struct {
|
||||
unsigned int re_line_pattern; /* 0x1cd0 */
|
||||
unsigned int re_line_state;
|
||||
unsigned int se_line_width; /* 0x1db8 */
|
||||
} line;
|
||||
struct {
|
||||
unsigned int pp_lum_matrix; /* 0x1d00 */
|
||||
unsigned int pp_rot_matrix_0; /* 0x1d58 */
|
||||
unsigned int pp_rot_matrix_1;
|
||||
} bumpmap;
|
||||
struct {
|
||||
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
|
||||
unsigned int rb3d_ropcntl;
|
||||
unsigned int rb3d_planemask;
|
||||
} mask;
|
||||
struct {
|
||||
unsigned int se_vport_xscale; /* 0x1d98 */
|
||||
unsigned int se_vport_xoffset;
|
||||
unsigned int se_vport_yscale;
|
||||
unsigned int se_vport_yoffset;
|
||||
unsigned int se_vport_zscale;
|
||||
unsigned int se_vport_zoffset;
|
||||
} viewport;
|
||||
struct {
|
||||
unsigned int se_cntl_status; /* 0x2140 */
|
||||
} setup2;
|
||||
struct {
|
||||
unsigned int re_top_left; /*ignored*/ /* 0x26c0 */
|
||||
unsigned int re_misc;
|
||||
} misc;
|
||||
struct {
|
||||
unsigned int pp_txfilter;
|
||||
unsigned int pp_txformat;
|
||||
unsigned int pp_txoffset;
|
||||
unsigned int pp_txcblend;
|
||||
unsigned int pp_txablend;
|
||||
unsigned int pp_tfactor;
|
||||
unsigned int pp_border_color;
|
||||
} texture[RADEON_MAX_TEXTURE_UNITS];
|
||||
struct {
|
||||
unsigned int se_zbias_factor;
|
||||
unsigned int se_zbias_constant;
|
||||
} zbias;
|
||||
unsigned int dirty;
|
||||
} drmRadeonState;
|
||||
|
||||
/* 1.1 vertex ioctl. Used in compatibility modes.
|
||||
*/
|
||||
typedef struct {
|
||||
int prim;
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drmRadeonVertex;
|
||||
|
||||
typedef struct {
|
||||
unsigned int start;
|
||||
unsigned int finish;
|
||||
unsigned int prim:8;
|
||||
unsigned int stateidx:8;
|
||||
unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
|
||||
unsigned int vc_format;
|
||||
} drmRadeonPrim;
|
||||
|
||||
typedef struct {
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int nr_states;
|
||||
drmRadeonState *state;
|
||||
int nr_prims;
|
||||
drmRadeonPrim *prim;
|
||||
} drmRadeonVertex2;
|
||||
|
||||
#define RADEON_MAX_STATES 16
|
||||
#define RADEON_MAX_PRIMS 64
|
||||
|
||||
/* Command buffer. Replace with true dma stream?
|
||||
*/
|
||||
typedef struct {
|
||||
int bufsz;
|
||||
char *buf;
|
||||
int nbox;
|
||||
drmClipRect *boxes;
|
||||
} drmRadeonCmdBuffer;
|
||||
|
||||
/* New style per-packet identifiers for use in cmd_buffer ioctl with
|
||||
* the RADEON_EMIT_PACKET command. Comments relate new packets to old
|
||||
* state bits and the packet size:
|
||||
*/
|
||||
#define RADEON_EMIT_PP_MISC 0 /* context/7 */
|
||||
#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
|
||||
#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
|
||||
#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
|
||||
#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
|
||||
#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
|
||||
#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
|
||||
#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
|
||||
#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
|
||||
#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
|
||||
#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
|
||||
#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
|
||||
#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
|
||||
#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
|
||||
#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
|
||||
#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
|
||||
#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/6 */
|
||||
#define R200_EMIT_TFACTOR_0 30 /* tf/6 */
|
||||
#define R200_EMIT_VTX_FMT_0 31 /* vtx/4 */
|
||||
#define R200_EMIT_VAP_CTL 32 /* vap/1 */
|
||||
#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
|
||||
#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
|
||||
#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
|
||||
#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
|
||||
#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
|
||||
#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
|
||||
#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
|
||||
#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
|
||||
#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
|
||||
#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
|
||||
#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
|
||||
#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
|
||||
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
|
||||
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
|
||||
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
|
||||
#define R200_EMIT_PP_CUBIC_FACES_0 61
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
|
||||
#define R200_EMIT_PP_CUBIC_FACES_1 63
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
|
||||
#define R200_EMIT_PP_CUBIC_FACES_2 65
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
|
||||
#define R200_EMIT_PP_CUBIC_FACES_3 67
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
|
||||
#define R200_EMIT_PP_CUBIC_FACES_4 69
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_4 70
|
||||
#define R200_EMIT_PP_CUBIC_FACES_5 71
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_5 72
|
||||
#define RADEON_MAX_STATE_PACKETS 73
|
||||
|
||||
|
||||
/* Commands understood by cmd_buffer ioctl. More can be added but
|
||||
* obviously these can't be removed or changed:
|
||||
*/
|
||||
#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
|
||||
#define RADEON_CMD_SCALARS 2 /* emit scalar data */
|
||||
#define RADEON_CMD_VECTORS 3 /* emit vector data */
|
||||
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
|
||||
#define RADEON_CMD_PACKET3 5 /* emit hw packet */
|
||||
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
|
||||
#define RADEON_CMD_SCALARS2 7 /* R200 stopgap */
|
||||
#define RADEON_CMD_WAIT 8 /* synchronization */
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
struct {
|
||||
unsigned char cmd_type, pad0, pad1, pad2;
|
||||
} header;
|
||||
struct {
|
||||
unsigned char cmd_type, packet_id, pad0, pad1;
|
||||
} packet;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
} scalars;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
} vectors;
|
||||
struct {
|
||||
unsigned char cmd_type, buf_idx, pad0, pad1;
|
||||
} dma;
|
||||
struct {
|
||||
unsigned char cmd_type, flags, pad0, pad1;
|
||||
} wait;
|
||||
} drmRadeonCmdHeader;
|
||||
|
||||
|
||||
#define RADEON_WAIT_2D 0x1
|
||||
#define RADEON_WAIT_3D 0x2
|
||||
|
||||
|
||||
typedef struct drm_radeon_getparam {
|
||||
int param;
|
||||
int *value;
|
||||
} drmRadeonGetParam;
|
||||
|
||||
#define RADEON_PARAM_AGP_BUFFER_OFFSET 1
|
||||
#define RADEON_PARAM_LAST_FRAME 2
|
||||
#define RADEON_PARAM_LAST_DISPATCH 3
|
||||
#define RADEON_PARAM_LAST_CLEAR 4
|
||||
#define RADEON_PARAM_IRQ_NR 5
|
||||
#define RADEON_PARAM_AGP_BASE 6
|
||||
|
||||
|
||||
#define RADEON_MEM_REGION_AGP 1
|
||||
#define RADEON_MEM_REGION_FB 2
|
||||
|
||||
typedef struct drm_radeon_mem_alloc {
|
||||
int region;
|
||||
int alignment;
|
||||
int size;
|
||||
int *region_offset; /* offset from start of fb or agp */
|
||||
} drmRadeonMemAlloc;
|
||||
|
||||
typedef struct drm_radeon_mem_free {
|
||||
int region;
|
||||
int region_offset;
|
||||
} drmRadeonMemFree;
|
||||
|
||||
typedef struct drm_radeon_mem_init_heap {
|
||||
int region;
|
||||
int size;
|
||||
int start;
|
||||
} drmRadeonMemInitHeap;
|
||||
|
||||
/* 1.6: Userspace can request & wait on irq's:
|
||||
*/
|
||||
typedef struct drm_radeon_irq_emit {
|
||||
int *irq_seq;
|
||||
} drmRadeonIrqEmit;
|
||||
|
||||
typedef struct drm_radeon_irq_wait {
|
||||
int irq_seq;
|
||||
} drmRadeonIrqWait;
|
||||
|
||||
|
||||
#endif
|
||||
304
src/mesa/drivers/dri/radeon/radeon_compat.c
Normal file
304
src/mesa/drivers/dri/radeon/radeon_compat.c
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Austin, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
|
||||
|
||||
static struct {
|
||||
int start;
|
||||
int len;
|
||||
const char *name;
|
||||
} packet[RADEON_MAX_STATE_PACKETS] = {
|
||||
{ RADEON_PP_MISC,7,"RADEON_PP_MISC" },
|
||||
{ RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
|
||||
{ RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
|
||||
{ RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
|
||||
{ RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
|
||||
{ RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
|
||||
{ RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
|
||||
{ RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
|
||||
{ RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
|
||||
{ RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
|
||||
{ RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
|
||||
{ RADEON_RE_MISC,1,"RADEON_RE_MISC" },
|
||||
{ RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
|
||||
{ RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
|
||||
{ RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
|
||||
{ RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
|
||||
{ RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
|
||||
{ RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
|
||||
{ RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
|
||||
{ RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
|
||||
};
|
||||
|
||||
|
||||
static void radeonCompatEmitPacket( radeonContextPtr rmesa,
|
||||
struct radeon_state_atom *state )
|
||||
{
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
radeon_context_regs_t *ctx = &sarea->ContextState;
|
||||
radeon_texture_regs_t *tex0 = &sarea->TexState[0];
|
||||
radeon_texture_regs_t *tex1 = &sarea->TexState[1];
|
||||
int i;
|
||||
int *buf = state->cmd;
|
||||
|
||||
for ( i = 0 ; i < state->cmd_size ; ) {
|
||||
drmRadeonCmdHeader *header = (drmRadeonCmdHeader *)&buf[i++];
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "%s %d: %s\n", __FUNCTION__, header->packet.packet_id,
|
||||
packet[(int)header->packet.packet_id].name);
|
||||
|
||||
switch (header->packet.packet_id) {
|
||||
case RADEON_EMIT_PP_MISC:
|
||||
ctx->pp_misc = buf[i++];
|
||||
ctx->pp_fog_color = buf[i++];
|
||||
ctx->re_solid_color = buf[i++];
|
||||
ctx->rb3d_blendcntl = buf[i++];
|
||||
ctx->rb3d_depthoffset = buf[i++];
|
||||
ctx->rb3d_depthpitch = buf[i++];
|
||||
ctx->rb3d_zstencilcntl = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_CONTEXT;
|
||||
break;
|
||||
case RADEON_EMIT_PP_CNTL:
|
||||
ctx->pp_cntl = buf[i++];
|
||||
ctx->rb3d_cntl = buf[i++];
|
||||
ctx->rb3d_coloroffset = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_CONTEXT;
|
||||
break;
|
||||
case RADEON_EMIT_RB3D_COLORPITCH:
|
||||
ctx->rb3d_colorpitch = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_CONTEXT;
|
||||
break;
|
||||
case RADEON_EMIT_RE_LINE_PATTERN:
|
||||
ctx->re_line_pattern = buf[i++];
|
||||
ctx->re_line_state = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_LINE;
|
||||
break;
|
||||
case RADEON_EMIT_SE_LINE_WIDTH:
|
||||
ctx->se_line_width = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_LINE;
|
||||
break;
|
||||
case RADEON_EMIT_PP_LUM_MATRIX:
|
||||
ctx->pp_lum_matrix = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_BUMPMAP;
|
||||
break;
|
||||
case RADEON_EMIT_PP_ROT_MATRIX_0:
|
||||
ctx->pp_rot_matrix_0 = buf[i++];
|
||||
ctx->pp_rot_matrix_1 = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_BUMPMAP;
|
||||
break;
|
||||
case RADEON_EMIT_RB3D_STENCILREFMASK:
|
||||
ctx->rb3d_stencilrefmask = buf[i++];
|
||||
ctx->rb3d_ropcntl = buf[i++];
|
||||
ctx->rb3d_planemask = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_MASKS;
|
||||
break;
|
||||
case RADEON_EMIT_SE_VPORT_XSCALE:
|
||||
ctx->se_vport_xscale = buf[i++];
|
||||
ctx->se_vport_xoffset = buf[i++];
|
||||
ctx->se_vport_yscale = buf[i++];
|
||||
ctx->se_vport_yoffset = buf[i++];
|
||||
ctx->se_vport_zscale = buf[i++];
|
||||
ctx->se_vport_zoffset = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_VIEWPORT;
|
||||
break;
|
||||
case RADEON_EMIT_SE_CNTL:
|
||||
ctx->se_cntl = buf[i++];
|
||||
ctx->se_coord_fmt = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_VERTFMT;
|
||||
break;
|
||||
case RADEON_EMIT_SE_CNTL_STATUS:
|
||||
ctx->se_cntl_status = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_SETUP;
|
||||
break;
|
||||
case RADEON_EMIT_RE_MISC:
|
||||
ctx->re_misc = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_MISC;
|
||||
break;
|
||||
case RADEON_EMIT_PP_TXFILTER_0:
|
||||
tex0->pp_txfilter = buf[i++];
|
||||
tex0->pp_txformat = buf[i++];
|
||||
tex0->pp_txoffset = buf[i++];
|
||||
tex0->pp_txcblend = buf[i++];
|
||||
tex0->pp_txablend = buf[i++];
|
||||
tex0->pp_tfactor = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_TEX0;
|
||||
break;
|
||||
case RADEON_EMIT_PP_BORDER_COLOR_0:
|
||||
tex0->pp_border_color = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_TEX0;
|
||||
break;
|
||||
case RADEON_EMIT_PP_TXFILTER_1:
|
||||
tex1->pp_txfilter = buf[i++];
|
||||
tex1->pp_txformat = buf[i++];
|
||||
tex1->pp_txoffset = buf[i++];
|
||||
tex1->pp_txcblend = buf[i++];
|
||||
tex1->pp_txablend = buf[i++];
|
||||
tex1->pp_tfactor = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_TEX1;
|
||||
break;
|
||||
case RADEON_EMIT_PP_BORDER_COLOR_1:
|
||||
tex1->pp_border_color = buf[i++];
|
||||
sarea->dirty |= RADEON_UPLOAD_TEX1;
|
||||
break;
|
||||
|
||||
case RADEON_EMIT_SE_ZBIAS_FACTOR:
|
||||
i++;
|
||||
i++;
|
||||
break;
|
||||
|
||||
case RADEON_EMIT_PP_TXFILTER_2:
|
||||
case RADEON_EMIT_PP_BORDER_COLOR_2:
|
||||
case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:
|
||||
case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:
|
||||
default:
|
||||
/* These states aren't understood by radeon drm 1.1 */
|
||||
fprintf(stderr, "Tried to emit unsupported state\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void radeonCompatEmitStateLocked( radeonContextPtr rmesa )
|
||||
{
|
||||
struct radeon_state_atom *state, *tmp;
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->lost_context) {
|
||||
if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL))
|
||||
fprintf(stderr, "%s - lost context\n", __FUNCTION__);
|
||||
|
||||
foreach_s( state, tmp, &(rmesa->hw.clean) )
|
||||
move_to_tail(&(rmesa->hw.dirty), state );
|
||||
|
||||
rmesa->lost_context = 0;
|
||||
}
|
||||
|
||||
foreach_s( state, tmp, &(rmesa->hw.dirty) ) {
|
||||
if (!state->is_tcl)
|
||||
radeonCompatEmitPacket( rmesa, state );
|
||||
move_to_head( &(rmesa->hw.clean), state );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void radeonCompatEmitPrimitiveLocked( radeonContextPtr rmesa,
|
||||
GLuint hw_primitive,
|
||||
GLuint nverts,
|
||||
XF86DRIClipRectPtr pbox,
|
||||
GLuint nbox )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < nbox ; ) {
|
||||
int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox );
|
||||
XF86DRIClipRectPtr b = rmesa->sarea->boxes;
|
||||
drmRadeonVertex vtx;
|
||||
|
||||
rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS;
|
||||
rmesa->sarea->nbox = nr - i;
|
||||
|
||||
for ( ; i < nr ; i++)
|
||||
*b++ = pbox[i];
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr,
|
||||
"RadeonFlushVertexBuffer: prim %x buf %d verts %d "
|
||||
"disc %d nbox %d\n",
|
||||
hw_primitive,
|
||||
rmesa->dma.current.buf->buf->idx,
|
||||
nverts,
|
||||
nr == nbox,
|
||||
rmesa->sarea->nbox );
|
||||
|
||||
vtx.prim = hw_primitive;
|
||||
vtx.idx = rmesa->dma.current.buf->buf->idx;
|
||||
vtx.count = nverts;
|
||||
vtx.discard = (nr == nbox);
|
||||
|
||||
drmCommandWrite( rmesa->dri.fd,
|
||||
DRM_RADEON_VERTEX,
|
||||
&vtx, sizeof(vtx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* No 'start' for 1.1 vertices ioctl: only one vertex prim/buffer!
|
||||
*/
|
||||
void radeonCompatEmitPrimitive( radeonContextPtr rmesa,
|
||||
GLuint vertex_format,
|
||||
GLuint hw_primitive,
|
||||
GLuint nrverts )
|
||||
{
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
radeonCompatEmitStateLocked( rmesa );
|
||||
rmesa->sarea->vc_format = vertex_format;
|
||||
|
||||
if (rmesa->state.scissor.enabled) {
|
||||
radeonCompatEmitPrimitiveLocked( rmesa,
|
||||
hw_primitive,
|
||||
nrverts,
|
||||
rmesa->state.scissor.pClipRects,
|
||||
rmesa->state.scissor.numClipRects );
|
||||
}
|
||||
else {
|
||||
radeonCompatEmitPrimitiveLocked( rmesa,
|
||||
hw_primitive,
|
||||
nrverts,
|
||||
rmesa->pClipRects,
|
||||
rmesa->numClipRects );
|
||||
}
|
||||
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
789
src/mesa/drivers/dri/radeon/radeon_context.c
Normal file
789
src/mesa/drivers/dri/radeon/radeon_context.c
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "api_arrayelt.h"
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "matrix.h"
|
||||
#include "extensions.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 "radeon_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_span.h"
|
||||
#include "radeon_tex.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_tcl.h"
|
||||
#include "radeon_vtxfmt.h"
|
||||
#include "radeon_maos.h"
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
#endif
|
||||
|
||||
#define RADEON_DATE "20021125"
|
||||
|
||||
#ifndef RADEON_DEBUG
|
||||
int RADEON_DEBUG = (0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Return the width and height of the given buffer.
|
||||
*/
|
||||
static void radeonGetBufferSize( GLframebuffer *buffer,
|
||||
GLuint *width, GLuint *height )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
*width = rmesa->dri.drawable->w;
|
||||
*height = rmesa->dri.drawable->h;
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
/* Return various strings for glGetString().
|
||||
*/
|
||||
static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
static char buffer[128];
|
||||
|
||||
switch ( name ) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *)"Tungsten Graphics, Inc.";
|
||||
|
||||
case GL_RENDERER:
|
||||
sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE);
|
||||
|
||||
/* Append any chipset-specific information. None yet.
|
||||
*/
|
||||
|
||||
/* Append any AGP-specific information.
|
||||
*/
|
||||
switch ( rmesa->radeonScreen->AGPMode ) {
|
||||
case 1:
|
||||
strncat( buffer, " AGP 1x", 7 );
|
||||
break;
|
||||
case 2:
|
||||
strncat( buffer, " AGP 2x", 7 );
|
||||
break;
|
||||
case 4:
|
||||
strncat( buffer, " AGP 4x", 7 );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Append any CPU-specific information.
|
||||
*/
|
||||
#ifdef USE_X86_ASM
|
||||
if ( _mesa_x86_cpu_features ) {
|
||||
strncat( buffer, " x86", 4 );
|
||||
}
|
||||
#ifdef USE_MMX_ASM
|
||||
if ( cpu_has_mmx ) {
|
||||
strncat( buffer, "/MMX", 4 );
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_3DNOW_ASM
|
||||
if ( cpu_has_3dnow ) {
|
||||
strncat( buffer, "/3DNow!", 7 );
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SSE_ASM
|
||||
if ( cpu_has_xmm ) {
|
||||
strncat( buffer, "/SSE", 4 );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( rmesa->dri.drmMinor < 3 ) {
|
||||
strncat( buffer, " DRM-COMPAT", 11 );
|
||||
}
|
||||
|
||||
if ( !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) ) {
|
||||
strncat( buffer, " TCL", 4 );
|
||||
}
|
||||
else {
|
||||
strncat( buffer, " NO-TCL", 7 );
|
||||
}
|
||||
|
||||
return (GLubyte *)buffer;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Extension strings exported by the R100 driver.
|
||||
*/
|
||||
static const char * const radeon_extensions[] =
|
||||
{
|
||||
"GL_ARB_multisample",
|
||||
"GL_ARB_multitexture",
|
||||
"GL_ARB_texture_border_clamp",
|
||||
"GL_ARB_texture_compression",
|
||||
"GL_ARB_texture_env_add",
|
||||
"GL_ARB_texture_env_combine",
|
||||
"GL_ARB_texture_env_dot3",
|
||||
"GL_ARB_texture_mirrored_repeat",
|
||||
"GL_EXT_blend_logic_op",
|
||||
"GL_EXT_blend_subtract",
|
||||
/* "GL_EXT_fog_coord", */
|
||||
"GL_EXT_secondary_color",
|
||||
"GL_EXT_texture_env_add",
|
||||
"GL_EXT_texture_env_combine",
|
||||
"GL_EXT_texture_env_dot3",
|
||||
"GL_EXT_texture_filter_anisotropic",
|
||||
"GL_EXT_texture_lod_bias",
|
||||
"GL_ATI_texture_mirror_once",
|
||||
"GL_IBM_texture_mirrored_repeat",
|
||||
"GL_NV_blend_square",
|
||||
"GL_SGIS_generate_mipmap",
|
||||
"GL_SGIS_texture_border_clamp",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Initialize the extensions supported by this driver.
|
||||
*/
|
||||
static void radeonInitExtensions( GLcontext *ctx )
|
||||
{
|
||||
unsigned i;
|
||||
_mesa_enable_imaging_extensions( ctx );
|
||||
|
||||
for ( i = 0 ; radeon_extensions[i] != NULL ; i++ ) {
|
||||
_mesa_enable_extension( ctx, radeon_extensions[i] );
|
||||
}
|
||||
}
|
||||
|
||||
extern const struct gl_pipeline_stage _radeon_render_stage;
|
||||
extern const struct gl_pipeline_stage _radeon_tcl_stage;
|
||||
|
||||
static const struct gl_pipeline_stage *radeon_pipeline[] = {
|
||||
|
||||
/* Try and go straight to t&l
|
||||
*/
|
||||
&_radeon_tcl_stage,
|
||||
|
||||
/* Catch any t&l fallbacks
|
||||
*/
|
||||
&_tnl_vertex_transform_stage,
|
||||
&_tnl_normal_transform_stage,
|
||||
&_tnl_lighting_stage,
|
||||
&_tnl_fog_coordinate_stage,
|
||||
&_tnl_texgen_stage,
|
||||
&_tnl_texture_transform_stage,
|
||||
|
||||
/* Try again to go to tcl?
|
||||
* - no good for asymmetric-twoside (do with multipass)
|
||||
* - no good for asymmetric-unfilled (do with multipass)
|
||||
* - good for material
|
||||
* - good for texgen
|
||||
* - need to manipulate a bit of state
|
||||
*
|
||||
* - worth it/not worth it?
|
||||
*/
|
||||
|
||||
/* Else do them here.
|
||||
*/
|
||||
&_radeon_render_stage,
|
||||
&_tnl_render_stage, /* FALLBACK: */
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Initialize the driver's misc functions.
|
||||
*/
|
||||
static void radeonInitDriverFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.GetBufferSize = radeonGetBufferSize;
|
||||
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
|
||||
ctx->Driver.GetString = radeonGetString;
|
||||
|
||||
ctx->Driver.Error = NULL;
|
||||
ctx->Driver.DrawPixels = NULL;
|
||||
ctx->Driver.Bitmap = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create the device specific context.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonCreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
radeonScreenPtr radeonScreen = (radeonScreenPtr)(sPriv->private);
|
||||
radeonContextPtr rmesa;
|
||||
GLcontext *ctx, *shareCtx;
|
||||
int i;
|
||||
|
||||
assert(glVisual);
|
||||
assert(driContextPriv);
|
||||
assert(radeonScreen);
|
||||
|
||||
/* Allocate the Radeon context */
|
||||
rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) );
|
||||
if ( !rmesa )
|
||||
return GL_FALSE;
|
||||
|
||||
/* Allocate the Mesa context */
|
||||
if (sharedContextPrivate)
|
||||
shareCtx = ((radeonContextPtr) sharedContextPrivate)->glCtx;
|
||||
else
|
||||
shareCtx = NULL;
|
||||
rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) rmesa, GL_TRUE);
|
||||
if (!rmesa->glCtx) {
|
||||
FREE(rmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
driContextPriv->driverPrivate = rmesa;
|
||||
|
||||
/* Init radeon context data */
|
||||
rmesa->dri.context = driContextPriv;
|
||||
rmesa->dri.screen = sPriv;
|
||||
rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
|
||||
rmesa->dri.hwContext = driContextPriv->hHWContext;
|
||||
rmesa->dri.hwLock = &sPriv->pSAREA->lock;
|
||||
rmesa->dri.fd = sPriv->fd;
|
||||
|
||||
/* If we don't have 1.3, fallback to the 1.1 interfaces.
|
||||
*/
|
||||
if (getenv("RADEON_COMPAT") || sPriv->drmMinor < 3 )
|
||||
rmesa->dri.drmMinor = 1;
|
||||
else
|
||||
rmesa->dri.drmMinor = sPriv->drmMinor;
|
||||
|
||||
rmesa->radeonScreen = radeonScreen;
|
||||
rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA +
|
||||
radeonScreen->sarea_priv_offset);
|
||||
|
||||
|
||||
rmesa->dma.buf0_address = rmesa->radeonScreen->buffers->list[0].address;
|
||||
|
||||
for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) {
|
||||
make_empty_list( &rmesa->texture.objects[i] );
|
||||
rmesa->texture.heap[i] = mmInit( 0, radeonScreen->texSize[i] );
|
||||
rmesa->texture.age[i] = -1;
|
||||
}
|
||||
rmesa->texture.numHeaps = radeonScreen->numTexHeaps;
|
||||
make_empty_list( &rmesa->texture.swapped );
|
||||
|
||||
rmesa->swtcl.RenderIndex = ~0;
|
||||
rmesa->lost_context = 1;
|
||||
|
||||
/* KW: Set the maximum texture size small enough that we can
|
||||
* guarentee that both texture units can bind a maximal texture
|
||||
* and have them both in on-card memory at once.
|
||||
* Test for 2 textures * 4 bytes/texel * size * size.
|
||||
*/
|
||||
ctx = rmesa->glCtx;
|
||||
if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 2048 * 2048) {
|
||||
ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */
|
||||
}
|
||||
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 1024 * 1024) {
|
||||
ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */
|
||||
}
|
||||
else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 512 * 512) {
|
||||
ctx->Const.MaxTextureLevels = 10; /* 512x512 */
|
||||
}
|
||||
else {
|
||||
ctx->Const.MaxTextureLevels = 9; /* 256x256 */
|
||||
}
|
||||
|
||||
ctx->Const.MaxTextureUnits = 2;
|
||||
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
|
||||
|
||||
/* No wide points.
|
||||
*/
|
||||
ctx->Const.MinPointSize = 1.0;
|
||||
ctx->Const.MinPointSizeAA = 1.0;
|
||||
ctx->Const.MaxPointSize = 1.0;
|
||||
ctx->Const.MaxPointSizeAA = 1.0;
|
||||
|
||||
ctx->Const.MinLineWidth = 1.0;
|
||||
ctx->Const.MinLineWidthAA = 1.0;
|
||||
ctx->Const.MaxLineWidth = 10.0;
|
||||
ctx->Const.MaxLineWidthAA = 10.0;
|
||||
ctx->Const.LineWidthGranularity = 0.0625;
|
||||
|
||||
/* Set maxlocksize (and hence vb size) small enough to avoid
|
||||
* fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
|
||||
* fit in a single dma buffer for indexed rendering of quad strips,
|
||||
* etc.
|
||||
*/
|
||||
/* ctx->Const.MaxArrayLockSize = */
|
||||
/* MIN2( ctx->Const.MaxArrayLockSize, */
|
||||
/* RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); */
|
||||
|
||||
if (getenv("LIBGL_PERFORMANCE_BOXES"))
|
||||
rmesa->boxes = 1;
|
||||
else
|
||||
rmesa->boxes = 0;
|
||||
|
||||
|
||||
/* Initialize the software rasterizer and helper modules.
|
||||
*/
|
||||
_swrast_CreateContext( ctx );
|
||||
_ac_CreateContext( ctx );
|
||||
_tnl_CreateContext( ctx );
|
||||
_swsetup_CreateContext( ctx );
|
||||
_ae_create_context( ctx );
|
||||
|
||||
/* Install the customized pipeline:
|
||||
*/
|
||||
_tnl_destroy_pipeline( ctx );
|
||||
_tnl_install_pipeline( ctx, radeon_pipeline );
|
||||
|
||||
/* Try and keep materials and vertices separate:
|
||||
*/
|
||||
_tnl_isolate_materials( ctx, GL_TRUE );
|
||||
|
||||
|
||||
/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */
|
||||
|
||||
/* Configure swrast to match hardware characteristics:
|
||||
*/
|
||||
_swrast_allow_pixel_fog( ctx, GL_FALSE );
|
||||
_swrast_allow_vertex_fog( ctx, GL_TRUE );
|
||||
|
||||
|
||||
_math_matrix_ctr( &rmesa->TexGenMatrix[0] );
|
||||
_math_matrix_ctr( &rmesa->TexGenMatrix[1] );
|
||||
_math_matrix_ctr( &rmesa->tmpmat );
|
||||
_math_matrix_set_identity( &rmesa->TexGenMatrix[0] );
|
||||
_math_matrix_set_identity( &rmesa->TexGenMatrix[1] );
|
||||
_math_matrix_set_identity( &rmesa->tmpmat );
|
||||
|
||||
radeonInitExtensions( ctx );
|
||||
radeonInitDriverFuncs( ctx );
|
||||
radeonInitIoctlFuncs( ctx );
|
||||
radeonInitStateFuncs( ctx );
|
||||
radeonInitSpanFuncs( ctx );
|
||||
radeonInitTextureFuncs( ctx );
|
||||
radeonInitState( rmesa );
|
||||
radeonInitSwtcl( ctx );
|
||||
|
||||
rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS"));
|
||||
rmesa->irqsEmitted = 0;
|
||||
rmesa->iw.irq_seq = -1;
|
||||
|
||||
rmesa->do_usleeps = !getenv("RADEON_NO_USLEEPS");
|
||||
|
||||
#if DO_DEBUG
|
||||
if (getenv("RADEON_DEBUG_FALLBACKS"))
|
||||
RADEON_DEBUG |= DEBUG_FALLBACKS;
|
||||
|
||||
if (getenv("RADEON_DEBUG_TEXTURE"))
|
||||
RADEON_DEBUG |= DEBUG_TEXTURE;
|
||||
|
||||
if (getenv("RADEON_DEBUG_IOCTL"))
|
||||
RADEON_DEBUG |= DEBUG_IOCTL;
|
||||
|
||||
if (getenv("RADEON_DEBUG_PRIMS"))
|
||||
RADEON_DEBUG |= DEBUG_PRIMS;
|
||||
|
||||
if (getenv("RADEON_DEBUG_VERTS"))
|
||||
RADEON_DEBUG |= DEBUG_VERTS;
|
||||
|
||||
if (getenv("RADEON_DEBUG_STATE"))
|
||||
RADEON_DEBUG |= DEBUG_STATE;
|
||||
|
||||
if (getenv("RADEON_DEBUG_CODEGEN"))
|
||||
RADEON_DEBUG |= DEBUG_CODEGEN;
|
||||
|
||||
if (getenv("RADEON_DEBUG_VTXFMT"))
|
||||
RADEON_DEBUG |= DEBUG_VFMT;
|
||||
|
||||
if (getenv("RADEON_DEBUG_VERBOSE"))
|
||||
RADEON_DEBUG |= DEBUG_VERBOSE;
|
||||
|
||||
if (getenv("RADEON_DEBUG_DRI"))
|
||||
RADEON_DEBUG |= DEBUG_DRI;
|
||||
|
||||
if (getenv("RADEON_DEBUG_DMA"))
|
||||
RADEON_DEBUG |= DEBUG_DMA;
|
||||
|
||||
if (getenv("RADEON_DEBUG_SANITY"))
|
||||
RADEON_DEBUG |= DEBUG_SANITY;
|
||||
|
||||
if (getenv("RADEON_DEBUG"))
|
||||
{
|
||||
const char *debug = getenv("RADEON_DEBUG");
|
||||
if (strstr(debug, "fall"))
|
||||
RADEON_DEBUG |= DEBUG_FALLBACKS;
|
||||
|
||||
if (strstr(debug, "tex"))
|
||||
RADEON_DEBUG |= DEBUG_TEXTURE;
|
||||
|
||||
if (strstr(debug, "ioctl"))
|
||||
RADEON_DEBUG |= DEBUG_IOCTL;
|
||||
|
||||
if (strstr(debug, "prim"))
|
||||
RADEON_DEBUG |= DEBUG_PRIMS;
|
||||
|
||||
if (strstr(debug, "vert"))
|
||||
RADEON_DEBUG |= DEBUG_VERTS;
|
||||
|
||||
if (strstr(debug, "state"))
|
||||
RADEON_DEBUG |= DEBUG_STATE;
|
||||
|
||||
if (strstr(debug, "code"))
|
||||
RADEON_DEBUG |= DEBUG_CODEGEN;
|
||||
|
||||
if (strstr(debug, "vfmt") || strstr(debug, "vtxf"))
|
||||
RADEON_DEBUG |= DEBUG_VFMT;
|
||||
|
||||
if (strstr(debug, "verb"))
|
||||
RADEON_DEBUG |= DEBUG_VERBOSE;
|
||||
|
||||
if (strstr(debug, "dri"))
|
||||
RADEON_DEBUG |= DEBUG_DRI;
|
||||
|
||||
if (strstr(debug, "dma"))
|
||||
RADEON_DEBUG |= DEBUG_DMA;
|
||||
|
||||
if (strstr(debug, "san"))
|
||||
RADEON_DEBUG |= DEBUG_SANITY;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
if (getenv("RADEON_NO_RAST")) {
|
||||
fprintf(stderr, "disabling 3D acceleration\n");
|
||||
FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
|
||||
}
|
||||
else if (getenv("RADEON_TCL_FORCE_ENABLE")) {
|
||||
fprintf(stderr, "Enabling TCL support... this will probably crash\n");
|
||||
fprintf(stderr, " your card if it isn't capable of TCL!\n");
|
||||
rmesa->radeonScreen->chipset |= RADEON_CHIPSET_TCL;
|
||||
} else if (getenv("RADEON_TCL_FORCE_DISABLE") ||
|
||||
rmesa->dri.drmMinor < 3 ||
|
||||
!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
|
||||
rmesa->radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
|
||||
fprintf(stderr, "disabling TCL support\n");
|
||||
TCL_FALLBACK(rmesa->glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
|
||||
}
|
||||
|
||||
if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
|
||||
if (!getenv("RADEON_NO_VTXFMT"))
|
||||
radeonVtxfmtInit( ctx );
|
||||
|
||||
_tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Destroy the device specific context.
|
||||
*/
|
||||
/* Destroy the Mesa and driver specific context data.
|
||||
*/
|
||||
static void
|
||||
radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate;
|
||||
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
|
||||
|
||||
/* check if we're deleting the currently bound context */
|
||||
if (rmesa == current) {
|
||||
RADEON_FIREVERTICES( rmesa );
|
||||
_mesa_make_current2(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Free radeon context resources */
|
||||
assert(rmesa); /* should never be null */
|
||||
if ( rmesa ) {
|
||||
if (rmesa->glCtx->Shared->RefCount == 1) {
|
||||
/* This share group is about to go away, free our private
|
||||
* texture object data.
|
||||
*/
|
||||
radeonTexObjPtr t, next_t;
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) {
|
||||
foreach_s ( t, next_t, &rmesa->texture.objects[i] ) {
|
||||
radeonDestroyTexObj( rmesa, t );
|
||||
}
|
||||
mmDestroy( rmesa->texture.heap[i] );
|
||||
rmesa->texture.heap[i] = NULL;
|
||||
}
|
||||
|
||||
foreach_s ( t, next_t, &rmesa->texture.swapped ) {
|
||||
radeonDestroyTexObj( rmesa, t );
|
||||
}
|
||||
}
|
||||
|
||||
_swsetup_DestroyContext( rmesa->glCtx );
|
||||
_tnl_DestroyContext( rmesa->glCtx );
|
||||
_ac_DestroyContext( rmesa->glCtx );
|
||||
_swrast_DestroyContext( rmesa->glCtx );
|
||||
|
||||
radeonDestroySwtcl( rmesa->glCtx );
|
||||
|
||||
radeonReleaseArrays( rmesa->glCtx, ~0 );
|
||||
if (rmesa->dma.current.buf) {
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
|
||||
radeonFlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
}
|
||||
|
||||
if (!rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
|
||||
if (!getenv("RADEON_NO_VTXFMT"))
|
||||
radeonVtxfmtDestroy( rmesa->glCtx );
|
||||
|
||||
/* free the Mesa context */
|
||||
rmesa->glCtx->DriverCtx = NULL;
|
||||
_mesa_destroy_context( rmesa->glCtx );
|
||||
|
||||
if (rmesa->state.scissor.pClipRects) {
|
||||
FREE(rmesa->state.scissor.pClipRects);
|
||||
rmesa->state.scissor.pClipRects = 0;
|
||||
}
|
||||
|
||||
FREE( rmesa );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Use this to force shared object profiling. */
|
||||
glx_fini_prof();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the driver specific screen private data.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonInitDriver( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
sPriv->private = (void *) radeonCreateScreen( sPriv );
|
||||
if ( !sPriv->private ) {
|
||||
radeonDestroyScreen( sPriv );
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Create and initialize the Mesa and driver specific pixmap buffer
|
||||
* data.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
|
||||
{
|
||||
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
radeonContextPtr rmesa;
|
||||
GLcontext *ctx;
|
||||
rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
||||
ctx = rmesa->glCtx;
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
|
||||
|
||||
if ( rmesa->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, "radeonSwapBuffers: drawable has no context!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Force the context `c' to be the current context and associate with it
|
||||
* buffer `b'.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv )
|
||||
{
|
||||
if ( driContextPriv ) {
|
||||
radeonContextPtr newRadeonCtx =
|
||||
(radeonContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newRadeonCtx->glCtx);
|
||||
|
||||
if ( newRadeonCtx->dri.drawable != driDrawPriv ) {
|
||||
newRadeonCtx->dri.drawable = driDrawPriv;
|
||||
radeonUpdateWindow( newRadeonCtx->glCtx );
|
||||
radeonUpdateViewportOffset( newRadeonCtx->glCtx );
|
||||
}
|
||||
|
||||
_mesa_make_current2( newRadeonCtx->glCtx,
|
||||
(GLframebuffer *) driDrawPriv->driverPrivate,
|
||||
(GLframebuffer *) driReadPriv->driverPrivate );
|
||||
|
||||
if ( !newRadeonCtx->glCtx->Viewport.Width ) {
|
||||
_mesa_set_viewport( newRadeonCtx->glCtx, 0, 0,
|
||||
driDrawPriv->w, driDrawPriv->h );
|
||||
}
|
||||
|
||||
if (newRadeonCtx->vb.enabled)
|
||||
radeonVtxfmtMakeCurrent( newRadeonCtx->glCtx );
|
||||
|
||||
} else {
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, NULL);
|
||||
_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.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonUnbindContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_DRI)
|
||||
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx);
|
||||
|
||||
radeonVtxfmtUnbindContext( rmesa->glCtx );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Fullscreen mode isn't used for much -- could be a way to shrink
|
||||
* front/back buffers & get more texture memory if the client has
|
||||
* changed the video resolution.
|
||||
*
|
||||
* Pageflipping is now done automatically whenever there is a single
|
||||
* 3d client.
|
||||
*/
|
||||
static GLboolean
|
||||
radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
__driRegisterExtensions( void )
|
||||
{
|
||||
/* See r200 driver for info */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct __DriverAPIRec radeonAPI = {
|
||||
radeonInitDriver,
|
||||
radeonDestroyScreen,
|
||||
radeonCreateContext,
|
||||
radeonDestroyContext,
|
||||
radeonCreateBuffer,
|
||||
radeonDestroyBuffer,
|
||||
radeonSwapBuffers,
|
||||
radeonMakeCurrent,
|
||||
radeonUnbindContext,
|
||||
radeonOpenCloseFullScreen,
|
||||
radeonOpenCloseFullScreen
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the bootstrap function for the driver.
|
||||
* The __driCreateScreen name is the symbol that libGL.so fetches.
|
||||
* Return: pointer to a __DRIscreenPrivate.
|
||||
*/
|
||||
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
|
||||
int numConfigs, __GLXvisualConfig *config)
|
||||
{
|
||||
__DRIscreenPrivate *psp;
|
||||
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
|
||||
return (void *) psp;
|
||||
}
|
||||
814
src/mesa/drivers/dri/radeon/radeon_context.h
Normal file
814
src/mesa/drivers/dri/radeon/radeon_context.h
Normal file
|
|
@ -0,0 +1,814 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.4 2002/09/10 00:39:39 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_CONTEXT_H__
|
||||
#define __RADEON_CONTEXT_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
struct radeon_context;
|
||||
typedef struct radeon_context radeonContextRec;
|
||||
typedef struct radeon_context *radeonContextPtr;
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "radeon_lock.h"
|
||||
#include "radeon_screen.h"
|
||||
#include "mm.h"
|
||||
|
||||
/* Flags for software fallback cases */
|
||||
/* See correponding strings in radeon_swtcl.c */
|
||||
#define RADEON_FALLBACK_TEXTURE 0x0001
|
||||
#define RADEON_FALLBACK_DRAW_BUFFER 0x0002
|
||||
#define RADEON_FALLBACK_STENCIL 0x0004
|
||||
#define RADEON_FALLBACK_RENDER_MODE 0x0008
|
||||
#define RADEON_FALLBACK_BLEND_EQ 0x0010
|
||||
#define RADEON_FALLBACK_BLEND_FUNC 0x0020
|
||||
#define RADEON_FALLBACK_DISABLE 0x0040
|
||||
|
||||
/* Use the templated vertex format:
|
||||
*/
|
||||
#define COLOR_IS_RGBA
|
||||
#define TAG(x) radeon##x
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
typedef void (*radeon_tri_func)( radeonContextPtr,
|
||||
radeonVertex *,
|
||||
radeonVertex *,
|
||||
radeonVertex * );
|
||||
|
||||
typedef void (*radeon_line_func)( radeonContextPtr,
|
||||
radeonVertex *,
|
||||
radeonVertex * );
|
||||
|
||||
typedef void (*radeon_point_func)( radeonContextPtr,
|
||||
radeonVertex * );
|
||||
|
||||
|
||||
struct radeon_colorbuffer_state {
|
||||
GLuint clear;
|
||||
GLint drawOffset, drawPitch;
|
||||
};
|
||||
|
||||
|
||||
struct radeon_depthbuffer_state {
|
||||
GLuint clear;
|
||||
GLfloat scale;
|
||||
};
|
||||
|
||||
struct radeon_pixel_state {
|
||||
GLint readOffset, readPitch;
|
||||
};
|
||||
|
||||
struct radeon_scissor_state {
|
||||
XF86DRIClipRectRec rect;
|
||||
GLboolean enabled;
|
||||
|
||||
GLuint numClipRects; /* Cliprects active */
|
||||
GLuint numAllocedClipRects; /* Cliprects available */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
};
|
||||
|
||||
struct radeon_stencilbuffer_state {
|
||||
GLboolean hwBuffer;
|
||||
GLuint clear; /* rb3d_stencilrefmask value */
|
||||
};
|
||||
|
||||
struct radeon_stipple_state {
|
||||
GLuint mask[32];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define TEX_0 0x1
|
||||
#define TEX_1 0x2
|
||||
#define TEX_ALL 0x3
|
||||
|
||||
typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr;
|
||||
|
||||
/* Texture object in locally shared texture space.
|
||||
*/
|
||||
struct radeon_tex_obj {
|
||||
radeonTexObjPtr next, prev;
|
||||
|
||||
struct gl_texture_object *tObj; /* Mesa texture object */
|
||||
|
||||
PMemBlock memBlock; /* Memory block containing texture */
|
||||
GLuint bufAddr; /* Offset to start of locally
|
||||
shared texture block */
|
||||
|
||||
GLuint dirty_images; /* Flags for whether or not
|
||||
images need to be uploaded to
|
||||
local or AGP texture space */
|
||||
|
||||
GLuint dirty_state; /* Flags (1 per texunit) for
|
||||
whether or not this texobj
|
||||
has dirty hardware state
|
||||
(pp_*) that needs to be
|
||||
brought into the
|
||||
texunit. */
|
||||
|
||||
GLint heap; /* Texture heap currently stored in */
|
||||
|
||||
drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS];
|
||||
|
||||
GLint totalSize; /* Total size of the texture
|
||||
including all mipmap levels */
|
||||
|
||||
GLuint pp_txfilter; /* hardware register values */
|
||||
GLuint pp_txformat;
|
||||
GLuint pp_txoffset;
|
||||
GLuint pp_border_color;
|
||||
|
||||
/* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the
|
||||
* images to upload.
|
||||
*/
|
||||
GLint firstLevel;
|
||||
GLint lastLevel;
|
||||
};
|
||||
|
||||
|
||||
struct radeon_texture_env_state {
|
||||
radeonTexObjPtr texobj;
|
||||
GLenum format;
|
||||
GLenum envMode;
|
||||
};
|
||||
|
||||
struct radeon_texture_state {
|
||||
struct radeon_texture_env_state unit[RADEON_MAX_TEXTURE_UNITS];
|
||||
};
|
||||
|
||||
|
||||
struct radeon_state_atom {
|
||||
struct radeon_state_atom *next, *prev;
|
||||
const char *name; /* for debug */
|
||||
int cmd_size; /* size in bytes */
|
||||
GLuint is_tcl;
|
||||
int *cmd; /* one or more cmd's */
|
||||
int *lastcmd; /* one or more cmd's */
|
||||
GLboolean (*check)( GLcontext * ); /* is this state active? */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Trying to keep these relatively short as the variables are becoming
|
||||
* extravagently long. Drop the RADEON_ off the front of everything -
|
||||
* I think we know we're in the radeon driver by now, and keep the
|
||||
* prefix to 3 letters unless absolutely impossible.
|
||||
*/
|
||||
|
||||
#define CTX_CMD_0 0
|
||||
#define CTX_PP_MISC 1
|
||||
#define CTX_PP_FOG_COLOR 2
|
||||
#define CTX_RE_SOLID_COLOR 3
|
||||
#define CTX_RB3D_BLENDCNTL 4
|
||||
#define CTX_RB3D_DEPTHOFFSET 5
|
||||
#define CTX_RB3D_DEPTHPITCH 6
|
||||
#define CTX_RB3D_ZSTENCILCNTL 7
|
||||
#define CTX_CMD_1 8
|
||||
#define CTX_PP_CNTL 9
|
||||
#define CTX_RB3D_CNTL 10
|
||||
#define CTX_RB3D_COLOROFFSET 11
|
||||
#define CTX_CMD_2 12
|
||||
#define CTX_RB3D_COLORPITCH 13
|
||||
#define CTX_STATE_SIZE 14
|
||||
|
||||
#define SET_CMD_0 0
|
||||
#define SET_SE_CNTL 1
|
||||
#define SET_SE_COORDFMT 2
|
||||
#define SET_CMD_1 3
|
||||
#define SET_SE_CNTL_STATUS 4
|
||||
#define SET_STATE_SIZE 5
|
||||
|
||||
#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 MSC_CMD_0 0
|
||||
#define MSC_RE_MISC 1
|
||||
#define MSC_STATE_SIZE 2
|
||||
|
||||
#define TEX_CMD_0 0
|
||||
#define TEX_PP_TXFILTER 1
|
||||
#define TEX_PP_TXFORMAT 2
|
||||
#define TEX_PP_TXOFFSET 3
|
||||
#define TEX_PP_TXCBLEND 4
|
||||
#define TEX_PP_TXABLEND 5
|
||||
#define TEX_PP_TFACTOR 6
|
||||
#define TEX_CMD_1 7
|
||||
#define TEX_PP_BORDER_COLOR 8
|
||||
#define TEX_STATE_SIZE 9
|
||||
|
||||
#define ZBS_CMD_0 0
|
||||
#define ZBS_SE_ZBIAS_FACTOR 1
|
||||
#define ZBS_SE_ZBIAS_CONSTANT 2
|
||||
#define ZBS_STATE_SIZE 3
|
||||
|
||||
#define TCL_CMD_0 0
|
||||
#define TCL_OUTPUT_VTXFMT 1
|
||||
#define TCL_OUTPUT_VTXSEL 2
|
||||
#define TCL_MATRIX_SELECT_0 3
|
||||
#define TCL_MATRIX_SELECT_1 4
|
||||
#define TCL_UCP_VERT_BLEND_CTL 5
|
||||
#define TCL_TEXTURE_PROC_CTL 6
|
||||
#define TCL_LIGHT_MODEL_CTL 7
|
||||
#define TCL_PER_LIGHT_CTL_0 8
|
||||
#define TCL_PER_LIGHT_CTL_1 9
|
||||
#define TCL_PER_LIGHT_CTL_2 10
|
||||
#define TCL_PER_LIGHT_CTL_3 11
|
||||
#define TCL_STATE_SIZE 12
|
||||
|
||||
#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_SHININESS 17
|
||||
#define MTL_STATE_SIZE 18
|
||||
|
||||
#define VTX_CMD_0 0
|
||||
#define VTX_SE_COORD_FMT 1
|
||||
#define VTX_STATE_SIZE 2
|
||||
|
||||
#define MAT_CMD_0 0
|
||||
#define MAT_ELT_0 1
|
||||
#define MAT_STATE_SIZE 17
|
||||
|
||||
#define GRD_CMD_0 0
|
||||
#define GRD_VERT_GUARD_CLIP_ADJ 1
|
||||
#define GRD_VERT_GUARD_DISCARD_ADJ 2
|
||||
#define GRD_HORZ_GUARD_CLIP_ADJ 3
|
||||
#define GRD_HORZ_GUARD_DISCARD_ADJ 4
|
||||
#define GRD_STATE_SIZE 5
|
||||
|
||||
/* position changes frequently when lighting in modelpos - separate
|
||||
* out to new state item?
|
||||
*/
|
||||
#define LIT_CMD_0 0
|
||||
#define LIT_AMBIENT_RED 1
|
||||
#define LIT_AMBIENT_GREEN 2
|
||||
#define LIT_AMBIENT_BLUE 3
|
||||
#define LIT_AMBIENT_ALPHA 4
|
||||
#define LIT_DIFFUSE_RED 5
|
||||
#define LIT_DIFFUSE_GREEN 6
|
||||
#define LIT_DIFFUSE_BLUE 7
|
||||
#define LIT_DIFFUSE_ALPHA 8
|
||||
#define LIT_SPECULAR_RED 9
|
||||
#define LIT_SPECULAR_GREEN 10
|
||||
#define LIT_SPECULAR_BLUE 11
|
||||
#define LIT_SPECULAR_ALPHA 12
|
||||
#define LIT_POSITION_X 13
|
||||
#define LIT_POSITION_Y 14
|
||||
#define LIT_POSITION_Z 15
|
||||
#define LIT_POSITION_W 16
|
||||
#define LIT_DIRECTION_X 17
|
||||
#define LIT_DIRECTION_Y 18
|
||||
#define LIT_DIRECTION_Z 19
|
||||
#define LIT_DIRECTION_W 20
|
||||
#define LIT_ATTEN_CONST 21
|
||||
#define LIT_ATTEN_LINEAR 22
|
||||
#define LIT_ATTEN_QUADRATIC 23
|
||||
#define LIT_ATTEN_XXX 24
|
||||
#define LIT_CMD_1 25
|
||||
#define LIT_SPOT_DCD 26
|
||||
#define LIT_SPOT_EXPONENT 27
|
||||
#define LIT_SPOT_CUTOFF 28
|
||||
#define LIT_SPECULAR_THRESH 29
|
||||
#define LIT_RANGE_CUTOFF 30 /* ? */
|
||||
#define LIT_RANGE_ATTEN 31 /* ? */
|
||||
#define LIT_STATE_SIZE 32
|
||||
|
||||
/* 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
|
||||
|
||||
#define SHN_CMD_0 0
|
||||
#define SHN_SHININESS 1
|
||||
#define SHN_STATE_SIZE 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct radeon_hw_state {
|
||||
/* All state should be on one of these lists:
|
||||
*/
|
||||
struct radeon_state_atom dirty; /* dirty list head placeholder */
|
||||
struct radeon_state_atom clean; /* clean list head placeholder */
|
||||
|
||||
/* Hardware state, stored as cmdbuf commands:
|
||||
* -- Need to doublebuffer for
|
||||
* - reviving state after loss of context
|
||||
* - eliding noop statechange loops? (except line stipple count)
|
||||
*/
|
||||
struct radeon_state_atom ctx;
|
||||
struct radeon_state_atom set;
|
||||
struct radeon_state_atom lin;
|
||||
struct radeon_state_atom msk;
|
||||
struct radeon_state_atom vpt;
|
||||
struct radeon_state_atom tcl;
|
||||
struct radeon_state_atom msc;
|
||||
struct radeon_state_atom tex[2];
|
||||
struct radeon_state_atom zbs;
|
||||
struct radeon_state_atom mtl;
|
||||
struct radeon_state_atom mat[5];
|
||||
struct radeon_state_atom lit[8]; /* includes vec, scl commands */
|
||||
struct radeon_state_atom ucp[6];
|
||||
struct radeon_state_atom eye; /* eye pos */
|
||||
struct radeon_state_atom grd; /* guard band clipping */
|
||||
struct radeon_state_atom fog;
|
||||
struct radeon_state_atom glt;
|
||||
};
|
||||
|
||||
struct radeon_state {
|
||||
/* Derived state for internal purposes:
|
||||
*/
|
||||
struct radeon_colorbuffer_state color;
|
||||
struct radeon_depthbuffer_state depth;
|
||||
struct radeon_pixel_state pixel;
|
||||
struct radeon_scissor_state scissor;
|
||||
struct radeon_stencilbuffer_state stencil;
|
||||
struct radeon_stipple_state stipple;
|
||||
struct radeon_texture_state texture;
|
||||
};
|
||||
|
||||
struct radeon_texture {
|
||||
radeonTexObj objects[RADEON_NR_TEX_HEAPS];
|
||||
radeonTexObj swapped;
|
||||
|
||||
memHeap_t *heap[RADEON_NR_TEX_HEAPS];
|
||||
GLint age[RADEON_NR_TEX_HEAPS];
|
||||
|
||||
GLint numHeaps;
|
||||
};
|
||||
|
||||
/* Need refcounting on dma buffers:
|
||||
*/
|
||||
struct radeon_dma_buffer {
|
||||
int refcount; /* the number of retained regions in buf */
|
||||
drmBufPtr buf;
|
||||
};
|
||||
|
||||
#define GET_START(rvb) (rmesa->radeonScreen->agp_buffer_offset + \
|
||||
(rvb)->address - rmesa->dma.buf0_address + \
|
||||
(rvb)->start)
|
||||
|
||||
/* A retained region, eg vertices for indexed vertices.
|
||||
*/
|
||||
struct radeon_dma_region {
|
||||
struct radeon_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 radeon_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 radeon_dma_region current;
|
||||
|
||||
void (*flush)( radeonContextPtr );
|
||||
|
||||
char *buf0_address; /* start of buf[0], for index calcs */
|
||||
GLuint nr_released_bufs; /* flush after so many buffers released */
|
||||
};
|
||||
|
||||
struct radeon_dri_mirror {
|
||||
__DRIcontextPrivate *context; /* DRI context */
|
||||
__DRIscreenPrivate *screen; /* DRI screen */
|
||||
__DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
|
||||
|
||||
drmContext hwContext;
|
||||
drmLock *hwLock;
|
||||
int fd;
|
||||
int drmMinor;
|
||||
};
|
||||
|
||||
|
||||
#define RADEON_CMD_BUF_SZ (8*1024)
|
||||
|
||||
struct radeon_store {
|
||||
GLuint statenr;
|
||||
GLuint primnr;
|
||||
char cmd_buf[RADEON_CMD_BUF_SZ];
|
||||
int cmd_used;
|
||||
int elts_start;
|
||||
};
|
||||
|
||||
|
||||
/* radeon_tcl.c
|
||||
*/
|
||||
struct radeon_tcl_info {
|
||||
GLuint vertex_format;
|
||||
GLint last_offset;
|
||||
GLuint hw_primitive;
|
||||
|
||||
struct radeon_dma_region *aos_components[8];
|
||||
GLuint nr_aos_components;
|
||||
|
||||
GLuint *Elts;
|
||||
|
||||
struct radeon_dma_region indexed_verts;
|
||||
struct radeon_dma_region obj;
|
||||
struct radeon_dma_region rgba;
|
||||
struct radeon_dma_region spec;
|
||||
struct radeon_dma_region fog;
|
||||
struct radeon_dma_region tex[RADEON_MAX_TEXTURE_UNITS];
|
||||
struct radeon_dma_region norm;
|
||||
};
|
||||
|
||||
|
||||
/* radeon_swtcl.c
|
||||
*/
|
||||
struct radeon_swtcl_info {
|
||||
GLuint SetupIndex;
|
||||
GLuint SetupNewInputs;
|
||||
GLuint RenderIndex;
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_stride_shift;
|
||||
GLuint vertex_format;
|
||||
char *verts;
|
||||
|
||||
/* Fallback rasterization functions
|
||||
*/
|
||||
radeon_point_func draw_point;
|
||||
radeon_line_func draw_line;
|
||||
radeon_tri_func draw_tri;
|
||||
|
||||
GLuint hw_primitive;
|
||||
GLenum render_primitive;
|
||||
GLuint numverts;
|
||||
|
||||
struct radeon_dma_region indexed_verts;
|
||||
};
|
||||
|
||||
|
||||
struct radeon_ioctl {
|
||||
GLuint vertex_offset;
|
||||
GLuint vertex_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define RADEON_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;
|
||||
char *code;
|
||||
};
|
||||
|
||||
struct dfn_lists {
|
||||
struct dynfn Vertex2f;
|
||||
struct dynfn Vertex2fv;
|
||||
struct dynfn Vertex3f;
|
||||
struct dynfn Vertex3fv;
|
||||
struct dynfn Color4ub;
|
||||
struct dynfn Color4ubv;
|
||||
struct dynfn Color3ub;
|
||||
struct dynfn Color3ubv;
|
||||
struct dynfn Color4f;
|
||||
struct dynfn Color4fv;
|
||||
struct dynfn Color3f;
|
||||
struct dynfn Color3fv;
|
||||
struct dynfn SecondaryColor3ubEXT;
|
||||
struct dynfn SecondaryColor3ubvEXT;
|
||||
struct dynfn SecondaryColor3fEXT;
|
||||
struct dynfn SecondaryColor3fvEXT;
|
||||
struct dynfn Normal3f;
|
||||
struct dynfn Normal3fv;
|
||||
struct dynfn TexCoord2f;
|
||||
struct dynfn TexCoord2fv;
|
||||
struct dynfn TexCoord1f;
|
||||
struct dynfn TexCoord1fv;
|
||||
struct dynfn MultiTexCoord2fARB;
|
||||
struct dynfn MultiTexCoord2fvARB;
|
||||
struct dynfn MultiTexCoord1fARB;
|
||||
struct dynfn MultiTexCoord1fvARB;
|
||||
};
|
||||
|
||||
struct _vb;
|
||||
|
||||
struct dfn_generators {
|
||||
struct dynfn *(*Vertex2f)( GLcontext *, int );
|
||||
struct dynfn *(*Vertex2fv)( GLcontext *, int );
|
||||
struct dynfn *(*Vertex3f)( GLcontext *, int );
|
||||
struct dynfn *(*Vertex3fv)( GLcontext *, int );
|
||||
struct dynfn *(*Color4ub)( GLcontext *, int );
|
||||
struct dynfn *(*Color4ubv)( GLcontext *, int );
|
||||
struct dynfn *(*Color3ub)( GLcontext *, int );
|
||||
struct dynfn *(*Color3ubv)( GLcontext *, int );
|
||||
struct dynfn *(*Color4f)( GLcontext *, int );
|
||||
struct dynfn *(*Color4fv)( GLcontext *, int );
|
||||
struct dynfn *(*Color3f)( GLcontext *, int );
|
||||
struct dynfn *(*Color3fv)( GLcontext *, int );
|
||||
struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int );
|
||||
struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int );
|
||||
struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int );
|
||||
struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int );
|
||||
struct dynfn *(*Normal3f)( GLcontext *, int );
|
||||
struct dynfn *(*Normal3fv)( GLcontext *, int );
|
||||
struct dynfn *(*TexCoord2f)( GLcontext *, int );
|
||||
struct dynfn *(*TexCoord2fv)( GLcontext *, int );
|
||||
struct dynfn *(*TexCoord1f)( GLcontext *, int );
|
||||
struct dynfn *(*TexCoord1fv)( GLcontext *, int );
|
||||
struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int );
|
||||
struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int );
|
||||
struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int );
|
||||
struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int );
|
||||
};
|
||||
|
||||
|
||||
struct radeon_vb {
|
||||
/* Keep these first: referenced from codegen templates:
|
||||
*/
|
||||
GLint counter, initial_counter;
|
||||
GLint *dmaptr;
|
||||
void (*notify)( void );
|
||||
GLint vertex_size;
|
||||
union { float f; int i; radeon_color_t color; } vertex[15];
|
||||
|
||||
GLfloat *normalptr;
|
||||
GLfloat *floatcolorptr;
|
||||
radeon_color_t *colorptr;
|
||||
radeon_color_t *specptr;
|
||||
GLfloat *texcoordptr[2];
|
||||
|
||||
GLcontext *context; /* current context : Single thread only! */
|
||||
};
|
||||
|
||||
struct radeon_prim {
|
||||
GLuint start;
|
||||
GLuint end;
|
||||
GLuint prim;
|
||||
};
|
||||
|
||||
struct radeon_vbinfo {
|
||||
GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
|
||||
GLuint primflags;
|
||||
GLboolean enabled; /* RADEON_NO_VTXFMT//RADEON_NO_TCL env vars */
|
||||
GLboolean installed;
|
||||
GLboolean fell_back;
|
||||
GLboolean recheck;
|
||||
GLint initial_counter;
|
||||
GLint nrverts;
|
||||
GLuint vertex_format;
|
||||
|
||||
GLuint installed_vertex_format;
|
||||
GLuint installed_color_3f_sz;
|
||||
|
||||
struct radeon_prim primlist[RADEON_MAX_PRIMS];
|
||||
int nrprims;
|
||||
|
||||
struct dfn_lists dfn_cache;
|
||||
struct dfn_generators codegen;
|
||||
GLvertexformat vtxfmt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct radeon_context {
|
||||
GLcontext *glCtx; /* Mesa context */
|
||||
|
||||
/* Driver and hardware state management
|
||||
*/
|
||||
struct radeon_hw_state hw;
|
||||
struct radeon_state state;
|
||||
|
||||
/* Texture object bookkeeping
|
||||
*/
|
||||
struct radeon_texture texture;
|
||||
|
||||
|
||||
/* Rasterization and vertex state:
|
||||
*/
|
||||
GLuint TclFallback;
|
||||
GLuint Fallback;
|
||||
GLuint NewGLState;
|
||||
|
||||
|
||||
/* Temporaries for translating away float colors:
|
||||
*/
|
||||
struct gl_client_array UbyteColor;
|
||||
struct gl_client_array UbyteSecondaryColor;
|
||||
|
||||
/* Vertex buffers
|
||||
*/
|
||||
struct radeon_ioctl ioctl;
|
||||
struct radeon_dma dma;
|
||||
struct radeon_store store;
|
||||
|
||||
/* Page flipping
|
||||
*/
|
||||
GLuint doPageFlip;
|
||||
|
||||
/* Busy waiting
|
||||
*/
|
||||
GLuint do_usleeps;
|
||||
GLuint do_irqs;
|
||||
GLuint irqsEmitted;
|
||||
drmRadeonIrqWait iw;
|
||||
|
||||
/* Drawable, cliprect and scissor information
|
||||
*/
|
||||
GLuint numClipRects; /* Cliprects for the draw buffer */
|
||||
XF86DRIClipRectPtr pClipRects;
|
||||
unsigned int lastStamp;
|
||||
GLboolean lost_context;
|
||||
radeonScreenPtr radeonScreen; /* Screen private DRI data */
|
||||
RADEONSAREAPrivPtr sarea; /* Private SAREA data */
|
||||
|
||||
/* TCL stuff
|
||||
*/
|
||||
GLmatrix TexGenMatrix[RADEON_MAX_TEXTURE_UNITS];
|
||||
GLboolean recheck_texgen[RADEON_MAX_TEXTURE_UNITS];
|
||||
GLboolean TexGenNeedNormals[RADEON_MAX_TEXTURE_UNITS];
|
||||
GLuint TexMatEnabled;
|
||||
GLuint TexGenEnabled;
|
||||
GLmatrix tmpmat;
|
||||
GLuint last_ReallyEnabled;
|
||||
|
||||
/* VBI
|
||||
*/
|
||||
GLuint vbl_seq;
|
||||
|
||||
/* radeon_tcl.c
|
||||
*/
|
||||
struct radeon_tcl_info tcl;
|
||||
|
||||
/* radeon_swtcl.c
|
||||
*/
|
||||
struct radeon_swtcl_info swtcl;
|
||||
|
||||
/* radeon_vtxfmt.c
|
||||
*/
|
||||
struct radeon_vbinfo vb;
|
||||
|
||||
/* Mirrors of some DRI state
|
||||
*/
|
||||
struct radeon_dri_mirror dri;
|
||||
|
||||
|
||||
/* Performance counters
|
||||
*/
|
||||
GLuint boxes; /* Draw performance boxes */
|
||||
GLuint hardwareWentIdle;
|
||||
GLuint c_clears;
|
||||
GLuint c_drawWaits;
|
||||
GLuint c_textureSwaps;
|
||||
GLuint c_textureBytes;
|
||||
GLuint c_vertexBuffers;
|
||||
};
|
||||
|
||||
#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx))
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#define RADEON_OLD_PACKETS 1
|
||||
|
||||
/* ================================================================
|
||||
* Debugging:
|
||||
*/
|
||||
#define DO_DEBUG 1
|
||||
|
||||
#if DO_DEBUG
|
||||
extern int RADEON_DEBUG;
|
||||
#else
|
||||
#define RADEON_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define DEBUG_TEXTURE 0x001
|
||||
#define DEBUG_STATE 0x002
|
||||
#define DEBUG_IOCTL 0x004
|
||||
#define DEBUG_PRIMS 0x008
|
||||
#define DEBUG_VERTS 0x010
|
||||
#define DEBUG_FALLBACKS 0x020
|
||||
#define DEBUG_VFMT 0x040
|
||||
#define DEBUG_CODEGEN 0x080
|
||||
#define DEBUG_VERBOSE 0x100
|
||||
#define DEBUG_DRI 0x200
|
||||
#define DEBUG_DMA 0x400
|
||||
#define DEBUG_SANITY 0x800
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_CONTEXT_H__ */
|
||||
1120
src/mesa/drivers/dri/radeon/radeon_ioctl.c
Normal file
1120
src/mesa/drivers/dri/radeon/radeon_ioctl.c
Normal file
File diff suppressed because it is too large
Load diff
178
src/mesa/drivers/dri/radeon/radeon_ioctl.h
Normal file
178
src/mesa/drivers/dri/radeon/radeon_ioctl.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.4 2002/09/16 18:05:20 eich Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_IOCTL_H__
|
||||
#define __RADEON_IOCTL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "simple_list.h"
|
||||
#include "radeon_lock.h"
|
||||
|
||||
|
||||
extern void radeonEmitState( radeonContextPtr rmesa );
|
||||
extern void radeonEmitVertexAOS( radeonContextPtr rmesa,
|
||||
GLuint vertex_size,
|
||||
GLuint offset );
|
||||
|
||||
extern void radeonEmitVbufPrim( radeonContextPtr rmesa,
|
||||
GLuint vertex_format,
|
||||
GLuint primitive,
|
||||
GLuint vertex_nr );
|
||||
|
||||
extern void radeonFlushElts( radeonContextPtr rmesa );
|
||||
|
||||
extern GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
|
||||
GLuint vertex_format,
|
||||
GLuint primitive,
|
||||
GLuint min_nr );
|
||||
|
||||
extern void radeonEmitAOS( radeonContextPtr rmesa,
|
||||
struct radeon_dma_region **regions,
|
||||
GLuint n,
|
||||
GLuint offset );
|
||||
|
||||
|
||||
|
||||
extern void radeonFlushCmdBuf( radeonContextPtr rmesa, const char * );
|
||||
extern void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa );
|
||||
|
||||
extern void radeonAllocDmaRegion( radeonContextPtr rmesa,
|
||||
struct radeon_dma_region *region,
|
||||
int bytes,
|
||||
int alignment );
|
||||
|
||||
extern void radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
|
||||
struct radeon_dma_region *region,
|
||||
int numverts,
|
||||
int vertsize,
|
||||
int alignment );
|
||||
|
||||
extern void radeonReleaseDmaRegion( radeonContextPtr rmesa,
|
||||
struct radeon_dma_region *region,
|
||||
const char *caller );
|
||||
|
||||
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 rmesa );
|
||||
extern void radeonWaitForVBlank( radeonContextPtr rmesa );
|
||||
extern void radeonInitIoctlFuncs( GLcontext *ctx );
|
||||
extern void radeonGetAllParams( radeonContextPtr rmesa );
|
||||
|
||||
/* radeon_compat.c:
|
||||
*/
|
||||
extern void radeonCompatEmitPrimitive( radeonContextPtr rmesa,
|
||||
GLuint vertex_format,
|
||||
GLuint hw_primitive,
|
||||
GLuint nrverts );
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Helper macros:
|
||||
*/
|
||||
|
||||
/* Close off the last primitive, if it exists.
|
||||
*/
|
||||
#define RADEON_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 RADEON_STATECHANGE( rmesa, ATOM ) \
|
||||
do { \
|
||||
RADEON_NEWPRIM( rmesa ); \
|
||||
move_to_head( &(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_DB_STATE( ATOM ) \
|
||||
memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
|
||||
rmesa->hw.ATOM.cmd_size * 4)
|
||||
|
||||
static __inline int RADEON_DB_STATECHANGE(
|
||||
radeonContextPtr rmesa,
|
||||
struct radeon_state_atom *atom )
|
||||
{
|
||||
if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) {
|
||||
int *tmp;
|
||||
RADEON_NEWPRIM( rmesa );
|
||||
move_to_head( &(rmesa->hw.dirty), atom );
|
||||
tmp = atom->cmd;
|
||||
atom->cmd = atom->lastcmd;
|
||||
atom->lastcmd = tmp;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Fire the buffered vertices no matter what.
|
||||
*/
|
||||
#define RADEON_FIREVERTICES( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \
|
||||
radeonFlush( rmesa->glCtx ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Alloc space in the command buffer
|
||||
*/
|
||||
static __inline char *radeonAllocCmdBuf( radeonContextPtr rmesa,
|
||||
int bytes, const char *where )
|
||||
{
|
||||
if (rmesa->store.cmd_used + bytes > RADEON_CMD_BUF_SZ)
|
||||
radeonFlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
|
||||
assert(rmesa->dri.drmMinor >= 3);
|
||||
|
||||
{
|
||||
char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
|
||||
rmesa->store.cmd_used += bytes;
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_IOCTL_H__ */
|
||||
130
src/mesa/drivers/dri/radeon/radeon_lock.c
Normal file
130
src/mesa/drivers/dri/radeon/radeon_lock.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_lock.h"
|
||||
#include "radeon_tex.h"
|
||||
#include "radeon_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 rmesa )
|
||||
{
|
||||
int use_back;
|
||||
|
||||
if (rmesa->dri.drmMinor < 3)
|
||||
return;
|
||||
|
||||
rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip;
|
||||
|
||||
use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT);
|
||||
use_back ^= (rmesa->sarea->pfCurrentPage == 1);
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_VERBOSE )
|
||||
fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__,
|
||||
rmesa->doPageFlip,
|
||||
rmesa->sarea->pfCurrentPage );
|
||||
|
||||
if ( use_back ) {
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
|
||||
} else {
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
|
||||
}
|
||||
|
||||
RADEON_STATECHANGE( rmesa, ctx );
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the hardware state. This is called if another context has
|
||||
* grabbed the hardware lock, which includes the X server. This
|
||||
* function also updates the driver's window state after the X server
|
||||
* moves, resizes or restacks a window -- the change will be reflected
|
||||
* in the drawable position and clip rects. Since the X server grabs
|
||||
* the hardware lock when it changes the window state, this routine will
|
||||
* automatically be called after such a change.
|
||||
*/
|
||||
void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
int i;
|
||||
|
||||
drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
|
||||
|
||||
/* The window might have moved, so we might need to get new clip
|
||||
* rects.
|
||||
*
|
||||
* NOTE: This releases and regrabs the hw lock to allow the X server
|
||||
* to respond to the DRI protocol request for new drawable info.
|
||||
* Since the hardware state depends on having the latest drawable
|
||||
* clip rects, all state checking must be done _after_ this call.
|
||||
*/
|
||||
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
|
||||
|
||||
if ( rmesa->lastStamp != dPriv->lastStamp ) {
|
||||
radeonUpdatePageFlipping( rmesa );
|
||||
if (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT)
|
||||
radeonSetCliprects( rmesa, GL_BACK_LEFT );
|
||||
else
|
||||
radeonSetCliprects( rmesa, GL_FRONT_LEFT );
|
||||
radeonUpdateViewportOffset( rmesa->glCtx );
|
||||
rmesa->lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
if ( sarea->ctxOwner != rmesa->dri.hwContext ) {
|
||||
sarea->ctxOwner = rmesa->dri.hwContext;
|
||||
|
||||
for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) {
|
||||
if ( rmesa->texture.heap[i] && sarea->texAge[i] != rmesa->texture.age[i] ) {
|
||||
radeonAgeTextures( rmesa, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
src/mesa/drivers/dri/radeon/radeon_lock.h
Normal file
113
src/mesa/drivers/dri/radeon/radeon_lock.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h,v 1.2 2002/02/22 21:45:00 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_LOCK_H__
|
||||
#define __RADEON_LOCK_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags );
|
||||
|
||||
/* Turn DEBUG_LOCKING on to find locking conflicts.
|
||||
*/
|
||||
#define DEBUG_LOCKING 0
|
||||
|
||||
#if DEBUG_LOCKING
|
||||
extern char *prevLockFile;
|
||||
extern int prevLockLine;
|
||||
|
||||
#define DEBUG_LOCK() \
|
||||
do { \
|
||||
prevLockFile = (__FILE__); \
|
||||
prevLockLine = (__LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_RESET() \
|
||||
do { \
|
||||
prevLockFile = 0; \
|
||||
prevLockLine = 0; \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_CHECK_LOCK() \
|
||||
do { \
|
||||
if ( prevLockFile ) { \
|
||||
fprintf( stderr, \
|
||||
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
|
||||
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
|
||||
exit( 1 ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG_LOCK()
|
||||
#define DEBUG_RESET()
|
||||
#define DEBUG_CHECK_LOCK()
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !!! We may want to separate locks from locks with validation. This
|
||||
* could be used to improve performance for those things commands that
|
||||
* do not do any drawing !!!
|
||||
*/
|
||||
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
#define LOCK_HARDWARE( rmesa ) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DEBUG_CHECK_LOCK(); \
|
||||
DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \
|
||||
(DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \
|
||||
if ( __ret ) \
|
||||
radeonGetLock( rmesa, 0 ); \
|
||||
DEBUG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
/* Unlock the hardware.
|
||||
*/
|
||||
#define UNLOCK_HARDWARE( rmesa ) \
|
||||
do { \
|
||||
DRM_UNLOCK( rmesa->dri.fd, \
|
||||
rmesa->dri.hwLock, \
|
||||
rmesa->dri.hwContext ); \
|
||||
DEBUG_RESET(); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_LOCK_H__ */
|
||||
134
src/mesa/drivers/dri/radeon/radeon_macros.h
Normal file
134
src/mesa/drivers/dri/radeon/radeon_macros.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */
|
||||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation on the rights to use, copy, modify, merge,
|
||||
* publish, distribute, 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
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
||||
* THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@xfree86.org>
|
||||
* Rickard E. Faith <faith@valinux.com>
|
||||
* Alan Hourihane <alanh@fairlite.demon.co.uk>
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* !!!! FIXME !!!!
|
||||
* RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
|
||||
* Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
|
||||
* 1999.
|
||||
*
|
||||
* !!!! FIXME !!!!
|
||||
* RAGE 128 Software Development Manual (Technical Reference Manual P/N
|
||||
* SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _RADEON_MACROS_H_
|
||||
#define _RADEON_MACROS_H_
|
||||
|
||||
#ifdef XFree86Module
|
||||
#include "xf86_ansic.h"
|
||||
#endif
|
||||
/* #include "compiler.h" */
|
||||
|
||||
/* Memory mapped register access macros */
|
||||
#define INREG8(addr) MMIO_IN8(RADEONMMIO, addr)
|
||||
#define INREG16(addr) MMIO_IN16(RADEONMMIO, addr)
|
||||
#define INREG(addr) MMIO_IN32(RADEONMMIO, addr)
|
||||
#define OUTREG8(addr, val) MMIO_OUT8(RADEONMMIO, addr, val)
|
||||
#define OUTREG16(addr, val) MMIO_OUT16(RADEONMMIO, addr, val)
|
||||
#define OUTREG(addr, val) MMIO_OUT32(RADEONMMIO, addr, val)
|
||||
|
||||
#define ADDRREG(addr) ((volatile GLuint *)(pointer)(RADEONMMIO + (addr)))
|
||||
|
||||
|
||||
#define OUTREGP(addr, val, mask) \
|
||||
do { \
|
||||
GLuint tmp = INREG(addr); \
|
||||
tmp &= (mask); \
|
||||
tmp |= (val); \
|
||||
OUTREG(addr, tmp); \
|
||||
} while (0)
|
||||
|
||||
#define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr)
|
||||
|
||||
#define OUTPLL(addr, val) \
|
||||
do { \
|
||||
OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | \
|
||||
RADEON_PLL_WR_EN)); \
|
||||
OUTREG(RADEON_CLOCK_CNTL_DATA, val); \
|
||||
} while (0)
|
||||
|
||||
#define OUTPLLP(pScrn, addr, val, mask) \
|
||||
do { \
|
||||
GLuint tmp = INPLL(pScrn, addr); \
|
||||
tmp &= (mask); \
|
||||
tmp |= (val); \
|
||||
OUTPLL(addr, tmp); \
|
||||
} while (0)
|
||||
|
||||
#define OUTPAL_START(idx) \
|
||||
do { \
|
||||
OUTREG8(RADEON_PALETTE_INDEX, (idx)); \
|
||||
} while (0)
|
||||
|
||||
#define OUTPAL_NEXT(r, g, b) \
|
||||
do { \
|
||||
OUTREG(RADEON_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \
|
||||
} while (0)
|
||||
|
||||
#define OUTPAL_NEXT_CARD32(v) \
|
||||
do { \
|
||||
OUTREG(RADEON_PALETTE_DATA, (v & 0x00ffffff)); \
|
||||
} while (0)
|
||||
|
||||
#define OUTPAL(idx, r, g, b) \
|
||||
do { \
|
||||
OUTPAL_START((idx)); \
|
||||
OUTPAL_NEXT((r), (g), (b)); \
|
||||
} while (0)
|
||||
|
||||
#define INPAL_START(idx) \
|
||||
do { \
|
||||
OUTREG(RADEON_PALETTE_INDEX, (idx) << 16); \
|
||||
} while (0)
|
||||
|
||||
#define INPAL_NEXT() INREG(RADEON_PALETTE_DATA)
|
||||
|
||||
#define PAL_SELECT(idx) \
|
||||
do { \
|
||||
if (!idx) { \
|
||||
OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) & \
|
||||
(GLuint)~RADEON_DAC2_PALETTE_ACC_CTL); \
|
||||
} else { \
|
||||
OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) | \
|
||||
RADEON_DAC2_PALETTE_ACC_CTL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif
|
||||
12
src/mesa/drivers/dri/radeon/radeon_maos.c
Normal file
12
src/mesa/drivers/dri/radeon/radeon_maos.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
/* If using new packets, can choose either verts or arrays.
|
||||
* Otherwise, must use verts.
|
||||
*/
|
||||
#include "radeon_context.h"
|
||||
#define RADEON_MAOS_VERTS 1
|
||||
#if (RADEON_MAOS_VERTS) || (RADEON_OLD_PACKETS)
|
||||
#include "radeon_maos_verts.c"
|
||||
#else
|
||||
#include "radeon_maos_arrays.c"
|
||||
#endif
|
||||
47
src/mesa/drivers/dri/radeon/radeon_maos.h
Normal file
47
src/mesa/drivers/dri/radeon/radeon_maos.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Grahpics Inc., Austin, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAHPICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_MAOS_H__
|
||||
#define __RADEON_MAOS_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "radeon_context.h"
|
||||
|
||||
extern void radeonEmitArrays( GLcontext *ctx, GLuint inputs );
|
||||
extern void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
591
src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
Normal file
591
src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
#include "mmath.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "math/m_translate.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_imm_debug.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_maos.h"
|
||||
|
||||
/* Usage:
|
||||
* - from radeon_tcl_render
|
||||
* - call radeonEmitArrays to ensure uptodate arrays in dma
|
||||
* - emit primitives (new type?) which reference the data
|
||||
* -- need to use elts for lineloop, quads, quadstrip/flat
|
||||
* -- other primitives are all well-formed (need tristrip-1,fake-poly)
|
||||
*
|
||||
*/
|
||||
static void emit_ubyte_rgba3( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
radeon_color_t *out = (radeon_color_t *)(rvb->start + rvb->address);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d out %p\n",
|
||||
__FUNCTION__, count, stride, out);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
out->red = *data;
|
||||
out->green = *(data+1);
|
||||
out->blue = *(data+2);
|
||||
out->alpha = 0xFF;
|
||||
out++;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
#define COPY_DWORDS( dst, src, nr ) \
|
||||
do { \
|
||||
int __tmp; \
|
||||
__asm__ __volatile__( "rep ; movsl" \
|
||||
: "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
|
||||
: "0" (nr), \
|
||||
"D" ((long)dst), \
|
||||
"S" ((long)src) ); \
|
||||
} while (0)
|
||||
#else
|
||||
#define COPY_DWORDS( dst, src, nr ) \
|
||||
do { \
|
||||
int j; \
|
||||
for ( j = 0 ; j < nr ; j++ ) \
|
||||
dst[j] = ((int *)src)[j]; \
|
||||
dst += nr; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void emit_ubyte_rgba4( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 4)
|
||||
COPY_DWORDS( out, data, count );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
*out++ = LE32_TO_CPU(*(int *)data);
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void emit_ubyte_rgba( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
if (stride == 0) {
|
||||
radeonAllocDmaRegion( rmesa, rvb, 4, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
else {
|
||||
radeonAllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 1;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 3:
|
||||
emit_ubyte_rgba3( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_ubyte_rgba4( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void emit_vec8( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 8)
|
||||
COPY_DWORDS( out, data, count*2 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out += 2;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_vec12( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
|
||||
__FUNCTION__, count, stride, out, data);
|
||||
|
||||
if (stride == 12)
|
||||
COPY_DWORDS( out, data, count*3 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out[2] = *(int *)(data+8);
|
||||
out += 3;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_vec16( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 16)
|
||||
COPY_DWORDS( out, data, count*4 );
|
||||
else
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out[2] = *(int *)(data+8);
|
||||
out[3] = *(int *)(data+12);
|
||||
out += 4;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void emit_vector( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
if (stride == 0) {
|
||||
radeonAllocDmaRegion( rmesa, rvb, size * 4, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = size;
|
||||
}
|
||||
else {
|
||||
radeonAllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = size;
|
||||
rvb->aos_size = size;
|
||||
}
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 2:
|
||||
emit_vec8( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 3:
|
||||
emit_vec12( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_vec16( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void emit_s0_vec( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = 0;
|
||||
out += 2;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_stq_vec( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
out[0] = *(int *)data;
|
||||
out[1] = *(int *)(data+4);
|
||||
out[2] = *(int *)(data+12);
|
||||
out += 3;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void emit_tex_vector( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
int emitsize;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
switch (size) {
|
||||
case 4: emitsize = 3; break;
|
||||
default: emitsize = 2; break;
|
||||
}
|
||||
|
||||
|
||||
if (stride == 0) {
|
||||
radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = emitsize;
|
||||
}
|
||||
else {
|
||||
radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize * count, 4 );
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = emitsize;
|
||||
rvb->aos_size = emitsize;
|
||||
}
|
||||
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 1:
|
||||
emit_s0_vec( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 2:
|
||||
emit_vec8( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 3:
|
||||
emit_vec8( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_stq_vec( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Emit any changed arrays to new agp memory, re-emit a packet to
|
||||
* update the arrays.
|
||||
*/
|
||||
void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
|
||||
struct radeon_dma_region **component = rmesa->tcl.aos_components;
|
||||
GLuint nr = 0;
|
||||
GLuint vfmt = 0;
|
||||
GLuint count = VB->Count;
|
||||
GLuint vtx;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, inputs );
|
||||
|
||||
if (1) {
|
||||
if (!rmesa->tcl.obj.buf)
|
||||
emit_vector( ctx,
|
||||
&rmesa->tcl.obj,
|
||||
(char *)VB->ObjPtr->data,
|
||||
VB->ObjPtr->size,
|
||||
VB->ObjPtr->stride,
|
||||
count);
|
||||
|
||||
switch( VB->ObjPtr->size ) {
|
||||
case 4: vfmt |= RADEON_CP_VC_FRMT_W0;
|
||||
case 3: vfmt |= RADEON_CP_VC_FRMT_Z;
|
||||
case 2: vfmt |= RADEON_CP_VC_FRMT_XY;
|
||||
default:
|
||||
}
|
||||
component[nr++] = &rmesa->tcl.obj;
|
||||
}
|
||||
|
||||
|
||||
if (inputs & VERT_BIT_NORMAL) {
|
||||
if (!rmesa->tcl.norm.buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.norm),
|
||||
(char *)VB->NormalPtr->data,
|
||||
3,
|
||||
VB->NormalPtr->stride,
|
||||
count);
|
||||
|
||||
vfmt |= RADEON_CP_VC_FRMT_N0;
|
||||
component[nr++] = &rmesa->tcl.norm;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR0) {
|
||||
if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
|
||||
if (!rmesa->tcl.rgba.buf)
|
||||
emit_ubyte_rgba( ctx,
|
||||
&rmesa->tcl.rgba,
|
||||
(char *)VB->ColorPtr[0]->Ptr,
|
||||
VB->ColorPtr[0]->Size,
|
||||
VB->ColorPtr[0]->StrideB,
|
||||
count);
|
||||
|
||||
vfmt |= RADEON_CP_VC_FRMT_PKCOLOR;
|
||||
}
|
||||
else {
|
||||
int emitsize;
|
||||
|
||||
if (VB->ColorPtr[0]->Size == 4 &&
|
||||
(VB->ColorPtr[0]->StrideB != 0 ||
|
||||
((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) {
|
||||
vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
|
||||
emitsize = 4;
|
||||
}
|
||||
else {
|
||||
vfmt |= RADEON_CP_VC_FRMT_FPCOLOR;
|
||||
emitsize = 3;
|
||||
}
|
||||
|
||||
|
||||
if (!rmesa->tcl.rgba.buf)
|
||||
emit_vector( ctx,
|
||||
&(rmesa->tcl.rgba),
|
||||
(char *)VB->ColorPtr[0]->Ptr,
|
||||
emitsize,
|
||||
VB->ColorPtr[0]->StrideB,
|
||||
count);
|
||||
}
|
||||
|
||||
component[nr++] = &rmesa->tcl.rgba;
|
||||
}
|
||||
|
||||
|
||||
if (inputs & VERT_BIT_COLOR1) {
|
||||
if (!rmesa->tcl.spec.buf) {
|
||||
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
|
||||
radeon_import_float_spec_colors( ctx );
|
||||
|
||||
emit_ubyte_rgba( ctx,
|
||||
&rmesa->tcl.spec,
|
||||
(char *)VB->SecondaryColorPtr[0]->Ptr,
|
||||
3,
|
||||
VB->SecondaryColorPtr[0]->StrideB,
|
||||
count);
|
||||
}
|
||||
|
||||
vfmt |= RADEON_CP_VC_FRMT_PKSPEC;
|
||||
component[nr++] = &rmesa->tcl.spec;
|
||||
}
|
||||
|
||||
vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
|
||||
~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1));
|
||||
|
||||
if (inputs & VERT_BIT_TEX0) {
|
||||
if (!rmesa->tcl.tex[0].buf)
|
||||
emit_tex_vector( ctx,
|
||||
&(rmesa->tcl.tex[0]),
|
||||
(char *)VB->TexCoordPtr[0]->data,
|
||||
VB->TexCoordPtr[0]->size,
|
||||
VB->TexCoordPtr[0]->stride,
|
||||
count );
|
||||
|
||||
switch( VB->TexCoordPtr[0]->size ) {
|
||||
case 4:
|
||||
vtx |= RADEON_TCL_VTX_Q0;
|
||||
vfmt |= RADEON_CP_VC_FRMT_Q0;
|
||||
default:
|
||||
vfmt |= RADEON_CP_VC_FRMT_ST0;
|
||||
}
|
||||
component[nr++] = &rmesa->tcl.tex[0];
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX1) {
|
||||
if (!rmesa->tcl.tex[1].buf)
|
||||
emit_tex_vector( ctx,
|
||||
&(rmesa->tcl.tex[1]),
|
||||
(char *)VB->TexCoordPtr[1]->data,
|
||||
VB->TexCoordPtr[1]->size,
|
||||
VB->TexCoordPtr[1]->stride,
|
||||
count );
|
||||
|
||||
switch( VB->TexCoordPtr[1]->size ) {
|
||||
case 4:
|
||||
vtx |= RADEON_TCL_VTX_Q1;
|
||||
vfmt |= RADEON_CP_VC_FRMT_Q1;
|
||||
default:
|
||||
vfmt |= RADEON_CP_VC_FRMT_ST1;
|
||||
}
|
||||
component[nr++] = &rmesa->tcl.tex[1];
|
||||
}
|
||||
|
||||
if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
|
||||
RADEON_STATECHANGE( rmesa, tcl );
|
||||
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
|
||||
}
|
||||
|
||||
rmesa->tcl.nr_aos_components = nr;
|
||||
rmesa->tcl.vertex_format = vfmt;
|
||||
}
|
||||
|
||||
|
||||
void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, newinputs );
|
||||
|
||||
if (newinputs & VERT_BIT_POS)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_NORMAL)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_COLOR0)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_COLOR1)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_TEX0)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
|
||||
|
||||
if (newinputs & VERT_BIT_TEX1)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
|
||||
}
|
||||
368
src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
Normal file
368
src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 4.1
|
||||
*
|
||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef LOCALVARS
|
||||
#define LOCALVARS
|
||||
#endif
|
||||
|
||||
#undef TCL_DEBUG
|
||||
#ifndef TCL_DEBUG
|
||||
#define TCL_DEBUG 0
|
||||
#endif
|
||||
|
||||
static void TAG(emit)( GLcontext *ctx,
|
||||
GLuint start, GLuint end,
|
||||
void *dest )
|
||||
{
|
||||
LOCALVARS
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLuint (*tc0)[4], (*tc1)[4], (*tc2)[4];
|
||||
GLfloat (*fog)[4];
|
||||
GLuint (*norm)[4];
|
||||
GLubyte (*col)[4], (*spec)[4];
|
||||
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
|
||||
GLuint tc2_stride, norm_stride;
|
||||
GLuint (*coord)[4];
|
||||
GLuint coord_stride; /* object coordinates */
|
||||
GLubyte dummy[4];
|
||||
int i;
|
||||
|
||||
union emit_union *v = (union emit_union *)dest;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* The vertex code expects Obj to be clean to element 3. To fix
|
||||
* this, add more vertex code (for obj-2, obj-3) or preferably move
|
||||
* to maos.
|
||||
*/
|
||||
if (VB->ObjPtr->size < 3) {
|
||||
if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 2 );
|
||||
}
|
||||
|
||||
if (DO_W && VB->ObjPtr->size < 4) {
|
||||
if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 3 );
|
||||
}
|
||||
|
||||
coord = (GLuint (*)[4])VB->ObjPtr->data;
|
||||
coord_stride = VB->ObjPtr->stride;
|
||||
|
||||
if (DO_TEX2) {
|
||||
const GLuint t2 = GET_TEXSOURCE(2);
|
||||
tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data;
|
||||
tc2_stride = VB->TexCoordPtr[t2]->stride;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) {
|
||||
if (VB->TexCoordPtr[t2]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_BIT_TEX2, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t2], VB->Count, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TEX1) {
|
||||
if (VB->TexCoordPtr[1]) {
|
||||
const GLuint t1 = GET_TEXSOURCE(1);
|
||||
tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data;
|
||||
tc1_stride = VB->TexCoordPtr[t1]->stride;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) {
|
||||
if (VB->TexCoordPtr[t1]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_BIT_TEX1, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t1], VB->Count, 3 );
|
||||
}
|
||||
} else {
|
||||
tc1 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX1]; /* could be anything, really */
|
||||
tc1_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_TEX0) {
|
||||
if (VB->TexCoordPtr[0]) {
|
||||
const GLuint t0 = GET_TEXSOURCE(0);
|
||||
tc0_stride = VB->TexCoordPtr[t0]->stride;
|
||||
tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data;
|
||||
if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) {
|
||||
if (VB->TexCoordPtr[t0]->flags & VEC_NOT_WRITEABLE) {
|
||||
VB->import_data( ctx, VERT_BIT_TEX0, VEC_NOT_WRITEABLE );
|
||||
}
|
||||
_mesa_vector4f_clean_elem( VB->TexCoordPtr[t0], VB->Count, 3 );
|
||||
}
|
||||
} else {
|
||||
tc0 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* could be anything, really */
|
||||
tc0_stride = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DO_NORM) {
|
||||
if (VB->NormalPtr) {
|
||||
norm_stride = VB->NormalPtr->stride;
|
||||
norm = (GLuint (*)[4])VB->NormalPtr->data;
|
||||
} else {
|
||||
norm_stride = 0;
|
||||
norm = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_RGBA) {
|
||||
if (VB->ColorPtr[0]) {
|
||||
/* This is incorrect when colormaterial is enabled:
|
||||
*/
|
||||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) {
|
||||
if (0) fprintf(stderr, "IMPORTING FLOAT COLORS\n");
|
||||
IMPORT_FLOAT_COLORS( ctx );
|
||||
}
|
||||
col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr;
|
||||
col_stride = VB->ColorPtr[0]->StrideB;
|
||||
} else {
|
||||
col = &dummy; /* any old memory is fine */
|
||||
col_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_SPEC) {
|
||||
if (VB->SecondaryColorPtr[0]) {
|
||||
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
|
||||
IMPORT_FLOAT_SPEC_COLORS( ctx );
|
||||
spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr;
|
||||
spec_stride = VB->SecondaryColorPtr[0]->StrideB;
|
||||
} else {
|
||||
spec = &dummy;
|
||||
spec_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (DO_FOG) {
|
||||
if (VB->FogCoordPtr) {
|
||||
fog = VB->FogCoordPtr->data;
|
||||
fog_stride = VB->FogCoordPtr->stride;
|
||||
} else {
|
||||
fog = (GLfloat (*)[4])&dummy; fog[0][0] = 0.0F;
|
||||
fog_stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (VB->importable_data) {
|
||||
if (start) {
|
||||
coord = (GLuint (*)[4])((GLubyte *)coord + start * coord_stride);
|
||||
if (DO_TEX0)
|
||||
tc0 = (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride);
|
||||
if (DO_TEX1)
|
||||
tc1 = (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride);
|
||||
if (DO_TEX2)
|
||||
tc2 = (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride);
|
||||
if (DO_NORM)
|
||||
norm = (GLuint (*)[4])((GLubyte *)norm + start * norm_stride);
|
||||
if (DO_RGBA)
|
||||
STRIDE_4UB(col, start * col_stride);
|
||||
if (DO_SPEC)
|
||||
STRIDE_4UB(spec, start * spec_stride);
|
||||
if (DO_FOG)
|
||||
fog = (GLfloat (*)[4])((GLubyte *)fog + start * fog_stride);
|
||||
}
|
||||
|
||||
for (i=start; i < end; i++) {
|
||||
v[0].ui = coord[0][0];
|
||||
v[1].ui = coord[0][1];
|
||||
v[2].ui = coord[0][2];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%d: %.2f %.2f %.2f ", i, v[0].f, v[1].f, v[2].f);
|
||||
if (DO_W) {
|
||||
v[3].ui = coord[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[3].f);
|
||||
v += 4;
|
||||
}
|
||||
else
|
||||
v += 3;
|
||||
coord = (GLuint (*)[4])((GLubyte *)coord + coord_stride);
|
||||
|
||||
if (DO_NORM) {
|
||||
v[0].ui = norm[0][0];
|
||||
v[1].ui = norm[0][1];
|
||||
v[2].ui = norm[0][2];
|
||||
if (TCL_DEBUG) fprintf(stderr, "norm: %.2f %.2f %.2f ", v[0].f, v[1].f, v[2].f);
|
||||
v += 3;
|
||||
norm = (GLuint (*)[4])((GLubyte *)norm + norm_stride);
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
v[0].ui = LE32_TO_CPU(*(GLuint *)&col[0]);
|
||||
STRIDE_4UB(col, col_stride);
|
||||
if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
|
||||
v++;
|
||||
}
|
||||
if (DO_SPEC || DO_FOG) {
|
||||
if (DO_SPEC) {
|
||||
v[0].specular.red = spec[0][0];
|
||||
v[0].specular.green = spec[0][1];
|
||||
v[0].specular.blue = spec[0][2];
|
||||
STRIDE_4UB(spec, spec_stride);
|
||||
}
|
||||
if (DO_FOG) {
|
||||
v[0].specular.alpha = fog[0][0] * 255.0;
|
||||
fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
|
||||
}
|
||||
if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
|
||||
v++;
|
||||
}
|
||||
if (DO_TEX0) {
|
||||
v[0].ui = tc0[0][0];
|
||||
v[1].ui = tc0[0][1];
|
||||
if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f);
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc0[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc0 = (GLuint (*)[4])((GLubyte *)tc0 + tc0_stride);
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
v[0].ui = tc1[0][0];
|
||||
v[1].ui = tc1[0][1];
|
||||
if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f);
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc1[0][3];
|
||||
if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc1 = (GLuint (*)[4])((GLubyte *)tc1 + tc1_stride);
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
v[0].ui = tc2[0][0];
|
||||
v[1].ui = tc2[0][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc2[0][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
tc2 = (GLuint (*)[4])((GLubyte *)tc2 + tc2_stride);
|
||||
}
|
||||
if (TCL_DEBUG) fprintf(stderr, "\n");
|
||||
}
|
||||
} else {
|
||||
for (i=start; i < end; i++) {
|
||||
v[0].ui = coord[i][0];
|
||||
v[1].ui = coord[i][1];
|
||||
v[2].ui = coord[i][2];
|
||||
if (DO_W) {
|
||||
v[3].ui = coord[i][3];
|
||||
v += 4;
|
||||
}
|
||||
else
|
||||
v += 3;
|
||||
|
||||
if (DO_NORM) {
|
||||
v[0].ui = norm[i][0];
|
||||
v[1].ui = norm[i][1];
|
||||
v[2].ui = norm[i][2];
|
||||
v += 3;
|
||||
}
|
||||
if (DO_RGBA) {
|
||||
v[0].ui = LE32_TO_CPU(*(GLuint *)&col[i]);
|
||||
v++;
|
||||
}
|
||||
if (DO_SPEC || DO_FOG) {
|
||||
if (DO_SPEC) {
|
||||
v[0].specular.red = spec[i][0];
|
||||
v[0].specular.green = spec[i][1];
|
||||
v[0].specular.blue = spec[i][2];
|
||||
}
|
||||
if (DO_FOG) {
|
||||
GLfloat *f = (GLfloat *) ((GLubyte *)fog + fog_stride);
|
||||
v[0].specular.alpha = *f * 255.0;
|
||||
}
|
||||
v++;
|
||||
}
|
||||
if (DO_TEX0) {
|
||||
v[0].ui = tc0[i][0];
|
||||
v[1].ui = tc0[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc0[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
if (DO_TEX1) {
|
||||
v[0].ui = tc1[i][0];
|
||||
v[1].ui = tc1[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc1[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
if (DO_TEX2) {
|
||||
v[0].ui = tc2[i][0];
|
||||
v[1].ui = tc2[i][1];
|
||||
if (DO_PTEX) {
|
||||
v[2].ui = tc2[i][3];
|
||||
v += 3;
|
||||
}
|
||||
else
|
||||
v += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void TAG(init)( void )
|
||||
{
|
||||
int sz = 3;
|
||||
if (DO_W) sz++;
|
||||
if (DO_NORM) sz += 3;
|
||||
if (DO_RGBA) sz++;
|
||||
if (DO_SPEC || DO_FOG) sz++;
|
||||
if (DO_TEX0) sz += 2;
|
||||
if (DO_TEX0 && DO_PTEX) sz++;
|
||||
if (DO_TEX1) sz += 2;
|
||||
if (DO_TEX1 && DO_PTEX) sz++;
|
||||
if (DO_TEX2) sz += 2;
|
||||
if (DO_TEX2 && DO_PTEX) sz++;
|
||||
|
||||
setup_tab[IDX].emit = TAG(emit);
|
||||
setup_tab[IDX].vertex_format = IND;
|
||||
setup_tab[IDX].vertex_size = sz;
|
||||
}
|
||||
|
||||
|
||||
#undef IND
|
||||
#undef TAG
|
||||
#undef IDX
|
||||
335
src/mesa/drivers/dri/radeon/radeon_maos_verts.c
Normal file
335
src/mesa/drivers/dri/radeon/radeon_maos_verts.c
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Austin, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "tnl/t_imm_debug.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_tex.h"
|
||||
#include "radeon_tcl.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_maos.h"
|
||||
|
||||
|
||||
#define RADEON_TCL_MAX_SETUP 13
|
||||
|
||||
union emit_union { float f; GLuint ui; radeon_color_t specular; };
|
||||
|
||||
static struct {
|
||||
void (*emit)( GLcontext *, GLuint, GLuint, void * );
|
||||
GLuint vertex_size;
|
||||
GLuint vertex_format;
|
||||
} setup_tab[RADEON_TCL_MAX_SETUP];
|
||||
|
||||
#define DO_W (IND & RADEON_CP_VC_FRMT_W0)
|
||||
#define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR)
|
||||
#define DO_SPEC (IND & RADEON_CP_VC_FRMT_PKSPEC)
|
||||
#define DO_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
|
||||
#define DO_TEX0 (IND & RADEON_CP_VC_FRMT_ST0)
|
||||
#define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1)
|
||||
#define DO_PTEX (IND & RADEON_CP_VC_FRMT_Q0)
|
||||
#define DO_NORM (IND & RADEON_CP_VC_FRMT_N0)
|
||||
|
||||
#define DO_TEX2 0
|
||||
#define DO_TEX3 0
|
||||
|
||||
#define GET_TEXSOURCE(n) n
|
||||
#define GET_UBYTE_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteColor
|
||||
#define GET_UBYTE_SPEC_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteSecondaryColor
|
||||
|
||||
#define IMPORT_FLOAT_COLORS radeon_import_float_colors
|
||||
#define IMPORT_FLOAT_SPEC_COLORS radeon_import_float_spec_colors
|
||||
|
||||
/***********************************************************************
|
||||
* Generate vertex emit functions *
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/* Defined in order of increasing vertex size:
|
||||
*/
|
||||
#define IDX 0
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR)
|
||||
#define TAG(x) x##_rgba
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 1
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 2
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_ST0)
|
||||
#define TAG(x) x##_rgba_st
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 3
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgba_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 4
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_st_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 5
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_ST1)
|
||||
#define TAG(x) x##_rgba_st_st
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 6
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgba_st_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 7
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_PKSPEC| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_ST1)
|
||||
#define TAG(x) x##_rgba_spec_st_st
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 8
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_ST1| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_st_st_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 9
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_PKSPEC| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_ST1| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_rgpa_spec_st_st_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 10
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_Q0)
|
||||
#define TAG(x) x##_rgba_stq
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 11
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_ST1| \
|
||||
RADEON_CP_VC_FRMT_Q1| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_Q0)
|
||||
#define TAG(x) x##_rgba_stq_stq
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
#define IDX 12
|
||||
#define IND (RADEON_CP_VC_FRMT_XY| \
|
||||
RADEON_CP_VC_FRMT_Z| \
|
||||
RADEON_CP_VC_FRMT_W0| \
|
||||
RADEON_CP_VC_FRMT_PKCOLOR| \
|
||||
RADEON_CP_VC_FRMT_PKSPEC| \
|
||||
RADEON_CP_VC_FRMT_ST0| \
|
||||
RADEON_CP_VC_FRMT_Q0| \
|
||||
RADEON_CP_VC_FRMT_ST1| \
|
||||
RADEON_CP_VC_FRMT_Q1| \
|
||||
RADEON_CP_VC_FRMT_N0)
|
||||
#define TAG(x) x##_w_rgpa_spec_stq_stq_n
|
||||
#include "radeon_maos_vbtmp.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialization
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
static void init_tcl_verts( void )
|
||||
{
|
||||
init_rgba();
|
||||
init_n();
|
||||
init_rgba_n();
|
||||
init_rgba_st();
|
||||
init_st_n();
|
||||
init_rgba_st_st();
|
||||
init_rgba_st_n();
|
||||
init_rgba_spec_st_st();
|
||||
init_st_st_n();
|
||||
init_rgpa_spec_st_st_n();
|
||||
init_rgba_stq();
|
||||
init_rgba_stq_stq();
|
||||
init_w_rgpa_spec_stq_stq_n();
|
||||
}
|
||||
|
||||
|
||||
void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLuint req = 0;
|
||||
GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
|
||||
~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1));
|
||||
int i;
|
||||
static int firsttime = 1;
|
||||
|
||||
if (firsttime) {
|
||||
init_tcl_verts();
|
||||
firsttime = 0;
|
||||
}
|
||||
|
||||
if (1) {
|
||||
req |= RADEON_CP_VC_FRMT_Z;
|
||||
if (VB->ObjPtr->size == 4) {
|
||||
req |= RADEON_CP_VC_FRMT_W0;
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_NORMAL) {
|
||||
req |= RADEON_CP_VC_FRMT_N0;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR0) {
|
||||
req |= RADEON_CP_VC_FRMT_PKCOLOR;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_COLOR1) {
|
||||
req |= RADEON_CP_VC_FRMT_PKSPEC;
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX0) {
|
||||
req |= RADEON_CP_VC_FRMT_ST0;
|
||||
|
||||
if (VB->TexCoordPtr[0]->size == 4) {
|
||||
req |= RADEON_CP_VC_FRMT_Q0;
|
||||
vtx |= RADEON_TCL_VTX_Q0;
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs & VERT_BIT_TEX1) {
|
||||
req |= RADEON_CP_VC_FRMT_ST1;
|
||||
|
||||
if (VB->TexCoordPtr[1]->size == 4) {
|
||||
req |= RADEON_CP_VC_FRMT_Q1;
|
||||
vtx |= RADEON_TCL_VTX_Q1;
|
||||
}
|
||||
}
|
||||
|
||||
if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
|
||||
RADEON_STATECHANGE( rmesa, tcl );
|
||||
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < RADEON_TCL_MAX_SETUP ; i++)
|
||||
if ((setup_tab[i].vertex_format & req) == req)
|
||||
break;
|
||||
|
||||
if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format &&
|
||||
rmesa->tcl.indexed_verts.buf)
|
||||
return;
|
||||
|
||||
if (rmesa->tcl.indexed_verts.buf)
|
||||
radeonReleaseArrays( ctx, ~0 );
|
||||
|
||||
radeonAllocDmaRegionVerts( rmesa,
|
||||
&rmesa->tcl.indexed_verts,
|
||||
VB->Count,
|
||||
setup_tab[i].vertex_size * 4,
|
||||
4);
|
||||
|
||||
setup_tab[i].emit( ctx, 0, VB->Count,
|
||||
rmesa->tcl.indexed_verts.address +
|
||||
rmesa->tcl.indexed_verts.start );
|
||||
|
||||
rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
|
||||
rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts );
|
||||
rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size;
|
||||
rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size;
|
||||
|
||||
rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts;
|
||||
rmesa->tcl.nr_aos_components = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_VERTS)
|
||||
_tnl_print_vert_flags( __FUNCTION__, newinputs );
|
||||
|
||||
if (newinputs)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ );
|
||||
}
|
||||
1928
src/mesa/drivers/dri/radeon/radeon_reg.h
Normal file
1928
src/mesa/drivers/dri/radeon/radeon_reg.h
Normal file
File diff suppressed because it is too large
Load diff
982
src/mesa/drivers/dri/radeon/radeon_sanity.c
Normal file
982
src/mesa/drivers/dri/radeon/radeon_sanity.c
Normal file
|
|
@ -0,0 +1,982 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc, Cedar Park, TX.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_sanity.h"
|
||||
#include <errno.h>
|
||||
|
||||
/* Set this '1' to get more verbiage.
|
||||
*/
|
||||
#define MORE_VERBOSE 1
|
||||
|
||||
#if MORE_VERBOSE
|
||||
#define VERBOSE (RADEON_DEBUG & DEBUG_VERBOSE)
|
||||
#define NORMAL (1)
|
||||
#else
|
||||
#define VERBOSE 0
|
||||
#define NORMAL (RADEON_DEBUG & DEBUG_VERBOSE)
|
||||
#endif
|
||||
|
||||
|
||||
/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
|
||||
* 1.3 cmdbuffers allow all previous state to be updated as well as
|
||||
* the tcl scalar and vector areas.
|
||||
*/
|
||||
static struct {
|
||||
int start;
|
||||
int len;
|
||||
const char *name;
|
||||
} packet[RADEON_MAX_STATE_PACKETS] = {
|
||||
{ RADEON_PP_MISC,7,"RADEON_PP_MISC" },
|
||||
{ RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
|
||||
{ RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
|
||||
{ RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
|
||||
{ RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
|
||||
{ RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
|
||||
{ RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
|
||||
{ RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
|
||||
{ RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
|
||||
{ RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
|
||||
{ RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
|
||||
{ RADEON_RE_MISC,1,"RADEON_RE_MISC" },
|
||||
{ RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
|
||||
{ RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
|
||||
{ RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
|
||||
{ RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
|
||||
{ RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
|
||||
{ RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
|
||||
{ RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
|
||||
{ RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
|
||||
};
|
||||
|
||||
struct reg_names {
|
||||
int idx;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct reg_names reg_names[] = {
|
||||
{ RADEON_PP_MISC, "RADEON_PP_MISC" },
|
||||
{ RADEON_PP_FOG_COLOR, "RADEON_PP_FOG_COLOR" },
|
||||
{ RADEON_RE_SOLID_COLOR, "RADEON_RE_SOLID_COLOR" },
|
||||
{ RADEON_RB3D_BLENDCNTL, "RADEON_RB3D_BLENDCNTL" },
|
||||
{ RADEON_RB3D_DEPTHOFFSET, "RADEON_RB3D_DEPTHOFFSET" },
|
||||
{ RADEON_RB3D_DEPTHPITCH, "RADEON_RB3D_DEPTHPITCH" },
|
||||
{ RADEON_RB3D_ZSTENCILCNTL, "RADEON_RB3D_ZSTENCILCNTL" },
|
||||
{ RADEON_PP_CNTL, "RADEON_PP_CNTL" },
|
||||
{ RADEON_RB3D_CNTL, "RADEON_RB3D_CNTL" },
|
||||
{ RADEON_RB3D_COLOROFFSET, "RADEON_RB3D_COLOROFFSET" },
|
||||
{ RADEON_RB3D_COLORPITCH, "RADEON_RB3D_COLORPITCH" },
|
||||
{ RADEON_SE_CNTL, "RADEON_SE_CNTL" },
|
||||
{ RADEON_SE_COORD_FMT, "RADEON_SE_COORDFMT" },
|
||||
{ RADEON_SE_CNTL_STATUS, "RADEON_SE_CNTL_STATUS" },
|
||||
{ RADEON_RE_LINE_PATTERN, "RADEON_RE_LINE_PATTERN" },
|
||||
{ RADEON_RE_LINE_STATE, "RADEON_RE_LINE_STATE" },
|
||||
{ RADEON_SE_LINE_WIDTH, "RADEON_SE_LINE_WIDTH" },
|
||||
{ RADEON_RB3D_STENCILREFMASK, "RADEON_RB3D_STENCILREFMASK" },
|
||||
{ RADEON_RB3D_ROPCNTL, "RADEON_RB3D_ROPCNTL" },
|
||||
{ RADEON_RB3D_PLANEMASK, "RADEON_RB3D_PLANEMASK" },
|
||||
{ RADEON_SE_VPORT_XSCALE, "RADEON_SE_VPORT_XSCALE" },
|
||||
{ RADEON_SE_VPORT_XOFFSET, "RADEON_SE_VPORT_XOFFSET" },
|
||||
{ RADEON_SE_VPORT_YSCALE, "RADEON_SE_VPORT_YSCALE" },
|
||||
{ RADEON_SE_VPORT_YOFFSET, "RADEON_SE_VPORT_YOFFSET" },
|
||||
{ RADEON_SE_VPORT_ZSCALE, "RADEON_SE_VPORT_ZSCALE" },
|
||||
{ RADEON_SE_VPORT_ZOFFSET, "RADEON_SE_VPORT_ZOFFSET" },
|
||||
{ RADEON_RE_MISC, "RADEON_RE_MISC" },
|
||||
{ RADEON_PP_TXFILTER_0, "RADEON_PP_TXFILTER_0" },
|
||||
{ RADEON_PP_TXFILTER_1, "RADEON_PP_TXFILTER_1" },
|
||||
{ RADEON_PP_TXFILTER_2, "RADEON_PP_TXFILTER_2" },
|
||||
{ RADEON_PP_TXFORMAT_0, "RADEON_PP_TXFORMAT_0" },
|
||||
{ RADEON_PP_TXFORMAT_1, "RADEON_PP_TXFORMAT_1" },
|
||||
{ RADEON_PP_TXFORMAT_2, "RADEON_PP_TXFORMAT_3" },
|
||||
{ RADEON_PP_TXOFFSET_0, "RADEON_PP_TXOFFSET_0" },
|
||||
{ RADEON_PP_TXOFFSET_1, "RADEON_PP_TXOFFSET_1" },
|
||||
{ RADEON_PP_TXOFFSET_2, "RADEON_PP_TXOFFSET_3" },
|
||||
{ RADEON_PP_TXCBLEND_0, "RADEON_PP_TXCBLEND_0" },
|
||||
{ RADEON_PP_TXCBLEND_1, "RADEON_PP_TXCBLEND_1" },
|
||||
{ RADEON_PP_TXCBLEND_2, "RADEON_PP_TXCBLEND_3" },
|
||||
{ RADEON_PP_TXABLEND_0, "RADEON_PP_TXABLEND_0" },
|
||||
{ RADEON_PP_TXABLEND_1, "RADEON_PP_TXABLEND_1" },
|
||||
{ RADEON_PP_TXABLEND_2, "RADEON_PP_TXABLEND_3" },
|
||||
{ RADEON_PP_TFACTOR_0, "RADEON_PP_TFACTOR_0" },
|
||||
{ RADEON_PP_TFACTOR_1, "RADEON_PP_TFACTOR_1" },
|
||||
{ RADEON_PP_TFACTOR_2, "RADEON_PP_TFACTOR_3" },
|
||||
{ RADEON_PP_BORDER_COLOR_0, "RADEON_PP_BORDER_COLOR_0" },
|
||||
{ RADEON_PP_BORDER_COLOR_1, "RADEON_PP_BORDER_COLOR_1" },
|
||||
{ RADEON_PP_BORDER_COLOR_2, "RADEON_PP_BORDER_COLOR_3" },
|
||||
{ RADEON_SE_ZBIAS_FACTOR, "RADEON_SE_ZBIAS_FACTOR" },
|
||||
{ RADEON_SE_ZBIAS_CONSTANT, "RADEON_SE_ZBIAS_CONSTANT" },
|
||||
{ RADEON_SE_TCL_OUTPUT_VTX_FMT, "RADEON_SE_TCL_OUTPUT_VTXFMT" },
|
||||
{ RADEON_SE_TCL_OUTPUT_VTX_SEL, "RADEON_SE_TCL_OUTPUT_VTXSEL" },
|
||||
{ RADEON_SE_TCL_MATRIX_SELECT_0, "RADEON_SE_TCL_MATRIX_SELECT_0" },
|
||||
{ RADEON_SE_TCL_MATRIX_SELECT_1, "RADEON_SE_TCL_MATRIX_SELECT_1" },
|
||||
{ RADEON_SE_TCL_UCP_VERT_BLEND_CTL, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" },
|
||||
{ RADEON_SE_TCL_TEXTURE_PROC_CTL, "RADEON_SE_TCL_TEXTURE_PROC_CTL" },
|
||||
{ RADEON_SE_TCL_LIGHT_MODEL_CTL, "RADEON_SE_TCL_LIGHT_MODEL_CTL" },
|
||||
{ RADEON_SE_TCL_PER_LIGHT_CTL_0, "RADEON_SE_TCL_PER_LIGHT_CTL_0" },
|
||||
{ RADEON_SE_TCL_PER_LIGHT_CTL_1, "RADEON_SE_TCL_PER_LIGHT_CTL_1" },
|
||||
{ RADEON_SE_TCL_PER_LIGHT_CTL_2, "RADEON_SE_TCL_PER_LIGHT_CTL_2" },
|
||||
{ RADEON_SE_TCL_PER_LIGHT_CTL_3, "RADEON_SE_TCL_PER_LIGHT_CTL_3" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, "RADEON_SE_TCL_EMMISSIVE_RED" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN, "RADEON_SE_TCL_EMMISSIVE_GREEN" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE, "RADEON_SE_TCL_EMMISSIVE_BLUE" },
|
||||
{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA, "RADEON_SE_TCL_EMMISSIVE_ALPHA" },
|
||||
{ RADEON_SE_TCL_MATERIAL_AMBIENT_RED, "RADEON_SE_TCL_AMBIENT_RED" },
|
||||
{ RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN, "RADEON_SE_TCL_AMBIENT_GREEN" },
|
||||
{ RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE, "RADEON_SE_TCL_AMBIENT_BLUE" },
|
||||
{ RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA, "RADEON_SE_TCL_AMBIENT_ALPHA" },
|
||||
{ RADEON_SE_TCL_MATERIAL_DIFFUSE_RED, "RADEON_SE_TCL_DIFFUSE_RED" },
|
||||
{ RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN, "RADEON_SE_TCL_DIFFUSE_GREEN" },
|
||||
{ RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE, "RADEON_SE_TCL_DIFFUSE_BLUE" },
|
||||
{ RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA, "RADEON_SE_TCL_DIFFUSE_ALPHA" },
|
||||
{ RADEON_SE_TCL_MATERIAL_SPECULAR_RED, "RADEON_SE_TCL_SPECULAR_RED" },
|
||||
{ RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN, "RADEON_SE_TCL_SPECULAR_GREEN" },
|
||||
{ RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE, "RADEON_SE_TCL_SPECULAR_BLUE" },
|
||||
{ RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA, "RADEON_SE_TCL_SPECULAR_ALPHA" },
|
||||
{ RADEON_SE_TCL_SHININESS, "RADEON_SE_TCL_SHININESS" },
|
||||
{ RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" }
|
||||
};
|
||||
|
||||
static struct reg_names scalar_names[] = {
|
||||
{ RADEON_SS_LIGHT_DCD_ADDR, "LIGHT_DCD" },
|
||||
{ RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR, "LIGHT_SPOT_EXPONENT" },
|
||||
{ RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR, "LIGHT_SPOT_CUTOFF" },
|
||||
{ RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR, "LIGHT_SPECULAR_THRESH" },
|
||||
{ RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR, "LIGHT_RANGE_CUTOFF" },
|
||||
{ RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, "VERT_GUARD_CLIP" },
|
||||
{ RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR, "VERT_GUARD_DISCARD" },
|
||||
{ RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR, "HORZ_GUARD_CLIP" },
|
||||
{ RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR, "HORZ_GUARD_DISCARD" },
|
||||
{ RADEON_SS_SHININESS, "SHININESS" },
|
||||
{ 1000, "" },
|
||||
};
|
||||
|
||||
/* Puff these out to make them look like normal (dword) registers.
|
||||
*/
|
||||
static struct reg_names vector_names[] = {
|
||||
{ RADEON_VS_MATRIX_0_ADDR * 4, "MATRIX_0" },
|
||||
{ RADEON_VS_MATRIX_1_ADDR * 4, "MATRIX_1" },
|
||||
{ RADEON_VS_MATRIX_2_ADDR * 4, "MATRIX_2" },
|
||||
{ RADEON_VS_MATRIX_3_ADDR * 4, "MATRIX_3" },
|
||||
{ RADEON_VS_MATRIX_4_ADDR * 4, "MATRIX_4" },
|
||||
{ RADEON_VS_MATRIX_5_ADDR * 4, "MATRIX_5" },
|
||||
{ RADEON_VS_MATRIX_6_ADDR * 4, "MATRIX_6" },
|
||||
{ RADEON_VS_MATRIX_7_ADDR * 4, "MATRIX_7" },
|
||||
{ RADEON_VS_MATRIX_8_ADDR * 4, "MATRIX_8" },
|
||||
{ RADEON_VS_MATRIX_9_ADDR * 4, "MATRIX_9" },
|
||||
{ RADEON_VS_MATRIX_10_ADDR * 4, "MATRIX_10" },
|
||||
{ RADEON_VS_MATRIX_11_ADDR * 4, "MATRIX_11" },
|
||||
{ RADEON_VS_MATRIX_12_ADDR * 4, "MATRIX_12" },
|
||||
{ RADEON_VS_MATRIX_13_ADDR * 4, "MATRIX_13" },
|
||||
{ RADEON_VS_MATRIX_14_ADDR * 4, "MATRIX_14" },
|
||||
{ RADEON_VS_MATRIX_15_ADDR * 4, "MATRIX_15" },
|
||||
{ RADEON_VS_LIGHT_AMBIENT_ADDR * 4, "LIGHT_AMBIENT" },
|
||||
{ RADEON_VS_LIGHT_DIFFUSE_ADDR * 4, "LIGHT_DIFFUSE" },
|
||||
{ RADEON_VS_LIGHT_SPECULAR_ADDR * 4, "LIGHT_SPECULAR" },
|
||||
{ RADEON_VS_LIGHT_DIRPOS_ADDR * 4, "LIGHT_DIRPOS" },
|
||||
{ RADEON_VS_LIGHT_HWVSPOT_ADDR * 4, "LIGHT_HWVSPOT" },
|
||||
{ RADEON_VS_LIGHT_ATTENUATION_ADDR * 4, "LIGHT_ATTENUATION" },
|
||||
{ RADEON_VS_MATRIX_EYE2CLIP_ADDR * 4, "MATRIX_EYE2CLIP" },
|
||||
{ RADEON_VS_UCP_ADDR * 4, "UCP" },
|
||||
{ RADEON_VS_GLOBAL_AMBIENT_ADDR * 4, "GLOBAL_AMBIENT" },
|
||||
{ RADEON_VS_FOG_PARAM_ADDR * 4, "FOG_PARAM" },
|
||||
{ RADEON_VS_EYE_VECTOR_ADDR * 4, "EYE_VECTOR" },
|
||||
{ 1000, "" },
|
||||
};
|
||||
|
||||
union fi { float f; int i; };
|
||||
|
||||
#define ISVEC 1
|
||||
#define ISFLOAT 2
|
||||
#define TOUCHED 4
|
||||
|
||||
struct reg {
|
||||
int idx;
|
||||
struct reg_names *closest;
|
||||
int flags;
|
||||
union fi current;
|
||||
union fi *values;
|
||||
int nvalues;
|
||||
int nalloc;
|
||||
float vmin, vmax;
|
||||
};
|
||||
|
||||
|
||||
static struct reg regs[Elements(reg_names)+1];
|
||||
static struct reg scalars[512+1];
|
||||
static struct reg vectors[512*4+1];
|
||||
|
||||
static int total, total_changed, bufs;
|
||||
|
||||
static void init_regs( void )
|
||||
{
|
||||
struct reg_names *tmp;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < Elements(regs) ; i++) {
|
||||
regs[i].idx = reg_names[i].idx;
|
||||
regs[i].closest = ®_names[i];
|
||||
regs[i].flags = 0;
|
||||
}
|
||||
|
||||
for (i = 0, tmp = scalar_names ; i < Elements(scalars) ; i++) {
|
||||
if (tmp[1].idx == i) tmp++;
|
||||
scalars[i].idx = i;
|
||||
scalars[i].closest = tmp;
|
||||
scalars[i].flags = ISFLOAT;
|
||||
}
|
||||
|
||||
for (i = 0, tmp = vector_names ; i < Elements(vectors) ; i++) {
|
||||
if (tmp[1].idx*4 == i) tmp++;
|
||||
vectors[i].idx = i;
|
||||
vectors[i].closest = tmp;
|
||||
vectors[i].flags = ISFLOAT|ISVEC;
|
||||
}
|
||||
|
||||
regs[Elements(regs)-1].idx = -1;
|
||||
scalars[Elements(scalars)-1].idx = -1;
|
||||
vectors[Elements(vectors)-1].idx = -1;
|
||||
}
|
||||
|
||||
static int find_or_add_value( struct reg *reg, int val )
|
||||
{
|
||||
int j;
|
||||
|
||||
for ( j = 0 ; j < reg->nvalues ; j++)
|
||||
if ( val == reg->values[j].i )
|
||||
return 1;
|
||||
|
||||
if (j == reg->nalloc) {
|
||||
reg->nalloc += 5;
|
||||
reg->nalloc *= 2;
|
||||
reg->values = (union fi *) realloc( reg->values,
|
||||
reg->nalloc * sizeof(union fi) );
|
||||
}
|
||||
|
||||
reg->values[reg->nvalues++].i = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct reg *lookup_reg( struct reg *tab, int reg )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; tab[i].idx != -1 ; i++) {
|
||||
if (tab[i].idx == reg)
|
||||
return &tab[i];
|
||||
}
|
||||
|
||||
fprintf(stderr, "*** unknown reg 0x%x\n", reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *get_reg_name( struct reg *reg )
|
||||
{
|
||||
static char tmp[80];
|
||||
|
||||
if (reg->idx == reg->closest->idx)
|
||||
return reg->closest->name;
|
||||
|
||||
|
||||
if (reg->flags & ISVEC) {
|
||||
if (reg->idx/4 != reg->closest->idx)
|
||||
sprintf(tmp, "%s+%d[%d]",
|
||||
reg->closest->name,
|
||||
(reg->idx/4) - reg->closest->idx,
|
||||
reg->idx%4);
|
||||
else
|
||||
sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4);
|
||||
}
|
||||
else {
|
||||
if (reg->idx != reg->closest->idx)
|
||||
sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx);
|
||||
else
|
||||
sprintf(tmp, "%s", reg->closest->name);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int print_int_reg_assignment( struct reg *reg, int data )
|
||||
{
|
||||
int changed = (reg->current.i != data);
|
||||
int ever_seen = find_or_add_value( reg, data );
|
||||
|
||||
if (VERBOSE || (NORMAL && (changed || !ever_seen)))
|
||||
fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data);
|
||||
|
||||
if (NORMAL) {
|
||||
if (!ever_seen)
|
||||
fprintf(stderr, " *** BRAND NEW VALUE");
|
||||
else if (changed)
|
||||
fprintf(stderr, " *** CHANGED");
|
||||
}
|
||||
|
||||
reg->current.i = data;
|
||||
|
||||
if (VERBOSE || (NORMAL && (changed || !ever_seen)))
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
static int print_float_reg_assignment( struct reg *reg, float data )
|
||||
{
|
||||
int changed = (reg->current.f != data);
|
||||
int newmin = (data < reg->vmin);
|
||||
int newmax = (data > reg->vmax);
|
||||
|
||||
if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
|
||||
fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data);
|
||||
|
||||
if (NORMAL) {
|
||||
if (newmin) {
|
||||
fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin);
|
||||
reg->vmin = data;
|
||||
}
|
||||
else if (newmax) {
|
||||
fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax);
|
||||
reg->vmax = data;
|
||||
}
|
||||
else if (changed) {
|
||||
fprintf(stderr, " *** CHANGED");
|
||||
}
|
||||
}
|
||||
|
||||
reg->current.f = data;
|
||||
|
||||
if (VERBOSE || (NORMAL && (newmin || newmax || changed)))
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int print_reg_assignment( struct reg *reg, int data )
|
||||
{
|
||||
reg->flags |= TOUCHED;
|
||||
if (reg->flags & ISFLOAT)
|
||||
return print_float_reg_assignment( reg, *(float *)&data );
|
||||
else
|
||||
return print_int_reg_assignment( reg, data );
|
||||
}
|
||||
|
||||
static void print_reg( struct reg *reg )
|
||||
{
|
||||
if (reg->flags & TOUCHED) {
|
||||
if (reg->flags & ISFLOAT) {
|
||||
fprintf(stderr, " %s == %f\n", get_reg_name(reg), reg->current.f);
|
||||
} else {
|
||||
fprintf(stderr, " %s == 0x%x\n", get_reg_name(reg), reg->current.i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_state( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < Elements(regs) ; i++)
|
||||
print_reg( ®s[i] );
|
||||
|
||||
for (i = 0 ; i < Elements(scalars) ; i++)
|
||||
print_reg( &scalars[i] );
|
||||
|
||||
for (i = 0 ; i < Elements(vectors) ; i++)
|
||||
print_reg( &vectors[i] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int radeon_emit_packets(
|
||||
drmRadeonCmdHeader header,
|
||||
drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
int id = (int)header.packet.packet_id;
|
||||
int sz = packet[id].len;
|
||||
int *data = (int *)cmdbuf->buf;
|
||||
int i;
|
||||
|
||||
if (sz * sizeof(int) > cmdbuf->bufsz) {
|
||||
fprintf(stderr, "Packet overflows cmdbuf\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!packet[id].name) {
|
||||
fprintf(stderr, "*** Unknown packet 0 nr %d\n", id );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
if (VERBOSE)
|
||||
fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz );
|
||||
|
||||
for ( i = 0 ; i < sz ; i++) {
|
||||
struct reg *reg = lookup_reg( regs, packet[id].start + i*4 );
|
||||
if (print_reg_assignment( reg, data[i] ))
|
||||
total_changed++;
|
||||
total++;
|
||||
}
|
||||
|
||||
cmdbuf->buf += sz * sizeof(int);
|
||||
cmdbuf->bufsz -= sz * sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int radeon_emit_scalars(
|
||||
drmRadeonCmdHeader header,
|
||||
drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
int sz = header.scalars.count;
|
||||
int *data = (int *)cmdbuf->buf;
|
||||
int start = header.scalars.offset;
|
||||
int stride = header.scalars.stride;
|
||||
int i;
|
||||
|
||||
if (VERBOSE)
|
||||
fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n",
|
||||
start, stride, sz, start + stride * sz);
|
||||
|
||||
|
||||
for (i = 0 ; i < sz ; i++, start += stride) {
|
||||
struct reg *reg = lookup_reg( scalars, start );
|
||||
if (print_reg_assignment( reg, data[i] ))
|
||||
total_changed++;
|
||||
total++;
|
||||
}
|
||||
|
||||
cmdbuf->buf += sz * sizeof(int);
|
||||
cmdbuf->bufsz -= sz * sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int radeon_emit_scalars2(
|
||||
drmRadeonCmdHeader header,
|
||||
drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
int sz = header.scalars.count;
|
||||
int *data = (int *)cmdbuf->buf;
|
||||
int start = header.scalars.offset + 0x100;
|
||||
int stride = header.scalars.stride;
|
||||
int i;
|
||||
|
||||
if (VERBOSE)
|
||||
fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n",
|
||||
start, stride, sz, start + stride * sz);
|
||||
|
||||
if (start + stride * sz > 257) {
|
||||
fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < sz ; i++, start += stride) {
|
||||
struct reg *reg = lookup_reg( scalars, start );
|
||||
if (print_reg_assignment( reg, data[i] ))
|
||||
total_changed++;
|
||||
total++;
|
||||
}
|
||||
|
||||
cmdbuf->buf += sz * sizeof(int);
|
||||
cmdbuf->bufsz -= sz * sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check: inf/nan/extreme-size?
|
||||
* Check: table start, end, nr, etc.
|
||||
*/
|
||||
static int radeon_emit_vectors(
|
||||
drmRadeonCmdHeader header,
|
||||
drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
int sz = header.vectors.count;
|
||||
int *data = (int *)cmdbuf->buf;
|
||||
int start = header.vectors.offset;
|
||||
int stride = header.vectors.stride;
|
||||
int i,j;
|
||||
|
||||
if (VERBOSE)
|
||||
fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n",
|
||||
start, stride, sz, start + stride * sz, header.i);
|
||||
|
||||
/* if (start + stride * (sz/4) > 128) { */
|
||||
/* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
|
||||
for (i = 0 ; i < sz ; start += stride) {
|
||||
int changed = 0;
|
||||
for (j = 0 ; j < 4 ; i++,j++) {
|
||||
struct reg *reg = lookup_reg( vectors, start*4+j );
|
||||
if (print_reg_assignment( reg, data[i] ))
|
||||
changed = 1;
|
||||
}
|
||||
if (changed)
|
||||
total_changed += 4;
|
||||
total += 4;
|
||||
}
|
||||
|
||||
|
||||
cmdbuf->buf += sz * sizeof(int);
|
||||
cmdbuf->bufsz -= sz * sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int print_vertex_format( int vfmt )
|
||||
{
|
||||
if (NORMAL) {
|
||||
fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
"vertex format",
|
||||
vfmt,
|
||||
"xy,",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Z) ? "z," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_W0) ? "w0," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_FPCOLOR) ? "fpcolor," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_FPALPHA) ? "fpalpha," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_PKCOLOR) ? "pkcolor," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_FPSPEC) ? "fpspec," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_FPFOG) ? "fpfog," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_PKSPEC) ? "pkspec," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_ST0) ? "st0," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_ST1) ? "st1," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Q1) ? "q1," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_ST2) ? "st2," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Q2) ? "q2," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_ST3) ? "st3," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Q3) ? "q3," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Q0) ? "q0," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_N0) ? "n0," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_XY1) ? "xy1," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_Z1) ? "z1," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_W1) ? "w1," : "",
|
||||
(vfmt & RADEON_CP_VC_FRMT_N1) ? "n1," : "");
|
||||
|
||||
|
||||
/* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */
|
||||
/* fprintf(stderr, " *** NEW VALUE"); */
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *primname[0xf] = {
|
||||
"NONE",
|
||||
"POINT",
|
||||
"LINE",
|
||||
"LINE_STRIP",
|
||||
"TRI_LIST",
|
||||
"TRI_FAN",
|
||||
"TRI_STRIP",
|
||||
"TRI_TYPE_2",
|
||||
"RECT_LIST",
|
||||
"3VRT_POINT_LIST",
|
||||
"3VRT_LINE_LIST",
|
||||
};
|
||||
|
||||
static int print_prim_and_flags( int prim )
|
||||
{
|
||||
int numverts;
|
||||
|
||||
if (NORMAL)
|
||||
fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s\n",
|
||||
"prim flags",
|
||||
prim,
|
||||
((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "",
|
||||
((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "",
|
||||
((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "",
|
||||
(prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ",
|
||||
(prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "",
|
||||
(prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "",
|
||||
(prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : "");
|
||||
|
||||
if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) {
|
||||
fprintf(stderr, " *** Bad primitive: %x\n", prim & 0xf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
numverts = prim>>16;
|
||||
|
||||
if (NORMAL)
|
||||
fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts);
|
||||
|
||||
switch (prim & 0xf) {
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE:
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT:
|
||||
if (numverts < 1) {
|
||||
fprintf(stderr, "Bad nr verts for line %d\n", numverts);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE:
|
||||
if ((numverts & 1) || numverts == 0) {
|
||||
fprintf(stderr, "Bad nr verts for line %d\n", numverts);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP:
|
||||
if (numverts < 2) {
|
||||
fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST:
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST:
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST:
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST:
|
||||
if (numverts % 3 || numverts == 0) {
|
||||
fprintf(stderr, "Bad nr verts for tri %d\n", numverts);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN:
|
||||
case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP:
|
||||
if (numverts < 3) {
|
||||
fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad primitive\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* build in knowledge about each packet type
|
||||
*/
|
||||
static int radeon_emit_packet3( drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
int cmdsz;
|
||||
int *cmd = (int *)cmdbuf->buf;
|
||||
int *tmp;
|
||||
int i, stride, size, start;
|
||||
|
||||
cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
||||
|
||||
if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 ||
|
||||
cmdsz * 4 > cmdbuf->bufsz ||
|
||||
cmdsz > RADEON_CP_PACKET_MAX_DWORDS) {
|
||||
fprintf(stderr, "Bad packet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) {
|
||||
case RADEON_CP_PACKET3_NOP:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_NEXT_CHAR:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_PLY_NEXTSCAN:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_SET_SCISSORS:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_LOAD_MICROCODE:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_WAIT_FOR_IDLE:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz);
|
||||
break;
|
||||
|
||||
case RADEON_CP_PACKET3_3D_DRAW_VBUF:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz);
|
||||
print_vertex_format(cmd[1]);
|
||||
print_prim_and_flags(cmd[2]);
|
||||
break;
|
||||
|
||||
case RADEON_CP_PACKET3_3D_DRAW_IMMD:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_3D_DRAW_INDX: {
|
||||
int neltdwords;
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz);
|
||||
print_vertex_format(cmd[1]);
|
||||
print_prim_and_flags(cmd[2]);
|
||||
neltdwords = cmd[2]>>16;
|
||||
neltdwords += neltdwords & 1;
|
||||
neltdwords /= 2;
|
||||
if (neltdwords + 3 != cmdsz)
|
||||
fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n",
|
||||
neltdwords, cmdsz);
|
||||
break;
|
||||
}
|
||||
case RADEON_CP_PACKET3_LOAD_PALETTE:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_3D_LOAD_VBPNTR:
|
||||
if (NORMAL) {
|
||||
fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz);
|
||||
fprintf(stderr, " nr arrays: %d\n", cmd[1]);
|
||||
}
|
||||
|
||||
if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) {
|
||||
fprintf(stderr, " ****** MISMATCH %d/%d *******\n",
|
||||
cmd[1]/2 + cmd[1]%2 + 3, cmdsz);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NORMAL) {
|
||||
tmp = cmd+2;
|
||||
for (i = 0 ; i < cmd[1] ; i++) {
|
||||
if (i & 1) {
|
||||
stride = (tmp[0]>>24) & 0xff;
|
||||
size = (tmp[0]>>16) & 0xff;
|
||||
start = tmp[2];
|
||||
tmp += 3;
|
||||
}
|
||||
else {
|
||||
stride = (tmp[0]>>8) & 0xff;
|
||||
size = (tmp[0]) & 0xff;
|
||||
start = tmp[1];
|
||||
}
|
||||
fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n",
|
||||
i, start, size, stride );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_PAINT:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_BITBLT:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_SMALLTEXT:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_POLYLINE:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_POLYSCANLINES:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_PAINT_MULTI:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT:
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n",
|
||||
cmdsz);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz);
|
||||
break;
|
||||
}
|
||||
|
||||
cmdbuf->buf += cmdsz * 4;
|
||||
cmdbuf->bufsz -= cmdsz * 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check cliprects for bounds, then pass on to above:
|
||||
*/
|
||||
static int radeon_emit_packet3_cliprect( drmRadeonCmdBuffer *cmdbuf )
|
||||
{
|
||||
XF86DRIClipRectRec *boxes = (XF86DRIClipRectRec *)cmdbuf->boxes;
|
||||
int i = 0;
|
||||
|
||||
if (VERBOSE && total_changed) {
|
||||
dump_state();
|
||||
total_changed = 0;
|
||||
}
|
||||
else fprintf(stderr, "total_changed zero\n");
|
||||
|
||||
if (NORMAL) {
|
||||
do {
|
||||
if ( i < cmdbuf->nbox ) {
|
||||
fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n",
|
||||
i, cmdbuf->nbox,
|
||||
boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2);
|
||||
}
|
||||
} while ( ++i < cmdbuf->nbox );
|
||||
}
|
||||
|
||||
if (cmdbuf->nbox == 1)
|
||||
cmdbuf->nbox = 0;
|
||||
|
||||
return radeon_emit_packet3( cmdbuf );
|
||||
}
|
||||
|
||||
|
||||
int radeonSanityCmdBuffer( radeonContextPtr rmesa,
|
||||
int nbox,
|
||||
XF86DRIClipRectRec *boxes )
|
||||
{
|
||||
int idx;
|
||||
drmRadeonCmdBuffer cmdbuf;
|
||||
drmRadeonCmdHeader header;
|
||||
static int inited = 0;
|
||||
|
||||
if (!inited) {
|
||||
init_regs();
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
cmdbuf.buf = rmesa->store.cmd_buf;
|
||||
cmdbuf.bufsz = rmesa->store.cmd_used;
|
||||
cmdbuf.boxes = (drmClipRect *)boxes;
|
||||
cmdbuf.nbox = nbox;
|
||||
|
||||
while ( cmdbuf.bufsz >= sizeof(header) ) {
|
||||
|
||||
header.i = *(int *)cmdbuf.buf;
|
||||
cmdbuf.buf += sizeof(header);
|
||||
cmdbuf.bufsz -= sizeof(header);
|
||||
|
||||
switch (header.header.cmd_type) {
|
||||
case RADEON_CMD_PACKET:
|
||||
if (radeon_emit_packets( header, &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_packets failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_SCALARS:
|
||||
if (radeon_emit_scalars( header, &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_scalars failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_SCALARS2:
|
||||
if (radeon_emit_scalars2( header, &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_scalars failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_VECTORS:
|
||||
if (radeon_emit_vectors( header, &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_vectors failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_DMA_DISCARD:
|
||||
idx = header.dma.buf_idx;
|
||||
if (NORMAL)
|
||||
fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx);
|
||||
bufs++;
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PACKET3:
|
||||
if (radeon_emit_packet3( &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_packet3 failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PACKET3_CLIP:
|
||||
if (radeon_emit_packet3_cliprect( &cmdbuf )) {
|
||||
fprintf(stderr,"radeon_emit_packet3_clip failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_WAIT:
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"bad cmd_type %d at %p\n",
|
||||
header.header.cmd_type,
|
||||
cmdbuf.buf - sizeof(header));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
static int n = 0;
|
||||
n++;
|
||||
if (n == 10) {
|
||||
fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n",
|
||||
bufs,
|
||||
total, total_changed,
|
||||
((float)total_changed/(float)total*100.0));
|
||||
fprintf(stderr, "Total emitted per buf: %.2f\n",
|
||||
(float)total/(float)bufs);
|
||||
fprintf(stderr, "Real changes per buf: %.2f\n",
|
||||
(float)total_changed/(float)bufs);
|
||||
|
||||
bufs = n = total = total_changed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
8
src/mesa/drivers/dri/radeon/radeon_sanity.h
Normal file
8
src/mesa/drivers/dri/radeon/radeon_sanity.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef RADEON_SANITY_H
|
||||
#define RADEON_SANITY_H
|
||||
|
||||
extern int radeonSanityCmdBuffer( radeonContextPtr rmesa,
|
||||
int nbox,
|
||||
XF86DRIClipRectRec *boxes );
|
||||
|
||||
#endif
|
||||
237
src/mesa/drivers/dri/radeon/radeon_sarea.h
Normal file
237
src/mesa/drivers/dri/radeon/radeon_sarea.h
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.4 2002/04/24 16:20:41 martin Exp $ */
|
||||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario,
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation on the rights to use, copy, modify, merge,
|
||||
* publish, distribute, 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
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
||||
* THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@xfree86.org>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RADEON_SAREA_H_
|
||||
#define _RADEON_SAREA_H_
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the kernel file (radeon_drm.h)
|
||||
*/
|
||||
#ifndef __RADEON_SAREA_DEFINES__
|
||||
#define __RADEON_SAREA_DEFINES__
|
||||
|
||||
/* What needs to be changed for the current vertex buffer? */
|
||||
#define RADEON_UPLOAD_CONTEXT 0x00000001
|
||||
#define RADEON_UPLOAD_VERTFMT 0x00000002
|
||||
#define RADEON_UPLOAD_LINE 0x00000004
|
||||
#define RADEON_UPLOAD_BUMPMAP 0x00000008
|
||||
#define RADEON_UPLOAD_MASKS 0x00000010
|
||||
#define RADEON_UPLOAD_VIEWPORT 0x00000020
|
||||
#define RADEON_UPLOAD_SETUP 0x00000040
|
||||
#define RADEON_UPLOAD_TCL 0x00000080
|
||||
#define RADEON_UPLOAD_MISC 0x00000100
|
||||
#define RADEON_UPLOAD_TEX0 0x00000200
|
||||
#define RADEON_UPLOAD_TEX1 0x00000400
|
||||
#define RADEON_UPLOAD_TEX2 0x00000800
|
||||
#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
|
||||
#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
|
||||
#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
|
||||
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
|
||||
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
|
||||
#define RADEON_UPLOAD_ZBIAS 0x00020000
|
||||
#define RADEON_UPLOAD_ALL 0x0002ffff
|
||||
#define RADEON_UPLOAD_CONTEXT_ALL 0x000201ff
|
||||
|
||||
#define RADEON_FRONT 0x1
|
||||
#define RADEON_BACK 0x2
|
||||
#define RADEON_DEPTH 0x4
|
||||
#define RADEON_STENCIL 0x8
|
||||
|
||||
/* Primitive types */
|
||||
#define RADEON_POINTS 0x1
|
||||
#define RADEON_LINES 0x2
|
||||
#define RADEON_LINE_STRIP 0x3
|
||||
#define RADEON_TRIANGLES 0x4
|
||||
#define RADEON_TRIANGLE_FAN 0x5
|
||||
#define RADEON_TRIANGLE_STRIP 0x6
|
||||
#define RADEON_3VTX_POINTS 0x9
|
||||
#define RADEON_3VTX_LINES 0xa
|
||||
|
||||
/* Vertex/indirect buffer size */
|
||||
#define RADEON_BUFFER_SIZE 65536
|
||||
|
||||
/* Byte offsets for indirect buffer data */
|
||||
#define RADEON_INDEX_PRIM_OFFSET 20
|
||||
#define RADEON_HOSTDATA_BLIT_OFFSET 32
|
||||
|
||||
#define RADEON_SCRATCH_REG_OFFSET 32
|
||||
|
||||
/* Keep these small for testing */
|
||||
#define RADEON_NR_SAREA_CLIPRECTS 12
|
||||
|
||||
/* There are 2 heaps (local/AGP). Each region within a heap is a
|
||||
* minimum of 64k, and there are at most 64 of them per heap.
|
||||
*/
|
||||
#define RADEON_CARD_HEAP 0
|
||||
#define RADEON_AGP_HEAP 1
|
||||
#define RADEON_NR_TEX_HEAPS 2
|
||||
#define RADEON_NR_TEX_REGIONS 64
|
||||
#define RADEON_LOG_TEX_GRANULARITY 16
|
||||
|
||||
#define RADEON_MAX_TEXTURE_LEVELS 12
|
||||
#define RADEON_MAX_TEXTURE_UNITS 3
|
||||
|
||||
/* Blits have strict offset rules. All blit offset must be aligned on
|
||||
* a 1K-byte boundary.
|
||||
*/
|
||||
#define RADEON_OFFSET_SHIFT 10
|
||||
#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
|
||||
#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
|
||||
|
||||
#endif /* __RADEON_SAREA_DEFINES__ */
|
||||
|
||||
typedef struct {
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
unsigned int alpha;
|
||||
} radeon_color_regs_t;
|
||||
|
||||
typedef struct {
|
||||
/* Context state */
|
||||
unsigned int pp_misc;
|
||||
unsigned int pp_fog_color;
|
||||
unsigned int re_solid_color;
|
||||
unsigned int rb3d_blendcntl;
|
||||
unsigned int rb3d_depthoffset;
|
||||
unsigned int rb3d_depthpitch;
|
||||
unsigned int rb3d_zstencilcntl;
|
||||
|
||||
unsigned int pp_cntl;
|
||||
unsigned int rb3d_cntl;
|
||||
unsigned int rb3d_coloroffset;
|
||||
unsigned int re_width_height;
|
||||
unsigned int rb3d_colorpitch;
|
||||
unsigned int se_cntl;
|
||||
|
||||
/* Vertex format state */
|
||||
unsigned int se_coord_fmt;
|
||||
|
||||
/* Line state */
|
||||
unsigned int re_line_pattern;
|
||||
unsigned int re_line_state;
|
||||
|
||||
unsigned int se_line_width;
|
||||
|
||||
/* Bumpmap state */
|
||||
unsigned int pp_lum_matrix;
|
||||
|
||||
unsigned int pp_rot_matrix_0;
|
||||
unsigned int pp_rot_matrix_1;
|
||||
|
||||
/* Mask state */
|
||||
unsigned int rb3d_stencilrefmask;
|
||||
unsigned int rb3d_ropcntl;
|
||||
unsigned int rb3d_planemask;
|
||||
|
||||
/* Viewport state */
|
||||
unsigned int se_vport_xscale;
|
||||
unsigned int se_vport_xoffset;
|
||||
unsigned int se_vport_yscale;
|
||||
unsigned int se_vport_yoffset;
|
||||
unsigned int se_vport_zscale;
|
||||
unsigned int se_vport_zoffset;
|
||||
|
||||
/* Setup state */
|
||||
unsigned int se_cntl_status;
|
||||
|
||||
/* Misc state */
|
||||
unsigned int re_top_left;
|
||||
unsigned int re_misc;
|
||||
} radeon_context_regs_t;
|
||||
|
||||
/* Setup registers for each texture unit */
|
||||
typedef struct {
|
||||
unsigned int pp_txfilter;
|
||||
unsigned int pp_txformat;
|
||||
unsigned int pp_txoffset;
|
||||
unsigned int pp_txcblend;
|
||||
unsigned int pp_txablend;
|
||||
unsigned int pp_tfactor;
|
||||
unsigned int pp_border_color;
|
||||
} radeon_texture_regs_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char next, prev; /* indices to form a circular LRU */
|
||||
unsigned char in_use; /* owned by a client, or free? */
|
||||
int age; /* tracked by clients to update local LRU's */
|
||||
} radeon_tex_region_t;
|
||||
|
||||
typedef struct {
|
||||
/* The channel for communication of state information to the kernel
|
||||
* on firing a vertex buffer.
|
||||
*/
|
||||
radeon_context_regs_t ContextState;
|
||||
radeon_texture_regs_t TexState[RADEON_MAX_TEXTURE_UNITS];
|
||||
unsigned int dirty;
|
||||
unsigned int vertsize;
|
||||
unsigned int vc_format;
|
||||
|
||||
/* The current cliprects, or a subset thereof */
|
||||
XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS];
|
||||
unsigned int nbox;
|
||||
|
||||
/* Counters for throttling of rendering clients */
|
||||
unsigned int last_frame;
|
||||
unsigned int last_dispatch;
|
||||
unsigned int last_clear;
|
||||
|
||||
/* Maintain an LRU of contiguous regions of texture space. If you
|
||||
* think you own a region of texture memory, and it has an age
|
||||
* different to the one you set, then you are mistaken and it has
|
||||
* been stolen by another client. If global texAge hasn't changed,
|
||||
* there is no need to walk the list.
|
||||
*
|
||||
* These regions can be used as a proxy for the fine-grained texture
|
||||
* information of other clients - by maintaining them in the same
|
||||
* lru which is used to age their own textures, clients have an
|
||||
* approximate lru for the whole of global texture space, and can
|
||||
* make informed decisions as to which areas to kick out. There is
|
||||
* no need to choose whether to kick out your own texture or someone
|
||||
* else's - simply eject them all in LRU order.
|
||||
*/
|
||||
/* Last elt is sentinal */
|
||||
radeon_tex_region_t texList[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
|
||||
/* last time texture was uploaded */
|
||||
int texAge[RADEON_NR_TEX_HEAPS];
|
||||
|
||||
int ctxOwner; /* last context to upload state */
|
||||
int pfAllowPageFlip; /* set by the 2d driver, read by the client */
|
||||
int pfCurrentPage; /* set by kernel, read by others */
|
||||
int crtc2_base; /* for pageflipping with CloneMode */
|
||||
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;
|
||||
|
||||
#endif
|
||||
268
src/mesa/drivers/dri/radeon/radeon_screen.c
Normal file
268
src/mesa/drivers/dri/radeon/radeon_screen.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
|
||||
#include "radeon_screen.h"
|
||||
|
||||
|
||||
#if 1
|
||||
/* Including xf86PciInfo.h introduces a bunch of errors...
|
||||
*/
|
||||
#define PCI_CHIP_RADEON_QD 0x5144
|
||||
#define PCI_CHIP_RADEON_QE 0x5145
|
||||
#define PCI_CHIP_RADEON_QF 0x5146
|
||||
#define PCI_CHIP_RADEON_QG 0x5147
|
||||
|
||||
#define PCI_CHIP_RADEON_QY 0x5159
|
||||
#define PCI_CHIP_RADEON_QZ 0x515A
|
||||
|
||||
#define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */
|
||||
|
||||
#define PCI_CHIP_RADEON_LY 0x4C59
|
||||
#define PCI_CHIP_RADEON_LZ 0x4C5A
|
||||
|
||||
#define PCI_CHIP_RV200_QW 0x5157 /* a confusing name for a radeon */
|
||||
#endif
|
||||
|
||||
|
||||
/* Create the device specific screen private data struct.
|
||||
*/
|
||||
radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
radeonScreenPtr radeonScreen;
|
||||
RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv;
|
||||
|
||||
/* Check the DRI extension version */
|
||||
if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) {
|
||||
__driUtilMessage( "Radeon DRI driver expected DRI version 4.0.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->driMajor, sPriv->driMinor, sPriv->driPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that the DDX driver version is compatible */
|
||||
if ( sPriv->ddxMajor != 4 ||
|
||||
sPriv->ddxMinor < 0 ) {
|
||||
__driUtilMessage( "Radeon DRI driver expected DDX driver version 4.0.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that the DRM driver version is compatible */
|
||||
if ( sPriv->drmMajor != 1 ) {
|
||||
__driUtilMessage( "Radeon DRI driver expected DRM driver version 1.x.x "
|
||||
"but got version %d.%d.%d",
|
||||
sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate the private area */
|
||||
radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) );
|
||||
if ( !radeonScreen ) {
|
||||
__driUtilMessage("%s: CALLOC radeonScreen struct failed",
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( sPriv->drmMinor < 3 ||
|
||||
getenv("RADEON_COMPAT")) {
|
||||
fprintf( stderr, "Radeon DRI driver:\n\t"
|
||||
"Compatibility mode for DRM driver version %d.%d.%d\n\t"
|
||||
"TCL will be disabled, expect reduced performance\n\t"
|
||||
"(prefer DRM radeon.o 1.3.x or newer)\n\t",
|
||||
sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
|
||||
}
|
||||
|
||||
|
||||
/* This is first since which regions we map depends on whether or
|
||||
* not we are using a PCI card.
|
||||
*/
|
||||
radeonScreen->IsPCI = radeonDRIPriv->IsPCI;
|
||||
|
||||
if (sPriv->drmMinor >= 3) {
|
||||
int ret;
|
||||
drmRadeonGetParam gp;
|
||||
|
||||
gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET;
|
||||
gp.value = &radeonScreen->agp_buffer_offset;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sPriv->drmMinor >= 6) {
|
||||
gp.param = RADEON_PARAM_IRQ_NR;
|
||||
gp.value = &radeonScreen->irq;
|
||||
|
||||
ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (ret) {
|
||||
fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
radeonScreen->mmio.handle = radeonDRIPriv->registerHandle;
|
||||
radeonScreen->mmio.size = radeonDRIPriv->registerSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
radeonScreen->mmio.handle,
|
||||
radeonScreen->mmio.size,
|
||||
&radeonScreen->mmio.map ) ) {
|
||||
FREE( radeonScreen );
|
||||
__driUtilMessage("radeonCreateScreen(): drmMap failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
radeonScreen->status.handle = radeonDRIPriv->statusHandle;
|
||||
radeonScreen->status.size = radeonDRIPriv->statusSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
radeonScreen->status.handle,
|
||||
radeonScreen->status.size,
|
||||
&radeonScreen->status.map ) ) {
|
||||
drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
|
||||
FREE( radeonScreen );
|
||||
__driUtilMessage("radeonCreateScreen(): drmMap (2) failed\n");
|
||||
return NULL;
|
||||
}
|
||||
radeonScreen->scratch = (__volatile__ GLuint *)
|
||||
((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
||||
|
||||
radeonScreen->buffers = drmMapBufs( sPriv->fd );
|
||||
if ( !radeonScreen->buffers ) {
|
||||
drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
|
||||
drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
|
||||
FREE( radeonScreen );
|
||||
__driUtilMessage("radeonCreateScreen(): drmMapBufs failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !radeonScreen->IsPCI ) {
|
||||
radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle;
|
||||
radeonScreen->agpTextures.size = radeonDRIPriv->agpTexMapSize;
|
||||
if ( drmMap( sPriv->fd,
|
||||
radeonScreen->agpTextures.handle,
|
||||
radeonScreen->agpTextures.size,
|
||||
(drmAddressPtr)&radeonScreen->agpTextures.map ) ) {
|
||||
drmUnmapBufs( radeonScreen->buffers );
|
||||
drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
|
||||
drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
|
||||
FREE( radeonScreen );
|
||||
__driUtilMessage("radeonCreateScreen(): IsPCI failed\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
radeonScreen->chipset = 0;
|
||||
switch ( radeonDRIPriv->deviceID ) {
|
||||
default:
|
||||
fprintf(stderr, "unknown chip id, assuming full radeon support\n");
|
||||
case PCI_CHIP_RADEON_QD:
|
||||
case PCI_CHIP_RADEON_QE:
|
||||
case PCI_CHIP_RADEON_QF:
|
||||
case PCI_CHIP_RADEON_QG:
|
||||
case PCI_CHIP_RV200_QW:
|
||||
case PCI_CHIP_RADEON_LW:
|
||||
radeonScreen->chipset |= RADEON_CHIPSET_TCL;
|
||||
case PCI_CHIP_RADEON_QY:
|
||||
case PCI_CHIP_RADEON_QZ:
|
||||
case PCI_CHIP_RADEON_LY:
|
||||
case PCI_CHIP_RADEON_LZ:
|
||||
break;
|
||||
}
|
||||
|
||||
radeonScreen->cpp = radeonDRIPriv->bpp / 8;
|
||||
radeonScreen->AGPMode = radeonDRIPriv->AGPMode;
|
||||
|
||||
radeonScreen->frontOffset = radeonDRIPriv->frontOffset;
|
||||
radeonScreen->frontPitch = radeonDRIPriv->frontPitch;
|
||||
radeonScreen->backOffset = radeonDRIPriv->backOffset;
|
||||
radeonScreen->backPitch = radeonDRIPriv->backPitch;
|
||||
radeonScreen->depthOffset = radeonDRIPriv->depthOffset;
|
||||
radeonScreen->depthPitch = radeonDRIPriv->depthPitch;
|
||||
|
||||
radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset;
|
||||
radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize;
|
||||
radeonScreen->logTexGranularity[RADEON_CARD_HEAP] =
|
||||
radeonDRIPriv->log2TexGran;
|
||||
|
||||
if ( radeonScreen->IsPCI ) {
|
||||
radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
|
||||
radeonScreen->texOffset[RADEON_AGP_HEAP] = 0;
|
||||
radeonScreen->texSize[RADEON_AGP_HEAP] = 0;
|
||||
radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0;
|
||||
} else {
|
||||
radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS;
|
||||
radeonScreen->texOffset[RADEON_AGP_HEAP] =
|
||||
radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET;
|
||||
radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize;
|
||||
radeonScreen->logTexGranularity[RADEON_AGP_HEAP] =
|
||||
radeonDRIPriv->log2AGPTexGran;
|
||||
}
|
||||
|
||||
radeonScreen->driScreen = sPriv;
|
||||
radeonScreen->sarea_priv_offset = radeonDRIPriv->sarea_priv_offset;
|
||||
return radeonScreen;
|
||||
}
|
||||
|
||||
/* Destroy the device specific screen private data struct.
|
||||
*/
|
||||
void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
|
||||
{
|
||||
radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private;
|
||||
|
||||
if (!radeonScreen)
|
||||
return;
|
||||
|
||||
if ( !radeonScreen->IsPCI ) {
|
||||
drmUnmap( radeonScreen->agpTextures.map,
|
||||
radeonScreen->agpTextures.size );
|
||||
}
|
||||
drmUnmapBufs( radeonScreen->buffers );
|
||||
drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
|
||||
drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
|
||||
|
||||
FREE( radeonScreen );
|
||||
sPriv->private = NULL;
|
||||
}
|
||||
101
src/mesa/drivers/dri/radeon/radeon_screen.h
Normal file
101
src/mesa/drivers/dri/radeon/radeon_screen.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.3 2002/02/22 21:45:01 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_SCREEN_H__
|
||||
#define __RADEON_SCREEN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
/*
|
||||
* IMPORTS: these headers contain all the DRI, X and kernel-related
|
||||
* definitions that we need.
|
||||
*/
|
||||
#include "dri_util.h"
|
||||
#include "radeon_common.h"
|
||||
#include "radeon_dri.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon_sarea.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
drmHandle handle; /* Handle to the DRM region */
|
||||
drmSize size; /* Size of the DRM region */
|
||||
drmAddress map; /* Mapping of the DRM region */
|
||||
} radeonRegionRec, *radeonRegionPtr;
|
||||
|
||||
/* chipset features */
|
||||
#define RADEON_CHIPSET_TCL (1 << 0)
|
||||
|
||||
typedef struct {
|
||||
|
||||
int chipset;
|
||||
int cpp;
|
||||
int IsPCI; /* Current card is a PCI card */
|
||||
int AGPMode;
|
||||
unsigned int irq; /* IRQ number (0 means none) */
|
||||
|
||||
unsigned int frontOffset;
|
||||
unsigned int frontPitch;
|
||||
unsigned int backOffset;
|
||||
unsigned int backPitch;
|
||||
|
||||
unsigned int depthOffset;
|
||||
unsigned int depthPitch;
|
||||
|
||||
/* Shared texture data */
|
||||
int numTexHeaps;
|
||||
int texOffset[RADEON_NR_TEX_HEAPS];
|
||||
int texSize[RADEON_NR_TEX_HEAPS];
|
||||
int logTexGranularity[RADEON_NR_TEX_HEAPS];
|
||||
|
||||
radeonRegionRec mmio;
|
||||
radeonRegionRec status;
|
||||
radeonRegionRec agpTextures;
|
||||
|
||||
drmBufMapPtr buffers;
|
||||
|
||||
__volatile__ GLuint *scratch;
|
||||
|
||||
__DRIscreenPrivate *driScreen;
|
||||
unsigned int sarea_priv_offset;
|
||||
unsigned int agp_buffer_offset; /* offset in card memory space */
|
||||
} radeonScreenRec, *radeonScreenPtr;
|
||||
|
||||
extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv );
|
||||
extern void radeonDestroyScreen( __DRIscreenPrivate *sPriv );
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_SCREEN_H__ */
|
||||
410
src/mesa/drivers/dri/radeon/radeon_span.c
Normal file
410
src/mesa/drivers/dri/radeon/radeon_span.c
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v 1.5 2002/02/22 21:45:01 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_span.h"
|
||||
#include "radeon_tex.h"
|
||||
|
||||
#define DBG 0
|
||||
|
||||
#define LOCAL_VARS \
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
|
||||
radeonScreenPtr radeonScreen = rmesa->radeonScreen; \
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \
|
||||
GLuint height = dPriv->h; \
|
||||
char *buf = (char *)(sPriv->pFB + \
|
||||
rmesa->state.color.drawOffset + \
|
||||
(dPriv->x * radeonScreen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
char *read_buf = (char *)(sPriv->pFB + \
|
||||
rmesa->state.pixel.readOffset + \
|
||||
(dPriv->x * radeonScreen->cpp) + \
|
||||
(dPriv->y * pitch)); \
|
||||
GLuint p; \
|
||||
(void) read_buf; (void) buf; (void) p
|
||||
|
||||
#define LOCAL_DEPTH_VARS \
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
|
||||
radeonScreenPtr radeonScreen = rmesa->radeonScreen; \
|
||||
__DRIscreenPrivate *sPriv = rmesa->dri.screen; \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
GLuint height = dPriv->h; \
|
||||
GLuint xo = dPriv->x; \
|
||||
GLuint yo = dPriv->y; \
|
||||
char *buf = (char *)(sPriv->pFB + radeonScreen->depthOffset); \
|
||||
(void) buf
|
||||
|
||||
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
|
||||
|
||||
|
||||
#define CLIPPIXEL( _x, _y ) \
|
||||
((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
|
||||
|
||||
|
||||
#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
|
||||
if ( _y < miny || _y >= maxy ) { \
|
||||
_n1 = 0, _x1 = x; \
|
||||
} else { \
|
||||
_n1 = _n; \
|
||||
_x1 = _x; \
|
||||
if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
|
||||
if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
|
||||
}
|
||||
|
||||
#define Y_FLIP( _y ) (height - _y - 1)
|
||||
|
||||
|
||||
#define HW_LOCK()
|
||||
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \
|
||||
int _nc = dPriv->numClipRects; \
|
||||
\
|
||||
while ( _nc-- ) { \
|
||||
int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
|
||||
int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
|
||||
int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
|
||||
int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
|
||||
|
||||
#define HW_ENDCLIPLOOP() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HW_UNLOCK()
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Color buffer
|
||||
*/
|
||||
|
||||
/* 16 bit, RGB565 color spanline and pixel functions
|
||||
*/
|
||||
#define INIT_MONO_PIXEL(p, color) \
|
||||
p = PACK_COLOR_565( color[0], color[1], color[2] )
|
||||
|
||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
|
||||
(((int)g & 0xfc) << 3) | \
|
||||
(((int)b & 0xf8) >> 3))
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
*(GLushort *)(buf + _x*2 + _y*pitch) = p
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
|
||||
rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
|
||||
rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
|
||||
rgba[3] = 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) 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 ) \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
|
||||
(g << 8) | \
|
||||
(r << 16) | \
|
||||
(a << 24) )
|
||||
|
||||
#define WRITE_PIXEL( _x, _y, p ) \
|
||||
*(GLuint *)(buf + _x*4 + _y*pitch) = p
|
||||
|
||||
#define READ_RGBA( rgba, _x, _y ) \
|
||||
do { \
|
||||
GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
|
||||
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 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.
|
||||
*/
|
||||
static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa,
|
||||
GLint x, GLint y )
|
||||
{
|
||||
radeonScreenPtr radeonScreen = rmesa->radeonScreen;
|
||||
GLuint pitch = radeonScreen->frontPitch;
|
||||
GLuint ba, address = 0; /* a[0] = 0 */
|
||||
|
||||
ba = (y / 16) * (pitch / 32) + (x / 32);
|
||||
|
||||
address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */
|
||||
address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */
|
||||
address |= (x & 0x8) << 4; /* a[7] = x[3] */
|
||||
address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
|
||||
address |= (y & 0x8) << 7; /* a[10] = y[3] */
|
||||
address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */
|
||||
address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static GLuint radeon_mba_z32( radeonContextPtr rmesa,
|
||||
GLint x, GLint y )
|
||||
{
|
||||
radeonScreenPtr radeonScreen = rmesa->radeonScreen;
|
||||
GLuint pitch = radeonScreen->frontPitch;
|
||||
GLuint ba, address = 0; /* a[0..1] = 0 */
|
||||
|
||||
ba = (y / 16) * (pitch / 16) + (x / 16);
|
||||
|
||||
address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */
|
||||
address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */
|
||||
address |=
|
||||
(((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */
|
||||
address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
|
||||
|
||||
address |= (y & 0x8) << 7; /* a[10] = y[3] */
|
||||
address |=
|
||||
(((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */
|
||||
address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
/* 16-bit depth buffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
*(GLushort *)(buf + radeon_mba_z16( rmesa, _x + xo, _y + yo )) = d;
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x + xo, _y + yo ));
|
||||
|
||||
#define TAG(x) radeon##x##_16
|
||||
#include "depthtmp.h"
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_DEPTH( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
tmp |= ((d) & 0x00ffffff); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_DEPTH( d, _x, _y ) \
|
||||
d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x + xo, \
|
||||
_y + yo )) & 0x00ffffff;
|
||||
|
||||
#define TAG(x) radeon##x##_24_8
|
||||
#include "depthtmp.h"
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Stencil buffer
|
||||
*/
|
||||
|
||||
/* 24 bit depth, 8 bit stencil depthbuffer functions
|
||||
*/
|
||||
#define WRITE_STENCIL( _x, _y, d ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0x00ffffff; \
|
||||
tmp |= (((d) & 0xff) << 24); \
|
||||
*(GLuint *)(buf + offset) = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define READ_STENCIL( d, _x, _y ) \
|
||||
do { \
|
||||
GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \
|
||||
GLuint tmp = *(GLuint *)(buf + offset); \
|
||||
tmp &= 0xff000000; \
|
||||
d = tmp >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define TAG(x) radeon##x##_24_8
|
||||
#include "stenciltmp.h"
|
||||
|
||||
|
||||
/*
|
||||
* This function is called to specify which buffer to read and write
|
||||
* for software rasterization (swrast) fallbacks. This doesn't necessarily
|
||||
* correspond to glDrawBuffer() or glReadBuffer() calls.
|
||||
*/
|
||||
static void radeonSetBuffer( GLcontext *ctx,
|
||||
GLframebuffer *colorBuffer,
|
||||
GLuint bufferBit )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
switch ( bufferBit ) {
|
||||
case FRONT_LEFT_BIT:
|
||||
if ( rmesa->sarea->pfCurrentPage == 1 ) {
|
||||
rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
|
||||
} else {
|
||||
rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
|
||||
}
|
||||
break;
|
||||
case BACK_LEFT_BIT:
|
||||
if ( rmesa->sarea->pfCurrentPage == 1 ) {
|
||||
rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
|
||||
} else {
|
||||
rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch;
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
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 rmesa = RADEON_CONTEXT( ctx );
|
||||
RADEON_FIREVERTICES( rmesa );
|
||||
LOCK_HARDWARE( rmesa );
|
||||
radeonWaitForIdleLocked( rmesa );
|
||||
}
|
||||
|
||||
static void radeonSpanRenderFinish( GLcontext *ctx )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
|
||||
_swrast_flush( ctx );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
}
|
||||
|
||||
void radeonInitSpanFuncs( GLcontext *ctx )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
|
||||
|
||||
swdd->SetBuffer = radeonSetBuffer;
|
||||
|
||||
switch ( rmesa->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;
|
||||
}
|
||||
|
||||
switch ( rmesa->glCtx->Visual.depthBits ) {
|
||||
case 16:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_16;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_16;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_16;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_16;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
swdd->ReadDepthSpan = radeonReadDepthSpan_24_8;
|
||||
swdd->WriteDepthSpan = radeonWriteDepthSpan_24_8;
|
||||
swdd->ReadDepthPixels = radeonReadDepthPixels_24_8;
|
||||
swdd->WriteDepthPixels = radeonWriteDepthPixels_24_8;
|
||||
|
||||
swdd->ReadStencilSpan = radeonReadStencilSpan_24_8;
|
||||
swdd->WriteStencilSpan = radeonWriteStencilSpan_24_8;
|
||||
swdd->ReadStencilPixels = radeonReadStencilPixels_24_8;
|
||||
swdd->WriteStencilPixels = radeonWriteStencilPixels_24_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
swdd->SpanRenderStart = radeonSpanRenderStart;
|
||||
swdd->SpanRenderFinish = radeonSpanRenderFinish;
|
||||
}
|
||||
45
src/mesa/drivers/dri/radeon/radeon_span.h
Normal file
45
src/mesa/drivers/dri/radeon/radeon_span.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.h,v 1.2 2002/02/22 21:45:01 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_SPAN_H__
|
||||
#define __RADEON_SPAN_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void radeonInitSpanFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
2165
src/mesa/drivers/dri/radeon/radeon_state.c
Normal file
2165
src/mesa/drivers/dri/radeon/radeon_state.c
Normal file
File diff suppressed because it is too large
Load diff
76
src/mesa/drivers/dri/radeon/radeon_state.h
Normal file
76
src/mesa/drivers/dri/radeon/radeon_state.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.3 2002/09/16 18:05:20 eich Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_STATE_H__
|
||||
#define __RADEON_STATE_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "radeon_context.h"
|
||||
|
||||
extern void radeonInitState( radeonContextPtr rmesa );
|
||||
extern void radeonInitStateFuncs( GLcontext *ctx );
|
||||
|
||||
extern void radeonUpdateMaterial( GLcontext *ctx );
|
||||
|
||||
extern void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode );
|
||||
extern void radeonRecalcScissorRects( radeonContextPtr rmesa );
|
||||
extern void radeonUpdateViewportOffset( GLcontext *ctx );
|
||||
extern void radeonUpdateWindow( GLcontext *ctx );
|
||||
|
||||
extern void radeonValidateState( GLcontext *ctx );
|
||||
|
||||
extern void radeonPrintDirty( radeonContextPtr rmesa,
|
||||
const char *msg );
|
||||
|
||||
|
||||
extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
#define FALLBACK( rmesa, bit, mode ) do { \
|
||||
if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
|
||||
__FUNCTION__, bit, mode ); \
|
||||
radeonFallback( rmesa->glCtx, bit, mode ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define MODEL_PROJ 0
|
||||
#define MODEL 1
|
||||
#define MODEL_IT 2
|
||||
#define TEXMAT_0 3
|
||||
#define TEXMAT_1 4
|
||||
#define TEXMAT_2 5
|
||||
|
||||
#endif
|
||||
#endif
|
||||
558
src/mesa/drivers/dri/radeon/radeon_state_init.c
Normal file
558
src/mesa/drivers/dri/radeon/radeon_state_init.c
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
* Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VA LINUX SYSTEMS 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:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "api_arrayelt.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_tcl.h"
|
||||
#include "radeon_tex.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_vtxfmt.h"
|
||||
|
||||
/* =============================================================
|
||||
* State initialization
|
||||
*/
|
||||
|
||||
void radeonPrintDirty( radeonContextPtr rmesa, const char *msg )
|
||||
{
|
||||
struct radeon_state_atom *l;
|
||||
|
||||
fprintf(stderr, msg);
|
||||
fprintf(stderr, ": ");
|
||||
|
||||
foreach(l, &(rmesa->hw.dirty)) {
|
||||
fprintf(stderr, "%s, ", l->name);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static int cmdpkt( int id )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.packet.cmd_type = RADEON_CMD_PACKET;
|
||||
h.packet.packet_id = id;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
static int cmdvec( int offset, int stride, int count )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.vectors.cmd_type = RADEON_CMD_VECTORS;
|
||||
h.vectors.offset = offset;
|
||||
h.vectors.stride = stride;
|
||||
h.vectors.count = count;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
static int cmdscl( int offset, int stride, int count )
|
||||
{
|
||||
drmRadeonCmdHeader h;
|
||||
h.i = 0;
|
||||
h.scalars.cmd_type = RADEON_CMD_SCALARS;
|
||||
h.scalars.offset = offset;
|
||||
h.scalars.stride = stride;
|
||||
h.scalars.count = count;
|
||||
return h.i;
|
||||
}
|
||||
|
||||
#define CHECK( NM, FLAG ) \
|
||||
static GLboolean check_##NM( GLcontext *ctx ) \
|
||||
{ \
|
||||
return FLAG; \
|
||||
}
|
||||
|
||||
#define TCL_CHECK( NM, FLAG ) \
|
||||
static GLboolean check_##NM( GLcontext *ctx ) \
|
||||
{ \
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
|
||||
return !rmesa->TclFallback && (FLAG); \
|
||||
}
|
||||
|
||||
|
||||
CHECK( always, GL_TRUE )
|
||||
CHECK( tex0, ctx->Texture.Unit[0]._ReallyEnabled )
|
||||
CHECK( tex1, ctx->Texture.Unit[1]._ReallyEnabled )
|
||||
CHECK( fog, ctx->Fog.Enabled )
|
||||
TCL_CHECK( tcl, GL_TRUE )
|
||||
TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled )
|
||||
TCL_CHECK( tcl_tex1, ctx->Texture.Unit[1]._ReallyEnabled )
|
||||
TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
|
||||
TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled )
|
||||
TCL_CHECK( tcl_lit0, ctx->Light.Enabled && ctx->Light.Light[0].Enabled )
|
||||
TCL_CHECK( tcl_lit1, ctx->Light.Enabled && ctx->Light.Light[1].Enabled )
|
||||
TCL_CHECK( tcl_lit2, ctx->Light.Enabled && ctx->Light.Light[2].Enabled )
|
||||
TCL_CHECK( tcl_lit3, ctx->Light.Enabled && ctx->Light.Light[3].Enabled )
|
||||
TCL_CHECK( tcl_lit4, ctx->Light.Enabled && ctx->Light.Light[4].Enabled )
|
||||
TCL_CHECK( tcl_lit5, ctx->Light.Enabled && ctx->Light.Light[5].Enabled )
|
||||
TCL_CHECK( tcl_lit6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled )
|
||||
TCL_CHECK( tcl_lit7, ctx->Light.Enabled && ctx->Light.Light[7].Enabled )
|
||||
TCL_CHECK( tcl_ucp0, (ctx->Transform.ClipPlanesEnabled & 0x1) )
|
||||
TCL_CHECK( tcl_ucp1, (ctx->Transform.ClipPlanesEnabled & 0x2) )
|
||||
TCL_CHECK( tcl_ucp2, (ctx->Transform.ClipPlanesEnabled & 0x4) )
|
||||
TCL_CHECK( tcl_ucp3, (ctx->Transform.ClipPlanesEnabled & 0x8) )
|
||||
TCL_CHECK( tcl_ucp4, (ctx->Transform.ClipPlanesEnabled & 0x10) )
|
||||
TCL_CHECK( tcl_ucp5, (ctx->Transform.ClipPlanesEnabled & 0x20) )
|
||||
TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled )
|
||||
|
||||
|
||||
|
||||
/* Initialize the context's hardware state.
|
||||
*/
|
||||
void radeonInitState( radeonContextPtr rmesa )
|
||||
{
|
||||
GLcontext *ctx = rmesa->glCtx;
|
||||
GLuint color_fmt, depth_fmt, i;
|
||||
|
||||
switch ( rmesa->radeonScreen->cpp ) {
|
||||
case 2:
|
||||
color_fmt = RADEON_COLOR_FORMAT_RGB565;
|
||||
break;
|
||||
case 4:
|
||||
color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
rmesa->state.color.clear = 0x00000000;
|
||||
|
||||
switch ( ctx->Visual.depthBits ) {
|
||||
case 16:
|
||||
rmesa->state.depth.clear = 0x0000ffff;
|
||||
rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff;
|
||||
depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
|
||||
rmesa->state.stencil.clear = 0x00000000;
|
||||
break;
|
||||
case 24:
|
||||
rmesa->state.depth.clear = 0x00ffffff;
|
||||
rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff;
|
||||
depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
|
||||
rmesa->state.stencil.clear = 0xff000000;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
|
||||
ctx->Visual.depthBits );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
/* Only have hw stencil when depth buffer is 24 bits deep */
|
||||
rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 &&
|
||||
ctx->Visual.depthBits == 24 );
|
||||
|
||||
rmesa->Fallback = 0;
|
||||
|
||||
if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) {
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
|
||||
} else {
|
||||
rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
|
||||
rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
|
||||
}
|
||||
rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset;
|
||||
rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch;
|
||||
|
||||
/* Initialize lists:
|
||||
*/
|
||||
make_empty_list(&(rmesa->hw.dirty));
|
||||
make_empty_list(&(rmesa->hw.clean));
|
||||
|
||||
|
||||
#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \
|
||||
do { \
|
||||
rmesa->hw.ATOM.cmd_size = SZ; \
|
||||
rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \
|
||||
rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \
|
||||
rmesa->hw.ATOM.name = NM; \
|
||||
rmesa->hw.ATOM.is_tcl = FLAG; \
|
||||
rmesa->hw.ATOM.check = check_##CHK; \
|
||||
insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Allocate state buffers:
|
||||
*/
|
||||
ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 );
|
||||
ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 );
|
||||
ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 );
|
||||
ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 );
|
||||
ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 );
|
||||
ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 );
|
||||
ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 );
|
||||
ALLOC_STATE( tcl, always, TCL_STATE_SIZE, "TCL/tcl", 1 );
|
||||
ALLOC_STATE( mtl, tcl_lighting, MTL_STATE_SIZE, "MTL/material", 1 );
|
||||
ALLOC_STATE( grd, always, GRD_STATE_SIZE, "GRD/guard-band", 1 );
|
||||
ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 );
|
||||
ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 );
|
||||
ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 );
|
||||
ALLOC_STATE( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0 );
|
||||
ALLOC_STATE( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0 );
|
||||
ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 );
|
||||
ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 );
|
||||
ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
|
||||
ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 );
|
||||
ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 );
|
||||
ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 );
|
||||
ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
|
||||
ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 );
|
||||
ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 );
|
||||
ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 );
|
||||
ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 );
|
||||
ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 );
|
||||
ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 );
|
||||
ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 );
|
||||
ALLOC_STATE( lit[3], tcl_lit3, LIT_STATE_SIZE, "LIT/light-3", 1 );
|
||||
ALLOC_STATE( lit[4], tcl_lit4, LIT_STATE_SIZE, "LIT/light-4", 1 );
|
||||
ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 );
|
||||
ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 );
|
||||
ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 );
|
||||
|
||||
|
||||
/* Fill in the packet headers:
|
||||
*/
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC);
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL);
|
||||
rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH);
|
||||
rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN);
|
||||
rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH);
|
||||
rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK);
|
||||
rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE);
|
||||
rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL);
|
||||
rmesa->hw.set.cmd[SET_CMD_1] = cmdpkt(RADEON_EMIT_SE_CNTL_STATUS);
|
||||
rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC);
|
||||
rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_0);
|
||||
rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_0);
|
||||
rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_1);
|
||||
rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_1);
|
||||
rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR);
|
||||
rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT);
|
||||
rmesa->hw.mtl.cmd[MTL_CMD_0] =
|
||||
cmdpkt(RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED);
|
||||
rmesa->hw.grd.cmd[GRD_CMD_0] =
|
||||
cmdscl( RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 );
|
||||
rmesa->hw.fog.cmd[FOG_CMD_0] =
|
||||
cmdvec( RADEON_VS_FOG_PARAM_ADDR, 1, 4 );
|
||||
rmesa->hw.glt.cmd[GLT_CMD_0] =
|
||||
cmdvec( RADEON_VS_GLOBAL_AMBIENT_ADDR, 1, 4 );
|
||||
rmesa->hw.eye.cmd[EYE_CMD_0] =
|
||||
cmdvec( RADEON_VS_EYE_VECTOR_ADDR, 1, 4 );
|
||||
|
||||
for (i = 0 ; i < 5; i++) {
|
||||
rmesa->hw.mat[i].cmd[MAT_CMD_0] =
|
||||
cmdvec( RADEON_VS_MATRIX_0_ADDR + i*4, 1, 16);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 8; i++) {
|
||||
rmesa->hw.lit[i].cmd[LIT_CMD_0] =
|
||||
cmdvec( RADEON_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 );
|
||||
rmesa->hw.lit[i].cmd[LIT_CMD_1] =
|
||||
cmdscl( RADEON_SS_LIGHT_DCD_ADDR + i, 8, 6 );
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 6; i++) {
|
||||
rmesa->hw.ucp[i].cmd[UCP_CMD_0] =
|
||||
cmdvec( RADEON_VS_UCP_ADDR + i, 1, 4 );
|
||||
}
|
||||
|
||||
rmesa->last_ReallyEnabled = -1;
|
||||
|
||||
/* Initial Harware state:
|
||||
*/
|
||||
rmesa->hw.ctx.cmd[CTX_PP_MISC] = (RADEON_ALPHA_TEST_PASS |
|
||||
RADEON_CHROMA_FUNC_FAIL |
|
||||
RADEON_CHROMA_KEY_NEAREST |
|
||||
RADEON_SHADOW_FUNC_EQUAL |
|
||||
RADEON_SHADOW_PASS_1 |
|
||||
RADEON_RIGHT_HAND_CUBE_OGL);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (RADEON_FOG_VERTEX |
|
||||
RADEON_FOG_USE_DEPTH);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (RADEON_COMB_FCN_ADD_CLAMP |
|
||||
RADEON_SRC_BLEND_GL_ONE |
|
||||
RADEON_DST_BLEND_GL_ZERO );
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] =
|
||||
rmesa->radeonScreen->depthOffset;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] =
|
||||
((rmesa->radeonScreen->depthPitch &
|
||||
RADEON_DEPTHPITCH_MASK) |
|
||||
RADEON_DEPTH_ENDIAN_NO_SWAP);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt |
|
||||
RADEON_Z_TEST_LESS |
|
||||
RADEON_STENCIL_TEST_ALWAYS |
|
||||
RADEON_STENCIL_FAIL_KEEP |
|
||||
RADEON_STENCIL_ZPASS_KEEP |
|
||||
RADEON_STENCIL_ZFAIL_KEEP |
|
||||
RADEON_Z_WRITE_ENABLE);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (RADEON_SCISSOR_ENABLE |
|
||||
RADEON_ANTI_ALIAS_NONE);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = (RADEON_PLANE_MASK_ENABLE |
|
||||
color_fmt |
|
||||
(1<<15));
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset &
|
||||
RADEON_COLOROFFSET_MASK);
|
||||
|
||||
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
|
||||
RADEON_COLORPITCH_MASK) |
|
||||
RADEON_COLOR_ENDIAN_NO_SWAP);
|
||||
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW |
|
||||
RADEON_BFACE_SOLID |
|
||||
RADEON_FFACE_SOLID |
|
||||
/* RADEON_BADVTX_CULL_DISABLE | */
|
||||
RADEON_FLAT_SHADE_VTX_LAST |
|
||||
RADEON_DIFFUSE_SHADE_GOURAUD |
|
||||
RADEON_ALPHA_SHADE_GOURAUD |
|
||||
RADEON_SPECULAR_SHADE_GOURAUD |
|
||||
RADEON_FOG_SHADE_GOURAUD |
|
||||
RADEON_VPORT_XY_XFORM_ENABLE |
|
||||
RADEON_VPORT_Z_XFORM_ENABLE |
|
||||
RADEON_VTX_PIX_CENTER_OGL |
|
||||
RADEON_ROUND_MODE_TRUNC |
|
||||
RADEON_ROUND_PREC_8TH_PIX);
|
||||
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] =
|
||||
#ifdef MESA_BIG_ENDIAN
|
||||
RADEON_VC_32BIT_SWAP;
|
||||
#else
|
||||
RADEON_VC_NO_SWAP;
|
||||
#endif
|
||||
|
||||
if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] |= RADEON_TCL_BYPASS;
|
||||
}
|
||||
|
||||
rmesa->hw.set.cmd[SET_SE_COORDFMT] = (
|
||||
RADEON_VTX_W0_IS_NOT_1_OVER_W0 |
|
||||
RADEON_TEX1_W_ROUTING_USE_Q1);
|
||||
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
|
||||
((0x0000 & RADEON_LINE_PATTERN_MASK) |
|
||||
(0 << RADEON_LINE_REPEAT_COUNT_SHIFT) |
|
||||
(0 << RADEON_LINE_PATTERN_START_SHIFT) |
|
||||
RADEON_LINE_PATTERN_LITTLE_BIT_ORDER);
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] =
|
||||
((0 << RADEON_LINE_CURRENT_PTR_SHIFT) |
|
||||
(1 << RADEON_LINE_CURRENT_COUNT_SHIFT));
|
||||
|
||||
rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4);
|
||||
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] =
|
||||
((0x00 << RADEON_STENCIL_REF_SHIFT) |
|
||||
(0xff << RADEON_STENCIL_MASK_SHIFT) |
|
||||
(0xff << RADEON_STENCIL_WRITEMASK_SHIFT));
|
||||
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = RADEON_ROP_COPY;
|
||||
rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff;
|
||||
|
||||
rmesa->hw.msc.cmd[MSC_RE_MISC] =
|
||||
((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) |
|
||||
(0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) |
|
||||
RADEON_STIPPLE_BIG_BIT_ORDER);
|
||||
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000;
|
||||
rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000;
|
||||
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL;
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TXFORMAT] =
|
||||
(RADEON_TXFORMAT_ENDIAN_NO_SWAP |
|
||||
RADEON_TXFORMAT_PERSPECTIVE_ENABLE |
|
||||
RADEON_TXFORMAT_ST_ROUTE_STQ0 |
|
||||
(2 << RADEON_TXFORMAT_WIDTH_SHIFT) |
|
||||
(2 << RADEON_TXFORMAT_HEIGHT_SHIFT));
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TXOFFSET] = 0x2000;
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_BORDER_COLOR] = 0;
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TXCBLEND] =
|
||||
(RADEON_COLOR_ARG_A_ZERO |
|
||||
RADEON_COLOR_ARG_B_ZERO |
|
||||
RADEON_COLOR_ARG_C_CURRENT_COLOR |
|
||||
RADEON_BLEND_CTL_ADD |
|
||||
RADEON_SCALE_1X |
|
||||
RADEON_CLAMP_TX);
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TXABLEND] =
|
||||
(RADEON_ALPHA_ARG_A_ZERO |
|
||||
RADEON_ALPHA_ARG_B_ZERO |
|
||||
RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
|
||||
RADEON_BLEND_CTL_ADD |
|
||||
RADEON_SCALE_1X |
|
||||
RADEON_CLAMP_TX);
|
||||
rmesa->hw.tex[0].cmd[TEX_PP_TFACTOR] = 0;
|
||||
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL;
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] =
|
||||
(RADEON_TXFORMAT_ENDIAN_NO_SWAP |
|
||||
RADEON_TXFORMAT_PERSPECTIVE_ENABLE |
|
||||
RADEON_TXFORMAT_ST_ROUTE_STQ1 |
|
||||
(2 << RADEON_TXFORMAT_WIDTH_SHIFT) |
|
||||
(2 << RADEON_TXFORMAT_HEIGHT_SHIFT));
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TXOFFSET] = 0x8000;
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_BORDER_COLOR] = 0;
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TXCBLEND] =
|
||||
(RADEON_COLOR_ARG_A_ZERO |
|
||||
RADEON_COLOR_ARG_B_ZERO |
|
||||
RADEON_COLOR_ARG_C_CURRENT_COLOR |
|
||||
RADEON_BLEND_CTL_ADD |
|
||||
RADEON_SCALE_1X |
|
||||
RADEON_CLAMP_TX);
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TXABLEND] =
|
||||
(RADEON_ALPHA_ARG_A_ZERO |
|
||||
RADEON_ALPHA_ARG_B_ZERO |
|
||||
RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
|
||||
RADEON_BLEND_CTL_ADD |
|
||||
RADEON_SCALE_1X |
|
||||
RADEON_CLAMP_TX);
|
||||
rmesa->hw.tex[1].cmd[TEX_PP_TFACTOR] = 0;
|
||||
|
||||
/* Can oly add ST1 at the time of doing some multitex but can keep
|
||||
* it after that. Errors if DIFFUSE is missing.
|
||||
*/
|
||||
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] =
|
||||
(RADEON_TCL_VTX_Z0 |
|
||||
RADEON_TCL_VTX_W0 |
|
||||
RADEON_TCL_VTX_PK_DIFFUSE
|
||||
); /* need to keep this uptodate */
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] =
|
||||
( RADEON_TCL_COMPUTE_XYZW |
|
||||
(RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
|
||||
(RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
|
||||
(RADEON_TCL_TEX_INPUT_TEX_2 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
|
||||
|
||||
|
||||
/* XXX */
|
||||
rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_0] =
|
||||
((MODEL << RADEON_MODELVIEW_0_SHIFT) |
|
||||
(MODEL_IT << RADEON_IT_MODELVIEW_0_SHIFT));
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_1] =
|
||||
((MODEL_PROJ << RADEON_MODELPROJECT_0_SHIFT) |
|
||||
(TEXMAT_0 << RADEON_TEXMAT_0_SHIFT) |
|
||||
(TEXMAT_1 << RADEON_TEXMAT_1_SHIFT));
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] =
|
||||
(RADEON_UCP_IN_CLIP_SPACE |
|
||||
RADEON_CULL_FRONT_IS_CCW);
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = 0;
|
||||
|
||||
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] =
|
||||
(RADEON_SPECULAR_LIGHTS |
|
||||
RADEON_DIFFUSE_SPECULAR_COMBINE |
|
||||
RADEON_LOCAL_LIGHT_VEC_GL |
|
||||
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
|
||||
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_AMBIENT_SOURCE_SHIFT) |
|
||||
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
|
||||
(RADEON_LM_SOURCE_STATE_PREMULT << RADEON_SPECULAR_SOURCE_SHIFT));
|
||||
|
||||
for (i = 0 ; i < 8; i++) {
|
||||
struct gl_light *l = &ctx->Light.Light[i];
|
||||
GLenum p = GL_LIGHT0 + i;
|
||||
*(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX;
|
||||
|
||||
ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION,
|
||||
&l->ConstantAttenuation );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION,
|
||||
&l->LinearAttenuation );
|
||||
ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION,
|
||||
&l->QuadraticAttenuation );
|
||||
}
|
||||
|
||||
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT,
|
||||
ctx->Light.Model.Ambient );
|
||||
|
||||
TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
|
||||
|
||||
for (i = 0 ; i < 6; i++) {
|
||||
ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL );
|
||||
}
|
||||
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
|
||||
ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 );
|
||||
|
||||
|
||||
/* Set up vector and scalar state commands:
|
||||
*/
|
||||
/* upload_matrix( rmesa, ctx->ModelView.m, MODEL ); */
|
||||
/* upload_matrix_t( rmesa, ctx->ModelView.inv, MODEL_IT ); */
|
||||
/* upload_matrix( rmesa, ctx->TextureMatrix[0].m, TEXMAT_0 ); */
|
||||
/* upload_matrix( rmesa, ctx->TextureMatrix[1].m, TEXMAT_1 ); */
|
||||
/* upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, TEXMAT_2 ); */
|
||||
|
||||
rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE;
|
||||
rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE;
|
||||
|
||||
rmesa->hw.eye.cmd[EYE_X] = 0;
|
||||
rmesa->hw.eye.cmd[EYE_Y] = 0;
|
||||
rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE;
|
||||
rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE;
|
||||
}
|
||||
1191
src/mesa/drivers/dri/radeon/radeon_swtcl.c
Normal file
1191
src/mesa/drivers/dri/radeon/radeon_swtcl.c
Normal file
File diff suppressed because it is too large
Load diff
76
src/mesa/drivers/dri/radeon/radeon_swtcl.h
Normal file
76
src/mesa/drivers/dri/radeon/radeon_swtcl.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_TRIS_H__
|
||||
#define __RADEON_TRIS_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "radeon_context.h"
|
||||
|
||||
extern void radeonInitSwtcl( GLcontext *ctx );
|
||||
extern void radeonDestroySwtcl( GLcontext *ctx );
|
||||
|
||||
extern void radeonChooseRenderState( GLcontext *ctx );
|
||||
extern void radeonChooseVertexState( GLcontext *ctx );
|
||||
|
||||
extern void radeonCheckTexSizes( GLcontext *ctx );
|
||||
|
||||
extern void radeonBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
|
||||
GLuint newinputs );
|
||||
|
||||
extern void radeonPrintSetupFlags(char *msg, GLuint flags );
|
||||
|
||||
|
||||
extern void radeon_emit_contiguous_verts( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count );
|
||||
|
||||
extern void radeon_emit_indexed_verts( GLcontext *ctx,
|
||||
GLuint start,
|
||||
GLuint count );
|
||||
|
||||
extern void radeon_translate_vertex( GLcontext *ctx,
|
||||
const radeonVertex *src,
|
||||
SWvertex *dst );
|
||||
|
||||
extern void radeon_print_vertex( GLcontext *ctx, const radeonVertex *v );
|
||||
|
||||
extern void radeon_import_float_colors( GLcontext *ctx );
|
||||
extern void radeon_import_float_spec_colors( GLcontext *ctx );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
546
src/mesa/drivers/dri/radeon/radeon_tcl.c
Normal file
546
src/mesa/drivers/dri/radeon/radeon_tcl.c
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Austin, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "light.h"
|
||||
#include "mmath.h"
|
||||
#include "mtypes.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "array_cache/acache.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_tex.h"
|
||||
#include "radeon_tcl.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_maos.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Render unclipped vertex buffers by emitting vertices directly to
|
||||
* dma buffers. Use strip/fan hardware primitives where possible.
|
||||
* Try to simulate missing primitives with indexed vertices.
|
||||
*/
|
||||
#define HAVE_POINTS 1
|
||||
#define HAVE_LINES 1
|
||||
#define HAVE_LINE_LOOP 0
|
||||
#define HAVE_LINE_STRIPS 1
|
||||
#define HAVE_TRIANGLES 1
|
||||
#define HAVE_TRI_STRIPS 1
|
||||
#define HAVE_TRI_STRIP_1 0
|
||||
#define HAVE_TRI_FANS 1
|
||||
#define HAVE_QUADS 0
|
||||
#define HAVE_QUAD_STRIPS 0
|
||||
#define HAVE_POLYGONS 1
|
||||
#define HAVE_ELTS 1
|
||||
|
||||
|
||||
#define HW_POINTS RADEON_CP_VC_CNTL_PRIM_TYPE_POINT
|
||||
#define HW_LINES RADEON_CP_VC_CNTL_PRIM_TYPE_LINE
|
||||
#define HW_LINE_LOOP 0
|
||||
#define HW_LINE_STRIP RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP
|
||||
#define HW_TRIANGLES RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST
|
||||
#define HW_TRIANGLE_STRIP_0 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP
|
||||
#define HW_TRIANGLE_STRIP_1 0
|
||||
#define HW_TRIANGLE_FAN RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
||||
#define HW_QUADS 0
|
||||
#define HW_QUAD_STRIP 0
|
||||
#define HW_POLYGON RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
||||
|
||||
|
||||
static GLboolean discreet_prim[0x10] = {
|
||||
0, /* none */
|
||||
1, /* points */
|
||||
1, /* lines */
|
||||
0, /* line_strip */
|
||||
1, /* tri_list */
|
||||
0, /* tri_fan */
|
||||
0, /* tri_type_2 */
|
||||
1, /* rect list (unused) */
|
||||
1, /* 3 vert point */
|
||||
1, /* 3 vert line */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
#define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
|
||||
#define ELTS_VARS GLushort *dest
|
||||
|
||||
#define ELT_INIT(prim, hw_prim) \
|
||||
radeonTclPrimitive( ctx, prim, hw_prim | RADEON_CP_VC_CNTL_PRIM_WALK_IND )
|
||||
|
||||
#define GET_ELTS() rmesa->tcl.Elts
|
||||
|
||||
|
||||
#define NEW_PRIMITIVE() RADEON_NEWPRIM( rmesa )
|
||||
#define NEW_BUFFER() radeonRefillCurrentDmaRegion( rmesa )
|
||||
|
||||
/* Don't really know how many elts will fit in what's left of cmdbuf,
|
||||
* as there is state to emit, etc:
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define GET_CURRENT_VB_MAX_ELTS() \
|
||||
((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
|
||||
#define GET_SUBSEQUENT_VB_MAX_ELTS() ((RADEON_CMD_BUF_SZ - 16) / 2)
|
||||
#else
|
||||
/* Testing on isosurf shows a maximum around here. Don't know if it's
|
||||
* the card or driver or kernel module that is causing the behaviour.
|
||||
*/
|
||||
#define GET_CURRENT_VB_MAX_ELTS() 300
|
||||
#define GET_SUBSEQUENT_VB_MAX_ELTS() 300
|
||||
#endif
|
||||
|
||||
#define RESET_STIPPLE() do { \
|
||||
RADEON_STATECHANGE( rmesa, lin ); \
|
||||
radeonEmitState( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
#define AUTO_STIPPLE( mode ) do { \
|
||||
RADEON_STATECHANGE( rmesa, lin ); \
|
||||
if (mode) \
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \
|
||||
RADEON_LINE_PATTERN_AUTO_RESET; \
|
||||
else \
|
||||
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \
|
||||
~RADEON_LINE_PATTERN_AUTO_RESET; \
|
||||
radeonEmitState( rmesa ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* How do you extend an existing primitive?
|
||||
*/
|
||||
#define ALLOC_ELTS(nr) \
|
||||
do { \
|
||||
if (rmesa->dma.flush == radeonFlushElts && \
|
||||
rmesa->store.cmd_used + nr*2 < RADEON_CMD_BUF_SZ) { \
|
||||
\
|
||||
dest = (GLushort *)(rmesa->store.cmd_buf + \
|
||||
rmesa->store.cmd_used); \
|
||||
rmesa->store.cmd_used += nr*2; \
|
||||
} \
|
||||
else { \
|
||||
if (rmesa->dma.flush) \
|
||||
rmesa->dma.flush( rmesa ); \
|
||||
\
|
||||
radeonEmitAOS( rmesa, \
|
||||
rmesa->tcl.aos_components, \
|
||||
rmesa->tcl.nr_aos_components, \
|
||||
0 ); \
|
||||
\
|
||||
dest = radeonAllocEltsOpenEnded( rmesa, \
|
||||
rmesa->tcl.vertex_format, \
|
||||
rmesa->tcl.hw_primitive, \
|
||||
nr ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/* TODO: Try to extend existing primitive if both are identical,
|
||||
* discreet and there are no intervening state changes. (Somewhat
|
||||
* duplicates changes to DrawArrays code)
|
||||
*/
|
||||
static void EMIT_PRIM( GLcontext *ctx,
|
||||
GLenum prim,
|
||||
GLuint hwprim,
|
||||
GLuint start,
|
||||
GLuint count)
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
|
||||
radeonTclPrimitive( ctx, prim, hwprim );
|
||||
|
||||
radeonEmitAOS( rmesa,
|
||||
rmesa->tcl.aos_components,
|
||||
rmesa->tcl.nr_aos_components,
|
||||
start );
|
||||
|
||||
/* Why couldn't this packet have taken an offset param?
|
||||
*/
|
||||
radeonEmitVbufPrim( rmesa,
|
||||
rmesa->tcl.vertex_format,
|
||||
rmesa->tcl.hw_primitive,
|
||||
count - start );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Try & join small primitives
|
||||
*/
|
||||
#if 0
|
||||
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0
|
||||
#else
|
||||
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) \
|
||||
((NR) < 20 || \
|
||||
((NR) < 40 && \
|
||||
rmesa->tcl.hw_primitive == (PRIM| \
|
||||
RADEON_CP_VC_CNTL_PRIM_WALK_IND| \
|
||||
RADEON_CP_VC_CNTL_TCL_ENABLE)))
|
||||
#endif
|
||||
|
||||
#ifdef MESA_BIG_ENDIAN
|
||||
/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
|
||||
#define EMIT_ELT(offset, x) do { \
|
||||
int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
|
||||
GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
|
||||
(des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
|
||||
#else
|
||||
#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
|
||||
#endif
|
||||
#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
|
||||
#define INCR_ELTS( nr ) dest += nr
|
||||
#define RELEASE_ELT_VERTS() \
|
||||
radeonReleaseArrays( ctx, ~0 )
|
||||
|
||||
|
||||
|
||||
#define TAG(x) tcl_##x
|
||||
#include "tnl_dd/t_dd_dmatmp2.h"
|
||||
|
||||
/**********************************************************************/
|
||||
/* External entrypoints */
|
||||
/**********************************************************************/
|
||||
|
||||
void radeonEmitPrimitive( GLcontext *ctx,
|
||||
GLuint first,
|
||||
GLuint last,
|
||||
GLuint flags )
|
||||
{
|
||||
tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
|
||||
}
|
||||
|
||||
void radeonEmitEltPrimitive( GLcontext *ctx,
|
||||
GLuint first,
|
||||
GLuint last,
|
||||
GLuint flags )
|
||||
{
|
||||
tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
|
||||
}
|
||||
|
||||
void radeonTclPrimitive( GLcontext *ctx,
|
||||
GLenum prim,
|
||||
int hw_prim )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
GLuint se_cntl;
|
||||
GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE;
|
||||
|
||||
if (newprim != rmesa->tcl.hw_primitive ||
|
||||
!discreet_prim[hw_prim&0xf]) {
|
||||
RADEON_NEWPRIM( rmesa );
|
||||
rmesa->tcl.hw_primitive = newprim;
|
||||
}
|
||||
|
||||
se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL];
|
||||
se_cntl &= ~RADEON_FLAT_SHADE_VTX_LAST;
|
||||
|
||||
if (prim == GL_POLYGON && (ctx->_TriangleCaps & DD_FLATSHADE))
|
||||
se_cntl |= RADEON_FLAT_SHADE_VTX_0;
|
||||
else
|
||||
se_cntl |= RADEON_FLAT_SHADE_VTX_LAST;
|
||||
|
||||
if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) {
|
||||
RADEON_STATECHANGE( rmesa, set );
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Render pipeline stage */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/* TCL render.
|
||||
*/
|
||||
static GLboolean radeon_run_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint i,flags = 0,length;
|
||||
|
||||
/* TODO: separate this from the swtnl pipeline
|
||||
*/
|
||||
if (rmesa->TclFallback)
|
||||
return GL_TRUE; /* fallback to software t&l */
|
||||
|
||||
if (VB->Count == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
radeonReleaseArrays( ctx, stage->changed_inputs );
|
||||
radeonEmitArrays( ctx, stage->inputs );
|
||||
|
||||
rmesa->tcl.Elts = VB->Elts;
|
||||
|
||||
for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
|
||||
{
|
||||
flags = VB->Primitive[i];
|
||||
length = VB->PrimitiveLength[i];
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_PRIMS)
|
||||
fprintf(stderr, "%s: prim %s %d..%d\n",
|
||||
__FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK),
|
||||
i, i+length);
|
||||
|
||||
if (!length)
|
||||
continue;
|
||||
|
||||
if (rmesa->tcl.Elts)
|
||||
radeonEmitEltPrimitive( ctx, i, i+length, flags );
|
||||
else
|
||||
radeonEmitPrimitive( ctx, i, i+length, flags );
|
||||
}
|
||||
|
||||
return GL_FALSE; /* finished the pipe */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void radeon_check_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
GLuint inputs = VERT_BIT_POS;
|
||||
|
||||
if (ctx->RenderMode == GL_RENDER) {
|
||||
/* Make all this event-driven:
|
||||
*/
|
||||
if (ctx->Light.Enabled) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
|
||||
if (ctx->Light.ColorMaterialEnabled) {
|
||||
inputs |= VERT_BIT_COLOR0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
inputs |= VERT_BIT_COLOR0;
|
||||
|
||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
|
||||
inputs |= VERT_BIT_COLOR1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[0]._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[0].TexGenEnabled) {
|
||||
if (rmesa->TexGenNeedNormals[0]) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
inputs |= VERT_BIT_TEX0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Texture.Unit[1]._ReallyEnabled) {
|
||||
if (ctx->Texture.Unit[1].TexGenEnabled) {
|
||||
if (rmesa->TexGenNeedNormals[1]) {
|
||||
inputs |= VERT_BIT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
inputs |= VERT_BIT_TEX1;
|
||||
}
|
||||
}
|
||||
|
||||
stage->inputs = inputs;
|
||||
stage->active = 1;
|
||||
}
|
||||
else
|
||||
stage->active = 0;
|
||||
}
|
||||
|
||||
static void radeon_init_tcl_render( GLcontext *ctx,
|
||||
struct gl_pipeline_stage *stage )
|
||||
{
|
||||
stage->check = radeon_check_tcl_render;
|
||||
stage->check( ctx, stage );
|
||||
}
|
||||
|
||||
static void dtr( struct gl_pipeline_stage *stage )
|
||||
{
|
||||
(void)stage;
|
||||
}
|
||||
|
||||
|
||||
/* Initial state for tcl stage.
|
||||
*/
|
||||
const struct gl_pipeline_stage _radeon_tcl_stage =
|
||||
{
|
||||
"radeon render",
|
||||
(_DD_NEW_SEPARATE_SPECULAR |
|
||||
_NEW_LIGHT|
|
||||
_NEW_TEXTURE|
|
||||
_NEW_FOG|
|
||||
_NEW_RENDERMODE), /* re-check (new inputs) */
|
||||
0, /* re-run (always runs) */
|
||||
GL_TRUE, /* active */
|
||||
0, 0, /* inputs (set in check_render), outputs */
|
||||
0, 0, /* changed_inputs, private */
|
||||
dtr, /* destructor */
|
||||
radeon_init_tcl_render, /* check - initially set to alloc data */
|
||||
radeon_run_tcl_render /* run */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Validate state at pipeline start */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Manage TCL fallbacks
|
||||
*/
|
||||
|
||||
|
||||
static void transition_to_swtnl( GLcontext *ctx )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
GLuint se_cntl;
|
||||
|
||||
RADEON_NEWPRIM( rmesa );
|
||||
rmesa->swtcl.vertex_format = 0;
|
||||
|
||||
radeonChooseVertexState( ctx );
|
||||
radeonChooseRenderState( ctx );
|
||||
|
||||
_mesa_validate_all_lighting_tables( ctx );
|
||||
|
||||
tnl->Driver.NotifyMaterialChange =
|
||||
_mesa_validate_all_lighting_tables;
|
||||
|
||||
radeonReleaseArrays( ctx, ~0 );
|
||||
|
||||
se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL];
|
||||
se_cntl |= RADEON_FLAT_SHADE_VTX_LAST;
|
||||
|
||||
if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) {
|
||||
RADEON_STATECHANGE( rmesa, set );
|
||||
rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void transition_to_hwtnl( GLcontext *ctx )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
GLuint se_coord_fmt = (RADEON_VTX_W0_IS_NOT_1_OVER_W0 |
|
||||
RADEON_TEX1_W_ROUTING_USE_Q1);
|
||||
|
||||
if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) {
|
||||
RADEON_STATECHANGE( rmesa, set );
|
||||
rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
|
||||
_tnl_need_projected_coords( ctx, GL_FALSE );
|
||||
}
|
||||
|
||||
radeonUpdateMaterial( ctx );
|
||||
|
||||
tnl->Driver.NotifyMaterialChange = radeonUpdateMaterial;
|
||||
|
||||
if ( rmesa->dma.flush )
|
||||
rmesa->dma.flush( rmesa );
|
||||
|
||||
rmesa->dma.flush = 0;
|
||||
rmesa->swtcl.vertex_format = 0;
|
||||
|
||||
if (rmesa->swtcl.indexed_verts.buf)
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
|
||||
__FUNCTION__ );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "Radeon end tcl fallback\n");
|
||||
}
|
||||
|
||||
static char *fallbackStrings[] = {
|
||||
"Rasterization fallback",
|
||||
"Unfilled triangles",
|
||||
"Twosided lighting, differing materials",
|
||||
"Materials in VB (maybe between begin/end)",
|
||||
"Texgen unit 0",
|
||||
"Texgen unit 1",
|
||||
"Texgen unit 2",
|
||||
"User disable"
|
||||
};
|
||||
|
||||
|
||||
static char *getFallbackString(GLuint bit)
|
||||
{
|
||||
int i = 0;
|
||||
while (bit > 1) {
|
||||
i++;
|
||||
bit >>= 1;
|
||||
}
|
||||
return fallbackStrings[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
GLuint oldfallback = rmesa->TclFallback;
|
||||
|
||||
if (mode) {
|
||||
rmesa->TclFallback |= bit;
|
||||
if (oldfallback == 0) {
|
||||
if (RADEON_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "Radeon begin tcl fallback %s\n",
|
||||
getFallbackString( bit ));
|
||||
transition_to_swtnl( ctx );
|
||||
}
|
||||
}
|
||||
else {
|
||||
rmesa->TclFallback &= ~bit;
|
||||
if (oldfallback == bit) {
|
||||
if (RADEON_DEBUG & DEBUG_FALLBACKS)
|
||||
fprintf(stderr, "Radeon end tcl fallback %s\n",
|
||||
getFallbackString( bit ));
|
||||
transition_to_hwtnl( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/mesa/drivers/dri/radeon/radeon_tcl.h
Normal file
66
src/mesa/drivers/dri/radeon/radeon_tcl.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Grahpics Inc., Austin, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAHPICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_TCL_H__
|
||||
#define __RADEON_TCL_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "radeon_context.h"
|
||||
|
||||
extern void radeonTclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim );
|
||||
extern void radeonEmitEltPrimitive( GLcontext *ctx, GLuint first, GLuint last,
|
||||
GLuint flags );
|
||||
extern void radeonEmitPrimitive( GLcontext *ctx, GLuint first, GLuint last,
|
||||
GLuint flags );
|
||||
|
||||
extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
|
||||
#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */
|
||||
#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */
|
||||
#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */
|
||||
#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */
|
||||
#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */
|
||||
#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */
|
||||
|
||||
#define RADEON_MAX_TCL_VERTSIZE (4*4) /* using maos now... */
|
||||
|
||||
#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode )
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
691
src/mesa/drivers/dri/radeon/radeon_tex.c
Normal file
691
src/mesa/drivers/dri/radeon/radeon_tex.c
Normal file
|
|
@ -0,0 +1,691 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.6 2002/09/16 18:05:20 eich Exp $ */
|
||||
/*
|
||||
* Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Brian Paul <brianp@valinux.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "colormac.h"
|
||||
#include "context.h"
|
||||
#include "enums.h"
|
||||
#include "image.h"
|
||||
#include "simple_list.h"
|
||||
#include "texformat.h"
|
||||
#include "texstore.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_state.h"
|
||||
#include "radeon_ioctl.h"
|
||||
#include "radeon_swtcl.h"
|
||||
#include "radeon_tex.h"
|
||||
|
||||
|
||||
|
||||
/* =============================================================
|
||||
* Utility functions:
|
||||
*/
|
||||
|
||||
static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap )
|
||||
{
|
||||
t->pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK);
|
||||
|
||||
switch ( swrap ) {
|
||||
case GL_REPEAT:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_WRAP;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_MIRROR;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_ATI:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_MIRROR_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE_ATI:
|
||||
t->pp_txfilter |= RADEON_CLAMP_S_MIRROR_CLAMP_LAST;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( twrap ) {
|
||||
case GL_REPEAT:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_WRAP;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
|
||||
break;
|
||||
case GL_CLAMP_TO_BORDER:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_MIRROR;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_ATI:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_MIRROR_CLAMP_BORDER;
|
||||
break;
|
||||
case GL_MIRROR_CLAMP_TO_EDGE_ATI:
|
||||
t->pp_txfilter |= RADEON_CLAMP_T_MIRROR_CLAMP_LAST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonSetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max )
|
||||
{
|
||||
t->pp_txfilter &= ~RADEON_MAX_ANISO_MASK;
|
||||
|
||||
if ( max == 1.0 ) {
|
||||
t->pp_txfilter |= RADEON_MAX_ANISO_1_TO_1;
|
||||
} else if ( max <= 2.0 ) {
|
||||
t->pp_txfilter |= RADEON_MAX_ANISO_2_TO_1;
|
||||
} else if ( max <= 4.0 ) {
|
||||
t->pp_txfilter |= RADEON_MAX_ANISO_4_TO_1;
|
||||
} else if ( max <= 8.0 ) {
|
||||
t->pp_txfilter |= RADEON_MAX_ANISO_8_TO_1;
|
||||
} else {
|
||||
t->pp_txfilter |= RADEON_MAX_ANISO_16_TO_1;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
|
||||
{
|
||||
GLuint anisotropy = (t->pp_txfilter & RADEON_MAX_ANISO_MASK);
|
||||
|
||||
t->pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK);
|
||||
|
||||
if ( anisotropy == RADEON_MAX_ANISO_1_TO_1 ) {
|
||||
switch ( minf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ( minf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_ANISO_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_ANISO_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( magf ) {
|
||||
case GL_NEAREST:
|
||||
t->pp_txfilter |= RADEON_MAG_FILTER_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
t->pp_txfilter |= RADEON_MAG_FILTER_LINEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] )
|
||||
{
|
||||
t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
|
||||
}
|
||||
|
||||
|
||||
static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *texObj )
|
||||
{
|
||||
radeonTexObjPtr t;
|
||||
|
||||
t = CALLOC_STRUCT( radeon_tex_obj );
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t );
|
||||
}
|
||||
|
||||
t->tObj = texObj;
|
||||
make_empty_list( t );
|
||||
|
||||
/* Initialize non-image-dependent parts of the state:
|
||||
*/
|
||||
radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT );
|
||||
radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
|
||||
radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
|
||||
radeonSetTexBorderColor( t, texObj->_BorderChan );
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static const struct gl_texture_format *
|
||||
radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
|
||||
GLenum format, GLenum type )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
const GLboolean do32bpt = ( rmesa->radeonScreen->cpp == 4 );
|
||||
|
||||
switch ( internalFormat ) {
|
||||
case 4:
|
||||
case GL_RGBA:
|
||||
case GL_COMPRESSED_RGBA:
|
||||
if ( format == GL_BGRA ) {
|
||||
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
||||
return &_mesa_texformat_argb8888;
|
||||
}
|
||||
else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
|
||||
return &_mesa_texformat_argb4444;
|
||||
}
|
||||
else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
|
||||
return &_mesa_texformat_argb1555;
|
||||
}
|
||||
}
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444;
|
||||
|
||||
case 3:
|
||||
case GL_RGB:
|
||||
case GL_COMPRESSED_RGB:
|
||||
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
|
||||
return &_mesa_texformat_rgb565;
|
||||
}
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_RGBA8:
|
||||
case GL_RGB10_A2:
|
||||
case GL_RGBA12:
|
||||
case GL_RGBA16:
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444;
|
||||
|
||||
case GL_RGBA4:
|
||||
case GL_RGBA2:
|
||||
return &_mesa_texformat_argb4444;
|
||||
|
||||
case GL_RGB5_A1:
|
||||
return &_mesa_texformat_argb1555;
|
||||
|
||||
case GL_RGB8:
|
||||
case GL_RGB10:
|
||||
case GL_RGB12:
|
||||
case GL_RGB16:
|
||||
return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_RGB5:
|
||||
case GL_RGB4:
|
||||
case GL_R3_G3_B2:
|
||||
return &_mesa_texformat_rgb565;
|
||||
|
||||
case GL_ALPHA:
|
||||
case GL_ALPHA4:
|
||||
case GL_ALPHA8:
|
||||
case GL_ALPHA12:
|
||||
case GL_ALPHA16:
|
||||
case GL_COMPRESSED_ALPHA:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case 1:
|
||||
case GL_LUMINANCE:
|
||||
case GL_LUMINANCE4:
|
||||
case GL_LUMINANCE8:
|
||||
case GL_LUMINANCE12:
|
||||
case GL_LUMINANCE16:
|
||||
case GL_COMPRESSED_LUMINANCE:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case 2:
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
case GL_LUMINANCE4_ALPHA4:
|
||||
case GL_LUMINANCE6_ALPHA2:
|
||||
case GL_LUMINANCE8_ALPHA8:
|
||||
case GL_LUMINANCE12_ALPHA4:
|
||||
case GL_LUMINANCE12_ALPHA12:
|
||||
case GL_LUMINANCE16_ALPHA16:
|
||||
case GL_COMPRESSED_LUMINANCE_ALPHA:
|
||||
return &_mesa_texformat_al88;
|
||||
|
||||
case GL_INTENSITY:
|
||||
case GL_INTENSITY4:
|
||||
case GL_INTENSITY8:
|
||||
case GL_INTENSITY12:
|
||||
case GL_INTENSITY16:
|
||||
case GL_COMPRESSED_INTENSITY:
|
||||
return &_mesa_texformat_i8;
|
||||
|
||||
default:
|
||||
_mesa_problem(ctx, "unexpected texture format in radeonChoosTexFormat");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL; /* never get here */
|
||||
}
|
||||
|
||||
|
||||
static void radeonTexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( t ) {
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = radeonAllocTexObj( texObj );
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
/* Note, this will call radeonChooseTextureFormat */
|
||||
_mesa_store_teximage1d(ctx, target, level, internalFormat,
|
||||
width, border, format, type, pixels,
|
||||
&ctx->Unpack, texObj, texImage);
|
||||
|
||||
t->dirty_images |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void radeonTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint xoffset,
|
||||
GLsizei width,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
|
||||
|
||||
assert( t ); /* this _should_ be true */
|
||||
if ( t ) {
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
t->dirty_images |= (1 << level);
|
||||
}
|
||||
else {
|
||||
t = radeonAllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
|
||||
format, type, pixels, packing, texObj,
|
||||
texImage);
|
||||
|
||||
t->dirty_images |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLint width, GLint height, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData;
|
||||
|
||||
/* fprintf(stderr, "%s\n", __FUNCTION__); */
|
||||
|
||||
if ( t ) {
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = radeonAllocTexObj( texObj );
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
/* Note, this will call radeonChooseTextureFormat */
|
||||
_mesa_store_teximage2d(ctx, target, level, internalFormat,
|
||||
width, height, border, format, type, pixels,
|
||||
&ctx->Unpack, texObj, texImage);
|
||||
|
||||
t->dirty_images |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels,
|
||||
const struct gl_pixelstore_attrib *packing,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
|
||||
/* fprintf(stderr, "%s\n", __FUNCTION__); */
|
||||
|
||||
assert( t ); /* this _should_ be true */
|
||||
if ( t ) {
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
}
|
||||
else {
|
||||
t = radeonAllocTexObj(texObj);
|
||||
if (!t) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
|
||||
return;
|
||||
}
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
|
||||
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
|
||||
height, format, type, pixels, packing, texObj,
|
||||
texImage);
|
||||
|
||||
t->dirty_images |= (1 << level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SCALED_FLOAT_TO_BYTE( x, scale ) \
|
||||
(((GLuint)((255.0F / scale) * (x))) / 2)
|
||||
|
||||
static void radeonTexEnv( GLcontext *ctx, GLenum target,
|
||||
GLenum pname, const GLfloat *param )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_STATE ) {
|
||||
fprintf( stderr, "%s( %s )\n",
|
||||
__FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
|
||||
}
|
||||
|
||||
switch ( pname ) {
|
||||
case GL_TEXTURE_ENV_COLOR: {
|
||||
GLubyte c[4];
|
||||
GLuint envColor;
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
|
||||
envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
|
||||
if ( rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] != envColor ) {
|
||||
RADEON_STATECHANGE( rmesa, tex[unit] );
|
||||
rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] = envColor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GL_TEXTURE_LOD_BIAS_EXT: {
|
||||
GLfloat bias;
|
||||
GLuint b;
|
||||
|
||||
/* The Radeon's LOD bias is a signed 2's complement value with a
|
||||
* range of -1.0 <= bias < 4.0. We break this into two linear
|
||||
* functions, one mapping [-1.0,0.0] to [-128,0] and one mapping
|
||||
* [0.0,4.0] to [0,127].
|
||||
*/
|
||||
bias = CLAMP( *param, -1.0, 4.0 );
|
||||
if ( bias == 0 ) {
|
||||
b = 0;
|
||||
} else if ( bias > 0 ) {
|
||||
b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 4.0 )) << RADEON_LOD_BIAS_SHIFT;
|
||||
} else {
|
||||
b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 1.0 )) << RADEON_LOD_BIAS_SHIFT;
|
||||
}
|
||||
if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] & RADEON_LOD_BIAS_MASK) != b ) {
|
||||
RADEON_STATECHANGE( rmesa, tex[unit] );
|
||||
rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] &= ~RADEON_LOD_BIAS_MASK;
|
||||
rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] |= (b & RADEON_LOD_BIAS_MASK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonTexParameter( GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum pname, const GLfloat *params )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %s )\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr( pname ) );
|
||||
}
|
||||
|
||||
if ( ( target != GL_TEXTURE_2D ) &&
|
||||
( target != GL_TEXTURE_1D ) )
|
||||
return;
|
||||
|
||||
switch ( pname ) {
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||
radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
|
||||
radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
case GL_TEXTURE_WRAP_T:
|
||||
radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
radeonSetTexBorderColor( t, texObj->_BorderChan );
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_BASE_LEVEL:
|
||||
case GL_TEXTURE_MAX_LEVEL:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
/* This isn't the most efficient solution but there doesn't appear to
|
||||
* be a nice alternative for Radeon. Since there's no LOD clamping,
|
||||
* we just have to rely on loading the right subset of mipmap levels
|
||||
* to simulate a clamped LOD.
|
||||
*/
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark this texobj as dirty (one bit per tex unit)
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void radeonBindTexture( GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit );
|
||||
}
|
||||
|
||||
if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) {
|
||||
if ( !t ) {
|
||||
t = radeonAllocTexObj( texObj );
|
||||
texObj->DriverData = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void radeonDeleteTexture( GLcontext *ctx,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
|
||||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj );
|
||||
}
|
||||
|
||||
if ( t ) {
|
||||
if ( rmesa ) {
|
||||
RADEON_FIREVERTICES( rmesa );
|
||||
}
|
||||
radeonDestroyTexObj( rmesa, t );
|
||||
texObj->DriverData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean radeonIsTextureResident( GLcontext *ctx,
|
||||
struct gl_texture_object *texObj )
|
||||
{
|
||||
radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
|
||||
|
||||
return ( t && t->memBlock );
|
||||
}
|
||||
|
||||
|
||||
static void radeonInitTextureObjects( GLcontext *ctx )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
struct gl_texture_object *texObj;
|
||||
GLuint tmp = ctx->Texture.CurrentUnit;
|
||||
|
||||
ctx->Texture.CurrentUnit = 0;
|
||||
|
||||
texObj = ctx->Texture.Unit[0].Current1D;
|
||||
radeonBindTexture( ctx, GL_TEXTURE_1D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(radeonTexObjPtr)texObj->DriverData );
|
||||
|
||||
texObj = ctx->Texture.Unit[0].Current2D;
|
||||
radeonBindTexture( ctx, GL_TEXTURE_2D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(radeonTexObjPtr)texObj->DriverData );
|
||||
|
||||
ctx->Texture.CurrentUnit = 1;
|
||||
|
||||
texObj = ctx->Texture.Unit[1].Current1D;
|
||||
radeonBindTexture( ctx, GL_TEXTURE_1D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(radeonTexObjPtr)texObj->DriverData );
|
||||
|
||||
texObj = ctx->Texture.Unit[1].Current2D;
|
||||
radeonBindTexture( ctx, GL_TEXTURE_2D, texObj );
|
||||
move_to_tail( &rmesa->texture.swapped,
|
||||
(radeonTexObjPtr)texObj->DriverData );
|
||||
|
||||
ctx->Texture.CurrentUnit = tmp;
|
||||
}
|
||||
|
||||
/* Need:
|
||||
* - Same GEN_MODE for all active bits
|
||||
* - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
|
||||
* - STRQ presumably all supported (matrix means incoming R values
|
||||
* can end up in STQ, this has implications for vertex support,
|
||||
* presumably ok if maos is used, though?)
|
||||
*
|
||||
* Basically impossible to do this on the fly - just collect some
|
||||
* basic info & do the checks from ValidateState().
|
||||
*/
|
||||
static void radeonTexGen( GLcontext *ctx,
|
||||
GLenum coord,
|
||||
GLenum pname,
|
||||
const GLfloat *params )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
GLuint unit = ctx->Texture.CurrentUnit;
|
||||
rmesa->recheck_texgen[unit] = GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void radeonInitTextureFuncs( GLcontext *ctx )
|
||||
{
|
||||
ctx->Driver.ChooseTextureFormat = radeonChooseTextureFormat;
|
||||
ctx->Driver.TexImage1D = radeonTexImage1D;
|
||||
ctx->Driver.TexImage2D = radeonTexImage2D;
|
||||
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
|
||||
ctx->Driver.TexSubImage1D = radeonTexSubImage1D;
|
||||
ctx->Driver.TexSubImage2D = radeonTexSubImage2D;
|
||||
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
|
||||
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
|
||||
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
|
||||
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
|
||||
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
|
||||
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
|
||||
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
|
||||
|
||||
ctx->Driver.BindTexture = radeonBindTexture;
|
||||
ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */
|
||||
ctx->Driver.DeleteTexture = radeonDeleteTexture;
|
||||
ctx->Driver.IsTextureResident = radeonIsTextureResident;
|
||||
ctx->Driver.PrioritizeTexture = NULL;
|
||||
ctx->Driver.ActiveTexture = NULL;
|
||||
ctx->Driver.UpdateTexturePalette = NULL;
|
||||
|
||||
ctx->Driver.TexEnv = radeonTexEnv;
|
||||
ctx->Driver.TexParameter = radeonTexParameter;
|
||||
ctx->Driver.TexGen = radeonTexGen;
|
||||
|
||||
radeonInitTextureObjects( ctx );
|
||||
}
|
||||
57
src/mesa/drivers/dri/radeon/radeon_tex.h
Normal file
57
src/mesa/drivers/dri/radeon/radeon_tex.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h,v 1.3 2002/02/22 21:45:01 dawes Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_TEX_H__
|
||||
#define __RADEON_TEX_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
extern void radeonUpdateTextureState( GLcontext *ctx );
|
||||
|
||||
extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t );
|
||||
|
||||
extern void radeonAgeTextures( radeonContextPtr rmesa, int heap );
|
||||
extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
|
||||
extern void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
|
||||
|
||||
extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap );
|
||||
extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap );
|
||||
extern void radeonUpdateTexLRU( radeonContextPtr rmesa, radeonTexObjPtr t );
|
||||
|
||||
extern void radeonInitTextureFuncs( GLcontext *ctx );
|
||||
|
||||
#endif
|
||||
#endif /* __RADEON_TEX_H__ */
|
||||
550
src/mesa/drivers/dri/radeon/radeon_texmem.c
Normal file
550
src/mesa/drivers/dri/radeon/radeon_texmem.c
Normal file
|
|
@ -0,0 +1,550 @@
|
|||
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c,v 1.4 2002/09/16 18:05:20 eich Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
VA Linux Systems Inc., Fremont, California.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
#include "mmath.h"
|
||||
#include "macros.h"
|
||||
#include "simple_list.h"
|
||||
|
||||
#include "radeon_context.h"
|
||||
#include "radeon_tex.h"
|
||||
#include <errno.h>
|
||||
|
||||
/* Destroy hardware state associated with texture `t'.
|
||||
*/
|
||||
void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
|
||||
{
|
||||
if ( !t )
|
||||
return;
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
|
||||
}
|
||||
|
||||
if ( t->memBlock ) {
|
||||
mmFreeMem( t->memBlock );
|
||||
t->memBlock = NULL;
|
||||
}
|
||||
|
||||
if ( t->tObj )
|
||||
t->tObj->DriverData = NULL;
|
||||
|
||||
if ( rmesa ) {
|
||||
/* Bump the performace counter */
|
||||
rmesa->c_textureSwaps++;
|
||||
|
||||
if ( t == rmesa->state.texture.unit[0].texobj ) {
|
||||
rmesa->state.texture.unit[0].texobj = NULL;
|
||||
remove_from_list( &rmesa->hw.tex[0] );
|
||||
make_empty_list( &rmesa->hw.tex[0] );
|
||||
}
|
||||
|
||||
if ( t == rmesa->state.texture.unit[1].texobj ) {
|
||||
rmesa->state.texture.unit[1].texobj = NULL;
|
||||
remove_from_list( &rmesa->hw.tex[1] );
|
||||
make_empty_list( &rmesa->hw.tex[1] );
|
||||
}
|
||||
}
|
||||
|
||||
remove_from_list( t );
|
||||
FREE( t );
|
||||
}
|
||||
|
||||
|
||||
/* Keep track of swapped out texture objects.
|
||||
*/
|
||||
void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
|
||||
{
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
|
||||
}
|
||||
|
||||
/* Bump the performace counter */
|
||||
rmesa->c_textureSwaps++;
|
||||
|
||||
if ( t->memBlock ) {
|
||||
mmFreeMem( t->memBlock );
|
||||
t->memBlock = NULL;
|
||||
}
|
||||
|
||||
t->dirty_images = ~0;
|
||||
move_to_tail( &rmesa->texture.swapped, t );
|
||||
}
|
||||
|
||||
/* Print out debugging information about texture LRU.
|
||||
*/
|
||||
void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap )
|
||||
{
|
||||
radeonTexObjPtr t;
|
||||
int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]);
|
||||
|
||||
fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
|
||||
|
||||
foreach ( t, &rmesa->texture.objects[heap] ) {
|
||||
if (!t->tObj) {
|
||||
fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
|
||||
t->memBlock->ofs / sz,
|
||||
t->memBlock->ofs,
|
||||
t->memBlock->size );
|
||||
} else {
|
||||
fprintf( stderr, "Texture at 0x%x sz 0x%x\n",
|
||||
t->memBlock->ofs,
|
||||
t->memBlock->size );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap )
|
||||
{
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int i, j;
|
||||
|
||||
fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
|
||||
|
||||
for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
|
||||
fprintf( stderr, "list[%d] age %d next %d prev %d\n",
|
||||
j, list[j].age, list[j].next, list[j].prev );
|
||||
j = list[j].next;
|
||||
if ( j == RADEON_NR_TEX_REGIONS ) break;
|
||||
}
|
||||
|
||||
if ( j != RADEON_NR_TEX_REGIONS ) {
|
||||
fprintf( stderr, "Loop detected in global LRU\n" );
|
||||
for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
|
||||
fprintf( stderr, "list[%d] age %d next %d prev %d\n",
|
||||
i, list[i].age, list[i].next, list[i].prev );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
/* Reset the global texture LRU.
|
||||
*/
|
||||
static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap )
|
||||
{
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* (Re)initialize the global circular LRU list. The last element in
|
||||
* the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at
|
||||
* the end of the array allows it to be addressed rationally when
|
||||
* looking up objects at a particular location in texture memory.
|
||||
*/
|
||||
for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) {
|
||||
list[i].prev = i-1;
|
||||
list[i].next = i+1;
|
||||
list[i].age = 0;
|
||||
}
|
||||
|
||||
i--;
|
||||
list[0].prev = RADEON_NR_TEX_REGIONS;
|
||||
list[i].prev = i-1;
|
||||
list[i].next = RADEON_NR_TEX_REGIONS;
|
||||
list[RADEON_NR_TEX_REGIONS].prev = i;
|
||||
list[RADEON_NR_TEX_REGIONS].next = 0;
|
||||
rmesa->sarea->texAge[heap] = 0;
|
||||
}
|
||||
|
||||
/* Update the local and glock texture LRUs.
|
||||
*/
|
||||
void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t )
|
||||
{
|
||||
int heap = t->heap;
|
||||
radeon_tex_region_t *list = rmesa->sarea->texList[heap];
|
||||
int sz = rmesa->radeonScreen->logTexGranularity[heap];
|
||||
int start = t->memBlock->ofs >> sz;
|
||||
int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz;
|
||||
int i;
|
||||
|
||||
rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap];
|
||||
|
||||
if ( !t->memBlock ) {
|
||||
fprintf( stderr, "no memblock\n\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update our local LRU */
|
||||
move_to_head( &rmesa->texture.objects[heap], t );
|
||||
|
||||
/* Update the global LRU */
|
||||
for ( i = start ; i <= end ; i++ ) {
|
||||
list[i].in_use = 1;
|
||||
list[i].age = rmesa->texture.age[heap];
|
||||
|
||||
/* remove_from_list(i) */
|
||||
list[(GLuint)list[i].next].prev = list[i].prev;
|
||||
list[(GLuint)list[i].prev].next = list[i].next;
|
||||
|
||||
/* insert_at_head(list, i) */
|
||||
list[i].prev = RADEON_NR_TEX_REGIONS;
|
||||
list[i].next = list[RADEON_NR_TEX_REGIONS].next;
|
||||
list[(GLuint)list[RADEON_NR_TEX_REGIONS].next].prev = i;
|
||||
list[RADEON_NR_TEX_REGIONS].next = i;
|
||||
}
|
||||
|
||||
if ( 0 ) {
|
||||
radeonPrintGlobalLRU( rmesa, t->heap );
|
||||
radeonPrintLocalLRU( rmesa, t->heap );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update our notion of what textures have been changed since we last
|
||||
* held the lock. This pertains to both our local textures and the
|
||||
* textures belonging to other clients. Keep track of other client's
|
||||
* textures by pushing a placeholder texture onto the LRU list -- these
|
||||
* are denoted by (tObj == NULL).
|
||||
*/
|
||||
static void radeonTexturesGone( radeonContextPtr rmesa, int heap,
|
||||
int offset, int size, int in_use )
|
||||
{
|
||||
radeonTexObjPtr t, tmp;
|
||||
|
||||
foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) {
|
||||
if ( t->memBlock->ofs >= offset + size ||
|
||||
t->memBlock->ofs + t->memBlock->size <= offset )
|
||||
continue;
|
||||
|
||||
/* It overlaps - kick it out. Need to hold onto the currently
|
||||
* bound objects, however.
|
||||
*/
|
||||
radeonSwapOutTexObj( rmesa, t );
|
||||
}
|
||||
|
||||
if ( in_use ) {
|
||||
t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
|
||||
if ( !t ) return;
|
||||
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset );
|
||||
if ( !t->memBlock ) {
|
||||
fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
|
||||
(int)size, (int)offset );
|
||||
mmDumpMemInfo( rmesa->texture.heap[heap] );
|
||||
return;
|
||||
}
|
||||
insert_at_head( &rmesa->texture.objects[heap], t );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update our client's shared texture state. If another client has
|
||||
* modified a region in which we have textures, then we need to figure
|
||||
* out which of our textures has been removed, and update our global
|
||||
* LRU.
|
||||
*/
|
||||
void radeonAgeTextures( radeonContextPtr rmesa, int heap )
|
||||
{
|
||||
RADEONSAREAPrivPtr sarea = rmesa->sarea;
|
||||
|
||||
if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) {
|
||||
int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
|
||||
int nr = 0;
|
||||
int idx;
|
||||
|
||||
for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ;
|
||||
idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ;
|
||||
idx = sarea->texList[heap][idx].prev, nr++ )
|
||||
{
|
||||
/* If switching texturing schemes, then the SAREA might not
|
||||
* have been properly cleared, so we need to reset the
|
||||
* global texture LRU.
|
||||
*/
|
||||
if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) {
|
||||
nr = RADEON_NR_TEX_REGIONS;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) {
|
||||
radeonTexturesGone( rmesa, heap, idx * sz, sz,
|
||||
sarea->texList[heap][idx].in_use );
|
||||
}
|
||||
}
|
||||
|
||||
if ( nr == RADEON_NR_TEX_REGIONS ) {
|
||||
radeonTexturesGone( rmesa, heap, 0,
|
||||
rmesa->radeonScreen->texSize[heap], 0 );
|
||||
radeonResetGlobalLRU( rmesa, heap );
|
||||
}
|
||||
|
||||
rmesa->texture.age[heap] = sarea->texAge[heap];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
* Texture image conversions
|
||||
*/
|
||||
|
||||
/* Upload the texture image associated with texture `t' at level `level'
|
||||
* at the address relative to `start'.
|
||||
*/
|
||||
static void radeonUploadSubImage( radeonContextPtr rmesa,
|
||||
radeonTexObjPtr t, GLint level,
|
||||
GLint x, GLint y, GLint width, GLint height )
|
||||
{
|
||||
struct gl_texture_image *texImage;
|
||||
const struct gl_texture_format *texFormat;
|
||||
GLint texelsPerDword = 0;
|
||||
GLuint format, pitch, offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drmRadeonTexture tex;
|
||||
drmRadeonTexImage tmp;
|
||||
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj );
|
||||
}
|
||||
|
||||
/* Ensure we have a valid texture to upload */
|
||||
level += t->firstLevel;
|
||||
if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) ) {
|
||||
_mesa_problem(NULL, "bad texture level in radeonUploadSubimage");
|
||||
return;
|
||||
}
|
||||
|
||||
texImage = t->tObj->Image[level];
|
||||
if ( !texImage ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
|
||||
return;
|
||||
}
|
||||
if ( !texImage->Data ) {
|
||||
if ( RADEON_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
|
||||
return;
|
||||
}
|
||||
|
||||
texFormat = texImage->TexFormat;
|
||||
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
texelsPerDword = 4;
|
||||
break;
|
||||
case 2:
|
||||
texelsPerDword = 2;
|
||||
break;
|
||||
case 4:
|
||||
texelsPerDword = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK;
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr;
|
||||
pitch = (t->image[0].width * texFormat->TexelBytes) / 64;
|
||||
|
||||
#if 0
|
||||
/* Bump the performace counter */
|
||||
rmesa->c_textureBytes += (dwords << 2);
|
||||
#endif
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
GLint imageX = 0;
|
||||
GLint imageY = 0;
|
||||
GLint blitX = t->image[level].x;
|
||||
GLint blitY = t->image[level].y;
|
||||
GLint blitWidth = t->image[level].width;
|
||||
GLint blitHeight = t->image[level].height;
|
||||
fprintf( stderr, " upload image: %d,%d at %d,%d\n",
|
||||
imageWidth, imageHeight, imageX, imageY );
|
||||
fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
|
||||
blitWidth, blitHeight, blitX, blitY );
|
||||
fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x "
|
||||
"level: %d format: %x\n",
|
||||
(GLuint)offset, (GLuint)pitch, level, format );
|
||||
}
|
||||
|
||||
t->image[level].data = texImage->Data;
|
||||
|
||||
tex.offset = offset;
|
||||
tex.pitch = pitch;
|
||||
tex.format = format;
|
||||
tex.width = imageWidth;
|
||||
tex.height = imageHeight;
|
||||
tex.image = &tmp;
|
||||
|
||||
memcpy( &tmp, &t->image[level], sizeof(drmRadeonTexImage) );
|
||||
|
||||
do {
|
||||
ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drmRadeonTexture) );
|
||||
} while ( ret && errno == EAGAIN );
|
||||
|
||||
if ( ret ) {
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n",
|
||||
offset, pitch, format );
|
||||
fprintf( stderr, " image width=%d height=%d\n",
|
||||
imageWidth, imageHeight );
|
||||
fprintf( stderr, " blit width=%d height=%d data=%p\n",
|
||||
t->image[level].width, t->image[level].height,
|
||||
t->image[level].data );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Upload the texture images associated with texture `t'. This might
|
||||
* require removing our own and/or other client's texture objects to
|
||||
* make room for these images.
|
||||
*/
|
||||
int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t )
|
||||
{
|
||||
const int numLevels = t->lastLevel - t->firstLevel + 1;
|
||||
int i;
|
||||
int heap;
|
||||
radeonTexObjPtr t0 = rmesa->state.texture.unit[0].texobj;
|
||||
radeonTexObjPtr t1 = rmesa->state.texture.unit[1].texobj;
|
||||
|
||||
if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
||||
rmesa->glCtx, t->tObj, t->totalSize,
|
||||
t->firstLevel, t->lastLevel );
|
||||
}
|
||||
|
||||
if ( !t || t->totalSize == 0 )
|
||||
return 0;
|
||||
|
||||
LOCK_HARDWARE( rmesa );
|
||||
|
||||
/* Choose the heap appropriately */
|
||||
heap = t->heap = RADEON_CARD_HEAP;
|
||||
#if 0
|
||||
if ( !rmesa->radeonScreen->IsPCI &&
|
||||
t->totalSize > rmesa->radeonScreen->texSize[heap] ) {
|
||||
heap = t->heap = RADEON_AGP_HEAP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do we need to eject LRU texture objects? */
|
||||
if ( !t->memBlock ) {
|
||||
/* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap],
|
||||
t->totalSize, 12, 0 );
|
||||
|
||||
#if 0
|
||||
/* Try AGP before kicking anything out of local mem */
|
||||
if ( !t->memBlock && heap == RADEON_CARD_HEAP ) {
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[RADEON_AGP_HEAP],
|
||||
t->totalSize, 12, 0 );
|
||||
|
||||
if ( t->memBlock )
|
||||
heap = t->heap = RADEON_AGP_HEAP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Kick out textures until the requested texture fits */
|
||||
while ( !t->memBlock ) {
|
||||
if ( rmesa->texture.objects[heap].prev == t0 ||
|
||||
rmesa->texture.objects[heap].prev == t1 ) {
|
||||
fprintf( stderr,
|
||||
"radeonUploadTexImages: ran into bound texture\n" );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
}
|
||||
if ( rmesa->texture.objects[heap].prev ==
|
||||
&rmesa->texture.objects[heap] ) {
|
||||
if ( rmesa->radeonScreen->IsPCI ) {
|
||||
fprintf( stderr, "radeonUploadTexImages: upload texture "
|
||||
"failure on local texture heaps, sz=%d\n",
|
||||
t->totalSize );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
#if 0
|
||||
} else if ( heap == RADEON_CARD_HEAP ) {
|
||||
heap = t->heap = RADEON_AGP_HEAP;
|
||||
continue;
|
||||
#endif
|
||||
} else {
|
||||
fprintf( stderr, "radeonUploadTexImages: upload texture "
|
||||
"failure on both local and AGP texture heaps, "
|
||||
"sz=%d\n",
|
||||
t->totalSize );
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
radeonSwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev );
|
||||
|
||||
t->memBlock = mmAllocMem( rmesa->texture.heap[heap],
|
||||
t->totalSize, 12, 0 );
|
||||
}
|
||||
|
||||
/* Set the base offset of the texture image */
|
||||
t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs;
|
||||
t->pp_txoffset = t->bufAddr;
|
||||
|
||||
#if 0
|
||||
/* Fix AGP texture offsets */
|
||||
if ( heap == RADEON_AGP_HEAP ) {
|
||||
t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET +
|
||||
rmesa->radeonScreen->agpTexOffset;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Mark this texobj as dirty on all units:
|
||||
*/
|
||||
t->dirty_state = TEX_ALL;
|
||||
}
|
||||
|
||||
/* Let the world know we've used this memory recently */
|
||||
radeonUpdateTexLRU( rmesa, t );
|
||||
|
||||
/* Upload any images that are new */
|
||||
if (t->dirty_images) {
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
if ( t->dirty_images & (1 << i) ) {
|
||||
radeonUploadSubImage( rmesa, t, i, 0, 0,
|
||||
t->image[i].width, t->image[i].height );
|
||||
}
|
||||
}
|
||||
t->dirty_images = 0;
|
||||
}
|
||||
|
||||
|
||||
UNLOCK_HARDWARE( rmesa );
|
||||
|
||||
return 0;
|
||||
}
|
||||
1407
src/mesa/drivers/dri/radeon/radeon_texstate.c
Normal file
1407
src/mesa/drivers/dri/radeon/radeon_texstate.c
Normal file
File diff suppressed because it is too large
Load diff
1125
src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
Normal file
1125
src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
Normal file
File diff suppressed because it is too large
Load diff
128
src/mesa/drivers/dri/radeon/radeon_vtxfmt.h
Normal file
128
src/mesa/drivers/dri/radeon/radeon_vtxfmt.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_VTXFMT_H__
|
||||
#define __RADEON_VTXFMT_H__
|
||||
|
||||
#ifdef GLX_DIRECT_RENDERING
|
||||
|
||||
#include "radeon_context.h"
|
||||
|
||||
|
||||
|
||||
extern struct radeon_vb vb;
|
||||
|
||||
|
||||
extern void radeonVtxfmtUpdate( GLcontext *ctx );
|
||||
extern void radeonVtxfmtInit( GLcontext *ctx );
|
||||
extern void radeonVtxfmtInvalidate( GLcontext *ctx );
|
||||
extern void radeonVtxfmtDestroy( GLcontext *ctx );
|
||||
extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt );
|
||||
|
||||
extern void radeonVtxfmtMakeCurrent( GLcontext *ctx );
|
||||
extern void radeonVtxfmtUnbindContext( GLcontext *ctx );
|
||||
|
||||
extern void radeon_copy_to_current( GLcontext *ctx );
|
||||
|
||||
#define DFN( FUNC, CACHE) \
|
||||
do { \
|
||||
char *start = (char *)&FUNC; \
|
||||
char *end = (char *)&FUNC##_end; \
|
||||
insert_at_head( &CACHE, dfn ); \
|
||||
dfn->key = key; \
|
||||
dfn->code = ALIGN_MALLOC( end - start, 16 ); \
|
||||
memcpy (dfn->code, start, end - start); \
|
||||
} \
|
||||
while ( 0 )
|
||||
|
||||
#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \
|
||||
do { \
|
||||
int *icode = (int *)(CODE+OFFSET); \
|
||||
assert (*icode == CHECKVAL); \
|
||||
*icode = (int)NEWVAL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Useful for figuring out the offsets:
|
||||
*/
|
||||
#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \
|
||||
do { \
|
||||
while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \
|
||||
fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \
|
||||
__LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \
|
||||
*(int *)(CODE+OFFSET) = (int)(NEWVAL); \
|
||||
OFFSET += 4; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
*/
|
||||
void radeonInitCodegen( struct dfn_generators *gen );
|
||||
void radeonInitX86Codegen( struct dfn_generators *gen );
|
||||
void radeonInitSSECodegen( struct dfn_generators *gen );
|
||||
|
||||
|
||||
|
||||
/* Defined in radeon_vtxfmt_x86.c
|
||||
*/
|
||||
struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color4ub( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color3ub( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color4f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color4fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color3f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Color3fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Normal3f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int );
|
||||
struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int );
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
728
src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c
Normal file
728
src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c
Normal file
|
|
@ -0,0 +1,728 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
#include "glheader.h"
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
#include "simple_list.h"
|
||||
#include "api_noop.h"
|
||||
#include "vtxfmt.h"
|
||||
|
||||
#include "radeon_vtxfmt.h"
|
||||
|
||||
/* Fallback versions of all the entrypoints for situations where
|
||||
* codegen isn't available. This is still a lot faster than the
|
||||
* vb/pipeline implementation in Mesa.
|
||||
*/
|
||||
static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&x;
|
||||
*vb.dmaptr++ = *(int *)&y;
|
||||
*vb.dmaptr++ = *(int *)&z;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Vertex3fv( const GLfloat *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&v[0];
|
||||
*vb.dmaptr++ = *(int *)&v[1];
|
||||
*vb.dmaptr++ = *(int *)&v[2];
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Vertex2f( GLfloat x, GLfloat y )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&x;
|
||||
*vb.dmaptr++ = *(int *)&y;
|
||||
*vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = *(int *)&vb.vertex[i];
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Vertex2fv( const GLfloat *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
*vb.dmaptr++ = *(int *)&v[0];
|
||||
*vb.dmaptr++ = *(int *)&v[1];
|
||||
*vb.dmaptr++ = 0;
|
||||
|
||||
for (i = 3; i < vb.vertex_size; i++)
|
||||
*vb.dmaptr++ = vb.vertex[i].i;
|
||||
|
||||
if (--vb.counter == 0)
|
||||
vb.notify();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color for ubyte (packed) color formats:
|
||||
*/
|
||||
static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void radeon_Color3ubv_ub( const GLubyte *v )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
dest->red = v[0];
|
||||
dest->green = v[1];
|
||||
dest->blue = v[2];
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = a;
|
||||
}
|
||||
|
||||
static void radeon_Color4ubv_ub( const GLubyte *v )
|
||||
{
|
||||
*(GLuint *)vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void radeon_Color3fv_ub( const GLfloat *v )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a );
|
||||
}
|
||||
|
||||
static void radeon_Color4fv_ub( const GLfloat *v )
|
||||
{
|
||||
radeon_color_t *dest = vb.colorptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* Color for float color+alpha formats:
|
||||
*/
|
||||
static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void radeon_Color3ubv_4f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
dest[3] = UBYTE_TO_FLOAT(a);
|
||||
}
|
||||
|
||||
static void radeon_Color4ubv_4f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
dest[3] = UBYTE_TO_FLOAT(v[3]);
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void radeon_Color3fv_4f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
dest[3] = a;
|
||||
}
|
||||
|
||||
static void radeon_Color4fv_4f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = v[3];
|
||||
}
|
||||
|
||||
|
||||
/* Color for float color formats:
|
||||
*/
|
||||
static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
}
|
||||
|
||||
static void radeon_Color3ubv_3f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
}
|
||||
|
||||
static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(r);
|
||||
dest[1] = UBYTE_TO_FLOAT(g);
|
||||
dest[2] = UBYTE_TO_FLOAT(b);
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
|
||||
}
|
||||
|
||||
static void radeon_Color4ubv_3f( const GLubyte *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = UBYTE_TO_FLOAT(v[0]);
|
||||
dest[1] = UBYTE_TO_FLOAT(v[1]);
|
||||
dest[2] = UBYTE_TO_FLOAT(v[2]);
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
|
||||
}
|
||||
|
||||
|
||||
static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
}
|
||||
|
||||
static void radeon_Color3fv_3f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
}
|
||||
|
||||
static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
|
||||
}
|
||||
|
||||
static void radeon_Color4fv_3f( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.floatcolorptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
vb.context->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
|
||||
}
|
||||
|
||||
|
||||
/* Secondary Color:
|
||||
*/
|
||||
static void radeon_SecondaryColor3ubEXT( GLubyte r, GLubyte g, GLubyte b )
|
||||
{
|
||||
radeon_color_t *dest = vb.specptr;
|
||||
dest->red = r;
|
||||
dest->green = g;
|
||||
dest->blue = b;
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void radeon_SecondaryColor3ubvEXT( const GLubyte *v )
|
||||
{
|
||||
radeon_color_t *dest = vb.specptr;
|
||||
dest->red = v[0];
|
||||
dest->green = v[1];
|
||||
dest->blue = v[2];
|
||||
dest->alpha = 0xff;
|
||||
}
|
||||
|
||||
static void radeon_SecondaryColor3fEXT( GLfloat r, GLfloat g, GLfloat b )
|
||||
{
|
||||
radeon_color_t *dest = vb.specptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
static void radeon_SecondaryColor3fvEXT( const GLfloat *v )
|
||||
{
|
||||
radeon_color_t *dest = vb.specptr;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
|
||||
UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
|
||||
dest->alpha = 255;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Normal
|
||||
*/
|
||||
static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
|
||||
{
|
||||
GLfloat *dest = vb.normalptr;
|
||||
dest[0] = n0;
|
||||
dest[1] = n1;
|
||||
dest[2] = n2;
|
||||
}
|
||||
|
||||
static void radeon_Normal3fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.normalptr;
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
/* TexCoord
|
||||
*/
|
||||
static void radeon_TexCoord1f( GLfloat s )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void radeon_TexCoord1fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void radeon_TexCoord2f( GLfloat s, GLfloat t )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void radeon_TexCoord2fv( const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[0];
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
}
|
||||
|
||||
|
||||
/* MultiTexcoord
|
||||
*/
|
||||
static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = s;
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = v[0];
|
||||
dest[1] = 0;
|
||||
}
|
||||
|
||||
static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = s;
|
||||
dest[1] = t;
|
||||
}
|
||||
|
||||
static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1];
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
}
|
||||
|
||||
static struct dynfn *lookup( struct dynfn *l, int key )
|
||||
{
|
||||
struct dynfn *f;
|
||||
|
||||
foreach( f, l ) {
|
||||
if (f->key == key)
|
||||
return f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Can't use the loopback template for this:
|
||||
*/
|
||||
|
||||
#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
|
||||
static void choose_##FN ARGS1 \
|
||||
{ \
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(vb.context); \
|
||||
int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \
|
||||
struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
|
||||
\
|
||||
if (dfn == 0) \
|
||||
dfn = rmesa->vb.codegen.FN( vb.context, key ); \
|
||||
else if (RADEON_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
|
||||
\
|
||||
if (dfn) \
|
||||
vb.context->Exec->FN = (FNTYPE)(dfn->code); \
|
||||
else { \
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
|
||||
vb.context->Exec->FN = radeon_##FN; \
|
||||
} \
|
||||
\
|
||||
vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
vb.context->Exec->FN ARGS2; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* For the _3f case, only allow one color function to be hooked in at
|
||||
* a time. Eventually, use a similar mechanism to allow selecting the
|
||||
* color component of the vertex format based on client behaviour.
|
||||
*
|
||||
* Note: Perform these actions even if there is a codegen or cached
|
||||
* codegen version of the chosen function.
|
||||
*/
|
||||
#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \
|
||||
static void choose_##FN ARGS1 \
|
||||
{ \
|
||||
GLcontext *ctx = vb.context; \
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(vb.context); \
|
||||
int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \
|
||||
struct dynfn *dfn; \
|
||||
\
|
||||
if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \
|
||||
ctx->Exec->FN = radeon_##FN##_ub; \
|
||||
} \
|
||||
else if ((rmesa->vb.vertex_format & \
|
||||
(ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \
|
||||
\
|
||||
if (rmesa->vb.installed_color_3f_sz != NR) { \
|
||||
rmesa->vb.installed_color_3f_sz = NR; \
|
||||
if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
|
||||
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
|
||||
radeon_copy_to_current( ctx ); \
|
||||
_mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
|
||||
ctx->Exec->FN ARGS2; \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
ctx->Exec->FN = radeon_##FN##_3f; \
|
||||
} \
|
||||
else { \
|
||||
ctx->Exec->FN = radeon_##FN##_4f; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
|
||||
if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
|
||||
\
|
||||
if (dfn) { \
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
|
||||
ctx->Exec->FN = (FNTYPE)dfn->code; \
|
||||
} \
|
||||
else if (RADEON_DEBUG & DEBUG_CODEGEN) \
|
||||
fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
|
||||
\
|
||||
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
|
||||
ctx->Exec->FN ARGS2; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Shorthands
|
||||
*/
|
||||
#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z)
|
||||
#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0
|
||||
#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR
|
||||
#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR
|
||||
#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA
|
||||
#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR)
|
||||
#define ACTIVE_SPEC RADEON_CP_VC_FRMT_PKSPEC
|
||||
#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0
|
||||
#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1
|
||||
#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0)
|
||||
|
||||
/* Each codegen function should be able to be fully specified by a
|
||||
* subsetted version of rmesa->vb.vertex_format.
|
||||
*/
|
||||
#define MASK_NORM (ACTIVE_XYZW)
|
||||
#define MASK_COLOR (MASK_NORM|ACTIVE_NORM)
|
||||
#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR)
|
||||
#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC)
|
||||
#define MASK_ST1 (MASK_ST0|ACTIVE_ST0)
|
||||
#define MASK_ST_ALL (MASK_ST1|ACTIVE_ST1)
|
||||
#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA)
|
||||
|
||||
|
||||
typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
|
||||
typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
|
||||
typedef void (*p2f)( GLfloat, GLfloat );
|
||||
typedef void (*p1f)( GLfloat );
|
||||
typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
|
||||
typedef void (*pe1f)( GLenum, GLfloat );
|
||||
typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
|
||||
typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
|
||||
typedef void (*pfv)( const GLfloat * );
|
||||
typedef void (*pefv)( GLenum, const GLfloat * );
|
||||
typedef void (*pubv)( const GLubyte * );
|
||||
|
||||
|
||||
CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM,
|
||||
(GLfloat a,GLfloat b,GLfloat c), (a,b,c))
|
||||
CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR,
|
||||
(GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
|
||||
CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR,
|
||||
(const GLubyte *v), (v))
|
||||
CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR,
|
||||
(GLubyte a,GLubyte b, GLubyte c), (a,b,c))
|
||||
CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR,
|
||||
(const GLubyte *v), (v))
|
||||
|
||||
CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR,
|
||||
(GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
|
||||
CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR,
|
||||
(GLfloat a,GLfloat b, GLfloat c), (a,b,c))
|
||||
CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
|
||||
CHOOSE(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC,
|
||||
(GLubyte a,GLubyte b, GLubyte c), (a,b,c))
|
||||
CHOOSE(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC,
|
||||
(const GLubyte *v), (v))
|
||||
CHOOSE(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC,
|
||||
(GLfloat a,GLfloat b, GLfloat c), (a,b,c))
|
||||
CHOOSE(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0,
|
||||
(GLfloat a,GLfloat b), (a,b))
|
||||
CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0,
|
||||
(GLfloat a), (a))
|
||||
CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL,
|
||||
(GLenum u,GLfloat a,GLfloat b), (u,a,b))
|
||||
CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
|
||||
(GLenum u,const GLfloat *v), (u,v))
|
||||
CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL,
|
||||
(GLenum u,GLfloat a), (u,a))
|
||||
CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
|
||||
(GLenum u,const GLfloat *v), (u,v))
|
||||
|
||||
CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX,
|
||||
(GLfloat a,GLfloat b,GLfloat c), (a,b,c))
|
||||
CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX,
|
||||
(const GLfloat *v), (v))
|
||||
CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX,
|
||||
(GLfloat a,GLfloat b), (a,b))
|
||||
CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX,
|
||||
(const GLfloat *v), (v))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void radeonVtxfmtInitChoosers( GLvertexformat *vfmt )
|
||||
{
|
||||
vfmt->Color3f = choose_Color3f;
|
||||
vfmt->Color3fv = choose_Color3fv;
|
||||
vfmt->Color3ub = choose_Color3ub;
|
||||
vfmt->Color3ubv = choose_Color3ubv;
|
||||
vfmt->Color4f = choose_Color4f;
|
||||
vfmt->Color4fv = choose_Color4fv;
|
||||
vfmt->Color4ub = choose_Color4ub;
|
||||
vfmt->Color4ubv = choose_Color4ubv;
|
||||
vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
|
||||
vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
|
||||
vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
|
||||
vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
|
||||
vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
|
||||
vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
|
||||
vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
|
||||
vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
|
||||
vfmt->Normal3f = choose_Normal3f;
|
||||
vfmt->Normal3fv = choose_Normal3fv;
|
||||
vfmt->TexCoord1f = choose_TexCoord1f;
|
||||
vfmt->TexCoord1fv = choose_TexCoord1fv;
|
||||
vfmt->TexCoord2f = choose_TexCoord2f;
|
||||
vfmt->TexCoord2fv = choose_TexCoord2fv;
|
||||
vfmt->Vertex2f = choose_Vertex2f;
|
||||
vfmt->Vertex2fv = choose_Vertex2fv;
|
||||
vfmt->Vertex3f = choose_Vertex3f;
|
||||
vfmt->Vertex3fv = choose_Vertex3fv;
|
||||
}
|
||||
|
||||
|
||||
static struct dynfn *codegen_noop( GLcontext *ctx, int key )
|
||||
{
|
||||
(void) ctx; (void) key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeonInitCodegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Vertex3f = codegen_noop;
|
||||
gen->Vertex3fv = codegen_noop;
|
||||
gen->Color4ub = codegen_noop;
|
||||
gen->Color4ubv = codegen_noop;
|
||||
gen->Normal3f = codegen_noop;
|
||||
gen->Normal3fv = codegen_noop;
|
||||
gen->TexCoord2f = codegen_noop;
|
||||
gen->TexCoord2fv = codegen_noop;
|
||||
gen->MultiTexCoord2fARB = codegen_noop;
|
||||
gen->MultiTexCoord2fvARB = codegen_noop;
|
||||
gen->Vertex2f = codegen_noop;
|
||||
gen->Vertex2fv = codegen_noop;
|
||||
gen->Color3ub = codegen_noop;
|
||||
gen->Color3ubv = codegen_noop;
|
||||
gen->Color4f = codegen_noop;
|
||||
gen->Color4fv = codegen_noop;
|
||||
gen->Color3f = codegen_noop;
|
||||
gen->Color3fv = codegen_noop;
|
||||
gen->SecondaryColor3fEXT = codegen_noop;
|
||||
gen->SecondaryColor3fvEXT = codegen_noop;
|
||||
gen->SecondaryColor3ubEXT = codegen_noop;
|
||||
gen->SecondaryColor3ubvEXT = codegen_noop;
|
||||
gen->TexCoord1f = codegen_noop;
|
||||
gen->TexCoord1fv = codegen_noop;
|
||||
gen->MultiTexCoord1fARB = codegen_noop;
|
||||
gen->MultiTexCoord1fvARB = codegen_noop;
|
||||
|
||||
if (!getenv("RADEON_NO_CODEGEN")) {
|
||||
#if defined(USE_X86_ASM)
|
||||
radeonInitX86Codegen( gen );
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSE_ASM)
|
||||
radeonInitSSECodegen( gen );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
87
src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c
Normal file
87
src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "simple_list.h"
|
||||
#include "radeon_vtxfmt.h"
|
||||
|
||||
#if defined(USE_SSE_ASM)
|
||||
#include "X86/common_x86_asm.h"
|
||||
|
||||
/* Build specialized versions of the immediate calls on the fly for
|
||||
* the current state. ???P4 SSE2 versions???
|
||||
*/
|
||||
|
||||
|
||||
static struct dynfn *makeSSENormal3fv( GLcontext *ctx, int key )
|
||||
{
|
||||
/* Requires P4 (sse2?)
|
||||
*/
|
||||
static unsigned char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */
|
||||
0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */
|
||||
0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */
|
||||
0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */
|
||||
0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn );
|
||||
dfn->key = key;
|
||||
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 5, 0x0, (int)vb.normalptr);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
void radeonInitSSECodegen( struct dfn_generators *gen )
|
||||
{
|
||||
if ( cpu_has_xmm && cpu_has_xmm2 )
|
||||
/*gen->Normal3fv = */ (void)makeSSENormal3fv;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void radeonInitSSECodegen( struct dfn_generators *gen )
|
||||
{
|
||||
(void) gen;
|
||||
}
|
||||
|
||||
#endif
|
||||
462
src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c
Normal file
462
src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/* $XFree86$ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
|
||||
Tungsten Graphics Inc., Cedar Park, Texas.
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mmath.h"
|
||||
#include "simple_list.h"
|
||||
#include "radeon_vtxfmt.h"
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
|
||||
#define EXTERN( FUNC ) \
|
||||
extern const char *FUNC; \
|
||||
extern const char *FUNC##_end
|
||||
|
||||
EXTERN ( _x86_Normal3fv );
|
||||
EXTERN ( _x86_Normal3f );
|
||||
EXTERN ( _x86_Vertex3fv_6 );
|
||||
EXTERN ( _x86_Vertex3fv_8 );
|
||||
EXTERN ( _x86_Vertex3fv );
|
||||
EXTERN ( _x86_Vertex3f_4 );
|
||||
EXTERN ( _x86_Vertex3f_6 );
|
||||
EXTERN ( _x86_Vertex3f );
|
||||
EXTERN ( _x86_Color4ubv_ub );
|
||||
EXTERN ( _x86_Color4ubv_4f );
|
||||
EXTERN ( _x86_Color4ub_ub );
|
||||
EXTERN ( _x86_Color3fv_3f );
|
||||
EXTERN ( _x86_Color3f_3f );
|
||||
EXTERN ( _x86_TexCoord2fv );
|
||||
EXTERN ( _x86_TexCoord2f );
|
||||
EXTERN ( _x86_MultiTexCoord2fvARB );
|
||||
EXTERN ( _x86_MultiTexCoord2fvARB_2 );
|
||||
EXTERN ( _x86_MultiTexCoord2fARB );
|
||||
EXTERN ( _x86_MultiTexCoord2fARB_2 );
|
||||
|
||||
|
||||
/* Build specialized versions of the immediate calls on the fly for
|
||||
* the current state. Generic x86 versions.
|
||||
*/
|
||||
|
||||
struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, vb.vertex_size );
|
||||
|
||||
switch (vb.vertex_size) {
|
||||
case 4: {
|
||||
|
||||
DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 2, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 25, 0x0, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 36, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 46, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 51, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 60, 0x0, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
|
||||
DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 3, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 28, 0x0, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 34, 0x0, (int)&vb.vertex[4]);
|
||||
FIXUP(dfn->code, 40, 0x0, (int)&vb.vertex[5]);
|
||||
FIXUP(dfn->code, 57, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 63, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 70, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 79, 0x0, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f );
|
||||
FIXUP(dfn->code, 3, 0x0, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 9, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 37, 0x0, vb.vertex_size-3);
|
||||
FIXUP(dfn->code, 44, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 50, 0x0, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 56, 0x0, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x0, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key )
|
||||
{
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, vb.vertex_size );
|
||||
|
||||
switch (vb.vertex_size) {
|
||||
case 6: {
|
||||
|
||||
DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]);
|
||||
FIXUP(dfn->code, 45, 0x00000024, (int)&vb.vertex[5]);
|
||||
FIXUP(dfn->code, 56, 0x00000000, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 61, 0x00000004, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x00000004, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 76, 0x00000008, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 8: {
|
||||
|
||||
DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]);
|
||||
FIXUP(dfn->code, 45, 0x0000001c, (int)&vb.vertex[5]);
|
||||
FIXUP(dfn->code, 51, 0x00000020, (int)&vb.vertex[6]);
|
||||
FIXUP(dfn->code, 63, 0x00000024, (int)&vb.vertex[7]);
|
||||
FIXUP(dfn->code, 74, 0x00000000, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 79, 0x00000004, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 85, 0x00000004, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 94, 0x00000008, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
default: {
|
||||
|
||||
DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv );
|
||||
FIXUP(dfn->code, 8, 0x01010101, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 32, 0x00000006, vb.vertex_size-3);
|
||||
FIXUP(dfn->code, 37, 0x00000058, (int)&vb.vertex[3]);
|
||||
FIXUP(dfn->code, 45, 0x01010101, (int)&vb.dmaptr);
|
||||
FIXUP(dfn->code, 50, 0x02020202, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 58, 0x02020202, (int)&vb.counter);
|
||||
FIXUP(dfn->code, 67, 0x0, (int)&vb.notify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
int i = 0;
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv );
|
||||
|
||||
FIXUP2(dfn->code, i, 0x0, (int)vb.normalptr);
|
||||
FIXUP2(dfn->code, i, 0x4, 4+(int)vb.normalptr);
|
||||
FIXUP2(dfn->code, i, 0x8, 8+(int)vb.normalptr);
|
||||
fprintf(stderr, "%s done\n", __FUNCTION__);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f );
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)vb.normalptr);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
if (key & RADEON_CP_VC_FRMT_PKCOLOR) {
|
||||
DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv);
|
||||
FIXUP(dfn->code, 5, 0x12345678, (int)vb.colorptr);
|
||||
return dfn;
|
||||
}
|
||||
else {
|
||||
|
||||
DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv);
|
||||
FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
|
||||
FIXUP(dfn->code, 27, 0xdeadbeaf, (int)vb.floatcolorptr);
|
||||
FIXUP(dfn->code, 33, 0xdeadbeaf, (int)vb.floatcolorptr+4);
|
||||
FIXUP(dfn->code, 55, 0xdeadbeaf, (int)vb.floatcolorptr+8);
|
||||
FIXUP(dfn->code, 61, 0xdeadbeaf, (int)vb.floatcolorptr+12);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key )
|
||||
{
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
if (key & RADEON_CP_VC_FRMT_PKCOLOR) {
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub );
|
||||
FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr);
|
||||
FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1);
|
||||
FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2);
|
||||
FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3);
|
||||
return dfn;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key )
|
||||
{
|
||||
if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv );
|
||||
FIXUP(dfn->code, 5, 0x0, (int)vb.floatcolorptr);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key )
|
||||
{
|
||||
if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f );
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key )
|
||||
{
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv );
|
||||
FIXUP(dfn->code, 5, 0x12345678, (int)vb.texcoordptr[0]);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key )
|
||||
{
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f );
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)vb.texcoordptr[0]);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key )
|
||||
{
|
||||
#if 0
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x11, /* mov (%ecx),%edx */
|
||||
0xc1, 0xe0, 0x03, /* shl $0x3,%eax */
|
||||
0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */
|
||||
0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */
|
||||
0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
static char temp2[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */
|
||||
0x8b, 0x01, /* mov (%ecx),%eax */
|
||||
0x89, 0x02, /* mov %eax,(%edx) */
|
||||
0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */
|
||||
0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
|
||||
(RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
|
||||
DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 26, 0xdeadbeef, (int)vb.texcoordptr[0]);
|
||||
FIXUP(dfn->code, 32, 0xdeadbeef, (int)vb.texcoordptr[0]+4);
|
||||
} else {
|
||||
DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
|
||||
FIXUP(dfn->code, 19, 0x0, (int)vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx,
|
||||
int key )
|
||||
{
|
||||
#if 0
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0xc1, 0xe0, 0x03, /* shl $0x3,%eax */
|
||||
0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */
|
||||
0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
static char temp2[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */
|
||||
0x89, 0x10, /* mov %edx,(%eax) */
|
||||
0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
#endif
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
|
||||
(RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
|
||||
DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 25, 0xdeadbeef, (int)vb.texcoordptr[0]);
|
||||
FIXUP(dfn->code, 31, 0xdeadbeef, (int)vb.texcoordptr[0]+4);
|
||||
}
|
||||
else {
|
||||
/* Note: this might get generated multiple times, even though the
|
||||
* actual emitted code is the same.
|
||||
*/
|
||||
DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
|
||||
FIXUP(dfn->code, 23, 0x0, (int)vb.texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
void radeonInitX86Codegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Vertex3f = radeon_makeX86Vertex3f;
|
||||
gen->Vertex3fv = radeon_makeX86Vertex3fv;
|
||||
gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */
|
||||
gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */
|
||||
gen->Normal3f = radeon_makeX86Normal3f;
|
||||
gen->Normal3fv = radeon_makeX86Normal3fv;
|
||||
gen->TexCoord2f = radeon_makeX86TexCoord2f;
|
||||
gen->TexCoord2fv = radeon_makeX86TexCoord2fv;
|
||||
gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB;
|
||||
gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB;
|
||||
gen->Color3f = radeon_makeX86Color3f;
|
||||
gen->Color3fv = radeon_makeX86Color3fv;
|
||||
|
||||
/* Not done:
|
||||
*/
|
||||
/* gen->Vertex2f = radeon_makeX86Vertex2f; */
|
||||
/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */
|
||||
/* gen->Color3ub = radeon_makeX86Color3ub; */
|
||||
/* gen->Color3ubv = radeon_makeX86Color3ubv; */
|
||||
/* gen->Color4f = radeon_makeX86Color4f; */
|
||||
/* gen->Color4fv = radeon_makeX86Color4fv; */
|
||||
/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */
|
||||
/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */
|
||||
/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */
|
||||
/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
void radeonInitX86Codegen( struct dfn_generators *gen )
|
||||
{
|
||||
(void) gen;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue