Remove the old i915 driver now that i915tex works without TTM.

This commit is contained in:
Eric Anholt 2007-09-24 09:55:16 -07:00
parent 439fa79578
commit 8fba8d2018
50 changed files with 2 additions and 21710 deletions

View File

@ -45,6 +45,6 @@ DRM_SOURCE_PATH=$(TOP)/../drm
# ffb and gamma are missing because they have not been converted to use the new
# interface.
DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \
DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon tdfx \
unichrome savage sis

View File

@ -66,5 +66,5 @@ WINDOW_SYSTEM=dri
# gamma are missing because they have not been converted to use the new
# interface.
DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \
DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon s3v \
savage sis tdfx trident unichrome ffb

View File

@ -1,50 +0,0 @@
TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = i915_dri.so
MINIGLX_SOURCES = server/intel_dri.c
DRIVER_SOURCES = \
i915_context.c \
i915_debug.c \
i915_fragprog.c \
i915_metaops.c \
i915_program.c \
i915_state.c \
i915_tex.c \
i915_texprog.c \
i915_texstate.c \
i915_vtbl.c \
i830_context.c \
i830_metaops.c \
i830_state.c \
i830_texblend.c \
i830_tex.c \
i830_texstate.c \
i830_vtbl.c \
intel_batchbuffer.c \
intel_context.c \
intel_ioctl.c \
intel_pixel.c \
intel_render.c \
intel_rotate.c \
intel_screen.c \
intel_span.c \
intel_state.c \
intel_tex.c \
intel_texmem.c \
intel_tris.c
C_SOURCES = \
$(COMMON_SOURCES) \
$(DRIVER_SOURCES)
ASM_SOURCES =
include ../Makefile.template
symlinks:

View File

@ -1,124 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "i830_context.h"
#include "imports.h"
#include "texmem.h"
#include "intel_tex.h"
#include "tnl/tnl.h"
#include "tnl/t_vertex.h"
#include "tnl/t_context.h"
#include "utils.h"
/***************************************
* Mesa's Driver Functions
***************************************/
static const struct dri_extension i830_extensions[] =
{
{ "GL_ARB_texture_env_crossbar", NULL },
{ NULL, NULL }
};
static void i830InitDriverFunctions( struct dd_function_table *functions )
{
intelInitDriverFunctions( functions );
i830InitStateFuncs( functions );
i830InitTextureFuncs( functions );
}
GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
struct dd_function_table functions;
i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context);
intelContextPtr intel = &i830->intel;
GLcontext *ctx = &intel->ctx;
GLuint i;
if (!i830) return GL_FALSE;
i830InitVtbl( i830 );
i830InitDriverFunctions( &functions );
if (!intelInitContext( intel, mesaVis, driContextPriv,
sharedContextPrivate, &functions )) {
FREE(i830);
return GL_FALSE;
}
intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS;
intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS;
intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS;
intel->nr_heaps = 1;
intel->texture_heaps[0] =
driCreateTextureHeap( 0, intel,
intel->intelScreen->tex.size,
12,
I830_NR_TEX_REGIONS,
intel->sarea->texList,
(unsigned *) & intel->sarea->texAge,
& intel->swapped,
sizeof( struct i830_texture_object ),
(destroy_texture_object_t *)intelDestroyTexObj );
/* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly
* FIXME: packed, but they're not in Intel graphics hardware.
*/
intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS;
i = driQueryOptioni( &intel->optionCache, "allow_large_textures");
driCalculateMaxTextureLevels( intel->texture_heaps,
intel->nr_heaps,
&intel->ctx.Const,
4,
11, /* max 2D texture size is 2048x2048 */
8, /* max 3D texture size is 256^3 */
10, /* max CUBE texture size is 1024x1024 */
11, /* max RECT. supported */
12,
GL_FALSE,
i );
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
18 * sizeof(GLfloat) );
intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf;
driInitExtensions( ctx, i830_extensions, GL_FALSE );
i830InitState( i830 );
_tnl_allow_vertex_fog( ctx, 1 );
_tnl_allow_pixel_fog( ctx, 0 );
return GL_TRUE;
}

View File

@ -1,218 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef I830CONTEXT_INC
#define I830CONTEXT_INC
#include "intel_context.h"
#define I830_FALLBACK_TEXTURE 0x1000
#define I830_FALLBACK_COLORMASK 0x2000
#define I830_FALLBACK_STENCIL 0x4000
#define I830_FALLBACK_STIPPLE 0x8000
#define I830_FALLBACK_LOGICOP 0x10000
#define I830_UPLOAD_CTX 0x1
#define I830_UPLOAD_BUFFERS 0x2
#define I830_UPLOAD_STIPPLE 0x4
#define I830_UPLOAD_INVARIENT 0x8
#define I830_UPLOAD_TEX(i) (0x10<<(i))
#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i))
#define I830_UPLOAD_TEX_ALL (0x0f0)
#define I830_UPLOAD_TEXBLEND_ALL (0xf00)
/* State structure offsets - these will probably disappear.
*/
#define I830_DESTREG_CBUFADDR0 0
#define I830_DESTREG_CBUFADDR1 1
#define I830_DESTREG_CBUFADDR2 2
#define I830_DESTREG_DBUFADDR0 3
#define I830_DESTREG_DBUFADDR1 4
#define I830_DESTREG_DBUFADDR2 5
#define I830_DESTREG_DV0 6
#define I830_DESTREG_DV1 7
#define I830_DESTREG_SENABLE 8
#define I830_DESTREG_SR0 9
#define I830_DESTREG_SR1 10
#define I830_DESTREG_SR2 11
#define I830_DEST_SETUP_SIZE 12
#define I830_CTXREG_STATE1 0
#define I830_CTXREG_STATE2 1
#define I830_CTXREG_STATE3 2
#define I830_CTXREG_STATE4 3
#define I830_CTXREG_STATE5 4
#define I830_CTXREG_IALPHAB 5
#define I830_CTXREG_STENCILTST 6
#define I830_CTXREG_ENABLES_1 7
#define I830_CTXREG_ENABLES_2 8
#define I830_CTXREG_AA 9
#define I830_CTXREG_FOGCOLOR 10
#define I830_CTXREG_BLENDCOLOR0 11
#define I830_CTXREG_BLENDCOLOR1 12
#define I830_CTXREG_VF 13
#define I830_CTXREG_VF2 14
#define I830_CTXREG_MCSB0 15
#define I830_CTXREG_MCSB1 16
#define I830_CTX_SETUP_SIZE 17
#define I830_STPREG_ST0 0
#define I830_STPREG_ST1 1
#define I830_STP_SETUP_SIZE 2
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
#define I830_TEXREG_TM0S0 1
#define I830_TEXREG_TM0S1 2
#define I830_TEXREG_TM0S2 3
#define I830_TEXREG_TM0S3 4
#define I830_TEXREG_TM0S4 5
#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */
#define I830_TEXREG_CUBE 7 /* _3DSTATE_MAP_SUBE */
#define I830_TEX_SETUP_SIZE 8
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
struct i830_texture_object
{
struct intel_texture_object intel;
GLuint Setup[I830_TEX_SETUP_SIZE];
};
#define I830_TEX_UNITS 4
struct i830_hw_state {
GLuint Ctx[I830_CTX_SETUP_SIZE];
GLuint Buffer[I830_DEST_SETUP_SIZE];
GLuint Stipple[I830_STP_SETUP_SIZE];
GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE];
GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE];
GLuint TexBlendWordsUsed[I830_TEX_UNITS];
GLuint emitted; /* I810_UPLOAD_* */
GLuint active;
};
struct i830_context
{
struct intel_context intel;
DECLARE_RENDERINPUTS(last_index_bitset);
struct i830_hw_state meta, initial, state, *current;
};
typedef struct i830_context *i830ContextPtr;
typedef struct i830_texture_object *i830TextureObjectPtr;
#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx))
#define I830_STATECHANGE(i830, flag) \
do { \
INTEL_FIREVERTICES( &i830->intel ); \
i830->state.emitted &= ~flag; \
} while (0)
#define I830_ACTIVESTATE(i830, flag, mode) \
do { \
INTEL_FIREVERTICES( &i830->intel ); \
if (mode) \
i830->state.active |= flag; \
else \
i830->state.active &= ~flag; \
} while (0)
/* i830_vtbl.c
*/
extern void
i830InitVtbl( i830ContextPtr i830 );
/* i830_context.c
*/
extern GLboolean
i830CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
/* i830_tex.c, i830_texstate.c
*/
extern void
i830UpdateTextureState( intelContextPtr intel );
extern void
i830InitTextureFuncs( struct dd_function_table *functions );
extern intelTextureObjectPtr
i830AllocTexObj( struct gl_texture_object *tObj );
/* i830_texblend.c
*/
extern GLuint i830SetTexEnvCombine(i830ContextPtr i830,
const struct gl_tex_env_combine_state * combine, GLint blendUnit,
GLuint texel_op, GLuint *state, const GLfloat *factor );
extern void
i830EmitTextureBlend( i830ContextPtr i830 );
/* i830_state.c
*/
extern void
i830InitStateFuncs( struct dd_function_table *functions );
extern void
i830EmitState( i830ContextPtr i830 );
extern void
i830InitState( i830ContextPtr i830 );
/* i830_metaops.c
*/
extern GLboolean
i830TryTextureReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels );
extern GLboolean
i830TryTextureDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
extern void
i830ClearWithTris( intelContextPtr intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
extern void
i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuf);
#endif

View File

@ -1,922 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "utils.h"
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "i830_context.h"
#include "i830_reg.h"
/* A large amount of state doesn't need to be uploaded.
*/
#define ACTIVE (I830_UPLOAD_INVARIENT | \
I830_UPLOAD_TEXBLEND(0) | \
I830_UPLOAD_STIPPLE | \
I830_UPLOAD_CTX | \
I830_UPLOAD_BUFFERS | \
I830_UPLOAD_TEX(0))
#define SET_STATE( i830, STATE ) \
do { \
i830->current->emitted = 0; \
i830->current = &i830->STATE; \
i830->current->emitted = 0; \
} while (0)
/* Operations where the 3D engine is decoupled temporarily from the
* current GL state and used for other purposes than simply rendering
* incoming triangles.
*/
static void set_initial_state( i830ContextPtr i830 )
{
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) );
i830->meta.active = ACTIVE;
i830->meta.emitted = 0;
}
static void set_no_depth_stencil_write( i830ContextPtr i830 )
{
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
*/
i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE;
i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE;
/* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
*/
i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
i830->meta.emitted &= ~I830_UPLOAD_CTX;
}
/* Set stencil unit to replace always with the reference value.
*/
static void set_stencil_replace( i830ContextPtr i830,
GLuint s_mask,
GLuint s_clear)
{
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE )
*/
i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
/* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
*/
i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
/* ctx->Driver.StencilMask( ctx, s_mask )
*/
i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK((s_mask&0xff)));
/* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
*/
i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
i830->meta.Ctx[I830_CTXREG_STENCILTST] |=
(ENABLE_STENCIL_PARMS |
STENCIL_FAIL_OP(STENCILOP_REPLACE) |
STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) |
STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE));
/* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 )
*/
i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
STENCIL_TEST_MASK(0xff));
i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
ENABLE_STENCIL_TEST_FUNC_MASK);
i830->meta.Ctx[I830_CTXREG_STENCILTST] |=
(ENABLE_STENCIL_REF_VALUE |
ENABLE_STENCIL_TEST_FUNC |
STENCIL_REF_VALUE((s_clear&0xff)) |
STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS));
i830->meta.emitted &= ~I830_UPLOAD_CTX;
}
static void set_color_mask( i830ContextPtr i830, GLboolean state )
{
const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) |
(1 << WRITEMASK_GREEN_SHIFT) |
(1 << WRITEMASK_BLUE_SHIFT) |
(1 << WRITEMASK_ALPHA_SHIFT));
i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask;
if (state) {
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |=
(i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask);
}
i830->meta.emitted &= ~I830_UPLOAD_CTX;
}
/* Installs a one-stage passthrough texture blend pipeline. Is there
* more that can be done to turn off texturing?
*/
static void set_no_texture( i830ContextPtr i830 )
{
static const struct gl_tex_env_combine_state comb = {
GL_NONE, GL_NONE,
{ GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, },
{ GL_SRC_COLOR, 0, 0 }, { GL_SRC_ALPHA, 0, 0 },
0, 0, 0, 0
};
i830->meta.TexBlendWordsUsed[0] =
i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0,
i830->meta.TexBlend[0], NULL);
i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE;
i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);
}
/* Set up a single element blend stage for 'replace' texturing with no
* funny ops.
*/
static void enable_texture_blend_replace( i830ContextPtr i830 )
{
static const struct gl_tex_env_combine_state comb = {
GL_REPLACE, GL_REPLACE,
{ GL_TEXTURE, GL_TEXTURE, GL_TEXTURE }, { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, },
{ GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR }, { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
0, 0, 1, 1
};
i830->meta.TexBlendWordsUsed[0] =
i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0,
i830->meta.TexBlend[0], NULL);
i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE;
i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0);
/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */
/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */
}
/* Set up an arbitary piece of memory as a rectangular texture
* (including the front or back buffer).
*/
static void set_tex_rect_source( i830ContextPtr i830,
GLuint offset,
GLuint width,
GLuint height,
GLuint pitch, /* in bytes */
GLuint textureFormat )
{
GLint numLevels = 1;
GLuint *setup = i830->meta.Tex[0];
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
(LOAD_TEXTURE_MAP0 << 0) | 4);
setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset);
setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) |
((width - 1) << TM0S1_WIDTH_SHIFT) |
textureFormat);
setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT));
setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD |
MAP_UNIT(0) |
ENABLE_TEXCOORD_PARAMS |
TEXCOORDS_ARE_IN_TEXELUNITS |
TEXCOORDTYPE_CARTESIAN |
ENABLE_ADDR_V_CNTL |
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
ENABLE_ADDR_U_CNTL |
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
i830->meta.emitted &= ~I830_UPLOAD_TEX(0);
}
/* Select between front and back draw buffers.
*/
static void set_draw_region( i830ContextPtr i830,
const intelRegion *region )
{
i830->meta.Buffer[I830_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = region->offset;
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
}
/* Setup an arbitary draw format, useful for targeting
* texture or agp memory.
*/
#if 0
static void set_draw_format( i830ContextPtr i830,
GLuint format,
GLuint depth_format)
{
i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
format |
DEPTH_IS_Z |
depth_format);
}
#endif
static void set_vertex_format( i830ContextPtr i830 )
{
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD |
VFT0_TEX_COUNT(1) |
VFT0_DIFFUSE |
VFT0_SPEC |
VFT0_XYZW);
i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD |
VFT1_TEX0_FMT(TEXCOORDFMT_2D) |
VFT1_TEX1_FMT(TEXCOORDFMT_2D) |
VFT1_TEX2_FMT(TEXCOORDFMT_2D) |
VFT1_TEX3_FMT(TEXCOORDFMT_2D));
i830->meta.emitted &= ~I830_UPLOAD_CTX;
}
static void draw_quad(i830ContextPtr i830,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1 )
{
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
PRIM3D_TRIFAN,
4*vertex_size,
vertex_size );
intelVertex tmp;
int i;
/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */
/* __FUNCTION__, */
/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */
/* initial vertex, left bottom */
tmp.v.x = x0;
tmp.v.y = y0;
tmp.v.z = 1.0;
tmp.v.w = 1.0;
tmp.v.color.red = red;
tmp.v.color.green = green;
tmp.v.color.blue = blue;
tmp.v.color.alpha = alpha;
tmp.v.specular.red = 0;
tmp.v.specular.green = 0;
tmp.v.specular.blue = 0;
tmp.v.specular.alpha = 0;
tmp.v.u0 = s0;
tmp.v.v0 = t0;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* right bottom */
vb += 8;
tmp.v.x = x1;
tmp.v.u0 = s1;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* right top */
vb += 8;
tmp.v.y = y1;
tmp.v.v0 = t1;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* left top */
vb += 8;
tmp.v.x = x0;
tmp.v.u0 = s0;
for (i = 0 ; i < 8 ; i++)
vb[i] = tmp.ui[i];
/* fprintf(stderr, "%s: DV1: %x\n", */
/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
}
static void draw_poly(i830ContextPtr i830,
GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha,
GLuint numVerts,
GLfloat verts[][2],
GLfloat texcoords[][2])
{
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
PRIM3D_TRIFAN,
numVerts * vertex_size,
vertex_size );
intelVertex tmp;
int i, k;
/* initial constant vertex fields */
tmp.v.z = 1.0;
tmp.v.w = 1.0;
tmp.v.color.red = red;
tmp.v.color.green = green;
tmp.v.color.blue = blue;
tmp.v.color.alpha = alpha;
tmp.v.specular.red = 0;
tmp.v.specular.green = 0;
tmp.v.specular.blue = 0;
tmp.v.specular.alpha = 0;
for (k = 0; k < numVerts; k++) {
tmp.v.x = verts[k][0];
tmp.v.y = verts[k][1];
tmp.v.u0 = texcoords[k][0];
tmp.v.v0 = texcoords[k][1];
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
vb += vertex_size;
}
}
void
i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean allFoo,
GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo)
{
i830ContextPtr i830 = I830_CONTEXT( intel );
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
GLint cx, cy, cw, ch;
GLboolean all;
INTEL_FIREVERTICES(intel);
SET_STATE( i830, meta );
set_initial_state( i830 );
/* set_no_texture( i830 ); */
set_vertex_format( i830 );
LOCK_HARDWARE(intel);
/* get clear bounds after locking */
cx = intel->ctx.DrawBuffer->_Xmin;
cy = intel->ctx.DrawBuffer->_Ymin;
cw = intel->ctx.DrawBuffer->_Xmax - cx;
ch = intel->ctx.DrawBuffer->_Ymax - cy;
all = (cw == intel->ctx.DrawBuffer->Width &&
ch == intel->ctx.DrawBuffer->Height);
if(!all) {
x0 = cx;
y0 = cy;
x1 = x0 + cw;
y1 = y0 + ch;
} else {
x0 = 0;
y0 = 0;
x1 = x0 + dPriv->w;
y1 = y0 + dPriv->h;
}
/* Don't do any clipping to screen - these are window coordinates.
* The active cliprects will be applied as for any other geometry.
*/
if(mask & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
set_draw_region( i830, &screen->front );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if(mask & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
set_draw_region( i830, &screen->back );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if(mask & BUFFER_BIT_STENCIL) {
set_stencil_replace( i830,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
set_color_mask( i830, GL_FALSE );
set_draw_region( i830, &screen->front );
draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
UNLOCK_HARDWARE(intel);
INTEL_FIREVERTICES(intel);
SET_STATE( i830, state );
}
#if 0
GLboolean
i830TryTextureReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelScreenPrivate *screen = i830->intel.intelScreen;
GLint pitch = pack->RowLength ? pack->RowLength : width;
__DRIdrawablePrivate *dPriv = i830->intel.driDrawable;
int textureFormat;
GLenum glTextureFormat;
int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels);
int destFormat, depthFormat, destPitch;
drm_clip_rect_t tmp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( ctx->_ImageTransferState ||
pack->SwapBytes ||
pack->LsbFirst ||
!pack->Invert) {
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
return GL_FALSE;
}
switch (screen->fbFormat) {
case DV_PF_565:
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
glTextureFormat = GL_RGB;
break;
case DV_PF_555:
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
glTextureFormat = GL_RGBA;
break;
case DV_PF_8888:
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
glTextureFormat = GL_RGBA;
break;
default:
fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__,
screen->fbFormat);
return GL_FALSE;
}
switch (type) {
case GL_UNSIGNED_SHORT_5_6_5:
if (format != GL_RGB) return GL_FALSE;
destFormat = COLR_BUF_RGB565;
depthFormat = DEPTH_FRMT_16_FIXED;
destPitch = pitch * 2;
break;
case GL_UNSIGNED_INT_8_8_8_8_REV:
if (format != GL_BGRA) return GL_FALSE;
destFormat = COLR_BUF_ARGB8888;
depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER;
destPitch = pitch * 4;
break;
default:
fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(type));
return GL_FALSE;
}
destFormat |= (0x02<<24);
/* fprintf(stderr, "type: %s destFormat: %x\n", */
/* _mesa_lookup_enum_by_nr(type), */
/* destFormat); */
intelFlush( ctx );
SET_STATE( i830, meta );
set_initial_state( i830 );
set_no_depth_stencil_write( i830 );
LOCK_HARDWARE( intel );
{
intelWaitForIdle( intel ); /* required by GL */
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
return GL_TRUE;
}
#if 0
/* FIXME -- Just emit the correct state
*/
if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH,
destPitch) != 0) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: setparam failed\n", __FUNCTION__);
return GL_FALSE;
}
#endif
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
/* Set the frontbuffer up as a large rectangular texture.
*/
set_tex_rect_source( i830,
src_offset,
screen->width,
screen->height,
screen->front.pitch,
textureFormat );
enable_texture_blend_replace( i830 );
/* Set the 3d engine to draw into the agp memory
*/
set_draw_region( i830, destOffset );
set_draw_format( i830, destFormat, depthFormat );
/* Draw a single quad, no cliprects:
*/
i830->intel.numClipRects = 1;
i830->intel.pClipRects = &tmp;
i830->intel.pClipRects[0].x1 = 0;
i830->intel.pClipRects[0].y1 = 0;
i830->intel.pClipRects[0].x2 = width;
i830->intel.pClipRects[0].y2 = height;
draw_quad( i830,
0, width, 0, height,
0, 255, 0, 0,
x, x+width, y, y+height );
intelWindowMoved( intel );
}
UNLOCK_HARDWARE( intel );
intelFinish( ctx ); /* required by GL */
SET_STATE( i830, state );
return GL_TRUE;
}
GLboolean
i830TryTextureDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
i830ContextPtr i830 = I830_CONTEXT(ctx);
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int textureFormat;
GLenum glTextureFormat;
int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int src_offset = intelAgpOffsetFromVirtual( intel, pixels );
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Todo -- upload images that aren't in agp space, then texture
* from them.
*/
if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) {
fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__);
return GL_FALSE;
}
/* Todo -- don't want to clobber all the drawing state like we do
* for readpixels -- most of this state can be handled just fine.
*/
if ( ctx->_ImageTransferState ||
unpack->SwapBytes ||
unpack->LsbFirst ||
ctx->Color.AlphaEnabled ||
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
ctx->Color.ColorLogicOpEnabled ||
ctx->Texture._EnabledUnits ||
ctx->Depth.OcclusionTest) {
fprintf(stderr, "%s: other tests failed\n", __FUNCTION__);
return GL_FALSE;
}
/* Todo -- remove these restrictions:
*/
if (ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != -1.0F)
return GL_FALSE;
switch (type) {
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
if (format != GL_BGRA) return GL_FALSE;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
glTextureFormat = GL_RGBA;
break;
case GL_UNSIGNED_SHORT_5_6_5:
if (format != GL_RGB) return GL_FALSE;
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
glTextureFormat = GL_RGB;
break;
case GL_UNSIGNED_SHORT_8_8_MESA:
if (format != GL_YCBCR_MESA) return GL_FALSE;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY
/* | TM0S1_COLORSPACE_CONVERSION */
);
glTextureFormat = GL_YCBCR_MESA;
break;
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
if (format != GL_YCBCR_MESA) return GL_FALSE;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL
/* | TM0S1_COLORSPACE_CONVERSION */
);
glTextureFormat = GL_YCBCR_MESA;
break;
case GL_UNSIGNED_INT_8_8_8_8_REV:
if (format != GL_BGRA) return GL_FALSE;
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
glTextureFormat = GL_RGBA;
break;
default:
fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__);
return GL_FALSE;
}
intelFlush( ctx );
SET_STATE( i830, meta );
LOCK_HARDWARE( intel );
{
intelWaitForIdle( intel ); /* required by GL */
y -= height; /* cope with pixel zoom */
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
SET_STATE(i830, state);
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
return GL_TRUE;
}
y = dPriv->h - y - height;
set_initial_state( i830 );
/* Set the pixel image up as a rectangular texture.
*/
set_tex_rect_source( i830,
src_offset,
width,
height,
pitch, /* XXXX!!!! -- /2 sometimes */
textureFormat );
enable_texture_blend_replace( i830 );
/* Draw to the current draw buffer:
*/
set_draw_offset( i830, dst_offset );
/* Draw a quad, use regular cliprects
*/
/* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */
draw_quad( i830,
x, x+width, y, y+height,
0, 255, 0, 0,
0, width, 0, height );
intelWindowMoved( intel );
}
UNLOCK_HARDWARE( intel );
intelFinish( ctx ); /* required by GL */
SET_STATE(i830, state);
return GL_TRUE;
}
#endif
/**
* Copy the window contents named by dPriv to the rotated (or reflected)
* color buffer.
* srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
*/
void
i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuf)
{
i830ContextPtr i830 = I830_CONTEXT( intel );
intelScreenPrivate *screen = intel->intelScreen;
const GLuint cpp = screen->cpp;
drm_clip_rect_t fullRect;
GLuint textureFormat, srcOffset, srcPitch;
const drm_clip_rect_t *clipRects;
int numClipRects;
int i;
int xOrig, yOrig;
int origNumClipRects;
drm_clip_rect_t *origRects;
/*
* set up hardware state
*/
intelFlush( &intel->ctx );
SET_STATE( i830, meta );
set_initial_state( i830 );
set_no_texture( i830 );
set_vertex_format( i830 );
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_FALSE );
LOCK_HARDWARE(intel);
/* save current drawing origin and cliprects (restored at end) */
xOrig = intel->drawX;
yOrig = intel->drawY;
origNumClipRects = intel->numClipRects;
origRects = intel->pClipRects;
if (!intel->numClipRects)
goto done;
/*
* set drawing origin, cliprects for full-screen access to rotated screen
*/
fullRect.x1 = 0;
fullRect.y1 = 0;
fullRect.x2 = screen->rotatedWidth;
fullRect.y2 = screen->rotatedHeight;
intel->drawX = 0;
intel->drawY = 0;
intel->numClipRects = 1;
intel->pClipRects = &fullRect;
set_draw_region( i830, &screen->rotated );
if (cpp == 4)
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
else
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
if (srcBuf == BUFFER_BIT_FRONT_LEFT) {
srcPitch = screen->front.pitch; /* in bytes */
srcOffset = screen->front.offset; /* bytes */
clipRects = dPriv->pClipRects;
numClipRects = dPriv->numClipRects;
}
else {
srcPitch = screen->back.pitch; /* in bytes */
srcOffset = screen->back.offset; /* bytes */
clipRects = dPriv->pBackClipRects;
numClipRects = dPriv->numBackClipRects;
}
/* set the whole screen up as a texture to avoid alignment issues */
set_tex_rect_source(i830,
srcOffset,
screen->width,
screen->height,
srcPitch,
textureFormat);
enable_texture_blend_replace(i830);
/*
* loop over the source window's cliprects
*/
for (i = 0; i < numClipRects; i++) {
int srcX0 = clipRects[i].x1;
int srcY0 = clipRects[i].y1;
int srcX1 = clipRects[i].x2;
int srcY1 = clipRects[i].y2;
GLfloat verts[4][2], tex[4][2];
int j;
/* build vertices for four corners of clip rect */
verts[0][0] = srcX0; verts[0][1] = srcY0;
verts[1][0] = srcX1; verts[1][1] = srcY0;
verts[2][0] = srcX1; verts[2][1] = srcY1;
verts[3][0] = srcX0; verts[3][1] = srcY1;
/* .. and texcoords */
tex[0][0] = srcX0; tex[0][1] = srcY0;
tex[1][0] = srcX1; tex[1][1] = srcY0;
tex[2][0] = srcX1; tex[2][1] = srcY1;
tex[3][0] = srcX0; tex[3][1] = srcY1;
/* transform coords to rotated screen coords */
for (j = 0; j < 4; j++) {
matrix23TransformCoordf(&screen->rotMatrix,
&verts[j][0], &verts[j][1]);
}
/* draw polygon to map source image to dest region */
draw_poly(i830, 255, 255, 255, 255, 4, verts, tex);
} /* cliprect loop */
intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE );
done:
/* restore original drawing origin and cliprects */
intel->drawX = xOrig;
intel->drawY = yOrig;
intel->numClipRects = origNumClipRects;
intel->pClipRects = origRects;
UNLOCK_HARDWARE(intel);
SET_STATE( i830, state );
}

View File

@ -1,641 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _I830_REG_H_
#define _I830_REG_H_
#include "intel_reg.h"
#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24))
#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16)
#define AA_LINE_ECAAR_WIDTH_0_5 0
#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14)
#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14)
#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14)
#define AA_LINE_REGION_WIDTH_ENABLE (1<<8)
#define AA_LINE_REGION_WIDTH_0_5 0
#define AA_LINE_REGION_WIDTH_1_0 (1<<6)
#define AA_LINE_REGION_WIDTH_2_0 (2<<6)
#define AA_LINE_REGION_WIDTH_4_0 (3<<6)
#define AA_LINE_ENABLE ((1<<1) | 1)
#define AA_LINE_DISABLE (1<<1)
#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
/* Dword 1 */
#define BUF_3D_ID_COLOR_BACK (0x3<<24)
#define BUF_3D_ID_DEPTH (0x7<<24)
#define BUF_3D_USE_FENCE (1<<23)
#define BUF_3D_TILED_SURFACE (1<<22)
#define BUF_3D_TILE_WALK_X 0
#define BUF_3D_TILE_WALK_Y (1<<21)
#define BUF_3D_PITCH(x) (((x)/4)<<2)
/* Dword 2 */
#define BUF_3D_ADDR(x) ((x) & ~0x3)
#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16))
#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \
((0x90+(stage))<<16))
#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16))
#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16))
#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16))
#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16))
#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16))
/* Dword 1 */
#define DSTORG_HORT_BIAS(x) ((x)<<20)
#define DSTORG_VERT_BIAS(x) ((x)<<16)
#define COLOR_4_2_2_CHNL_WRT_ALL 0
#define COLOR_4_2_2_CHNL_WRT_Y (1<<12)
#define COLOR_4_2_2_CHNL_WRT_CR (2<<12)
#define COLOR_4_2_2_CHNL_WRT_CB (3<<12)
#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12)
#define COLR_BUF_8BIT 0
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
#define DEPTH_IS_Z 0
#define DEPTH_IS_W (1<<6)
#define DEPTH_FRMT_16_FIXED 0
#define DEPTH_FRMT_16_FLOAT (1<<2)
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2)
#define VERT_LINE_STRIDE_1 (1<<1)
#define VERT_LINE_STRIDE_0 0
#define VERT_LINE_STRIDE_OFS_1 1
#define VERT_LINE_STRIDE_OFS_0 0
#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3)
/* Dword 1 */
#define DRAW_RECT_DIS_DEPTH_OFS (1<<30)
#define DRAW_DITHER_OFS_X(x) ((x)<<26)
#define DRAW_DITHER_OFS_Y(x) ((x)<<24)
/* Dword 2 */
#define DRAW_YMIN(x) ((x)<<16)
#define DRAW_XMIN(x) (x)
/* Dword 3 */
#define DRAW_YMAX(x) ((x)<<16)
#define DRAW_XMAX(x) (x)
/* Dword 4 */
#define DRAW_YORG(x) ((x)<<16)
#define DRAW_XORG(x) (x)
#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24))
#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22))
#define ENABLE_LOGIC_OP ((1<<23)|(1<<22))
#define DISABLE_LOGIC_OP (1<<23)
#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20))
#define DISABLE_STENCIL_TEST (1<<21)
#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10))
#define DISABLE_DEPTH_BIAS (1<<11)
#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8))
#define ENABLE_SPEC_ADD ((1<<9)|(1<<8))
#define DISABLE_SPEC_ADD (1<<9)
#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6))
#define ENABLE_FOG ((1<<7)|(1<<6))
#define DISABLE_FOG (1<<7)
#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4))
#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4))
#define DISABLE_ALPHA_TEST (1<<5)
#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2))
#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2))
#define DISABLE_COLOR_BLEND (1<<3)
#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1)
#define ENABLE_DEPTH_TEST ((1<<1)|1)
#define DISABLE_DEPTH_TEST (1<<1)
/* _3DSTATE_ENABLES_2, p138 */
#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24))
#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20))
#define DISABLE_STENCIL_WRITE (1<<21)
#define ENABLE_TEX_CACHE ((1<<17)|(1<<16))
#define DISABLE_TEX_CACHE (1<<17)
#define ENABLE_DITHER ((1<<9)|(1<<8))
#define DISABLE_DITHER (1<<9)
#define ENABLE_COLOR_MASK (1<<10)
#define WRITEMASK_ALPHA (1<<7)
#define WRITEMASK_ALPHA_SHIFT 7
#define WRITEMASK_RED (1<<6)
#define WRITEMASK_RED_SHIFT 6
#define WRITEMASK_GREEN (1<<5)
#define WRITEMASK_GREEN_SHIFT 5
#define WRITEMASK_BLUE (1<<4)
#define WRITEMASK_BLUE_SHIFT 4
#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7))
#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2))
#define DISABLE_COLOR_WRITE (1<<3)
#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3
#define ENABLE_DEPTH_WRITE ((1<<1)|1)
#define DISABLE_DEPTH_WRITE (1<<1)
/* _3DSTATE_FOG_COLOR, p139 */
#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24))
#define FOG_COLOR_RED(x) ((x)<<16)
#define FOG_COLOR_GREEN(x) ((x)<<8)
#define FOG_COLOR_BLUE(x) (x)
/* _3DSTATE_FOG_MODE, p140 */
#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2)
/* Dword 1 */
#define FOGFUNC_ENABLE (1<<31)
#define FOGFUNC_VERTEX 0
#define FOGFUNC_PIXEL_EXP (1<<28)
#define FOGFUNC_PIXEL_EXP2 (2<<28)
#define FOGFUNC_PIXEL_LINEAR (3<<28)
#define FOGSRC_INDEX_Z (1<<27)
#define FOGSRC_INDEX_W ((1<<27)|(1<<25))
#define FOG_LINEAR_CONST (1<<24)
#define FOG_CONST_1(x) ((x)<<4)
#define ENABLE_FOG_DENSITY (1<<23)
/* Dword 2 */
#define FOG_CONST_2(x) (x)
/* Dword 3 */
#define FOG_DENSITY(x) (x)
/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */
#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24))
#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22))
#define DISABLE_INDPT_ALPHA_BLEND (1<<23)
#define ALPHA_BLENDFUNC_MASK 0x3f0000
#define ENABLE_ALPHA_BLENDFUNC (1<<21)
#define ABLENDFUNC_ADD 0
#define ABLENDFUNC_SUB (1<<16)
#define ABLENDFUNC_RVSE_SUB (2<<16)
#define ABLENDFUNC_MIN (3<<16)
#define ABLENDFUNC_MAX (4<<16)
#define SRC_DST_ABLEND_MASK 0xfff
#define ENABLE_SRC_ABLEND_FACTOR (1<<11)
#define SRC_ABLEND_FACT(x) ((x)<<6)
#define ENABLE_DST_ABLEND_FACTOR (1<<5)
#define DST_ABLEND_FACT(x) (x)
/* _3DSTATE_MAP_BLEND_ARG, p152 */
#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20))
#define TEXPIPE_COLOR 0
#define TEXPIPE_ALPHA (1<<18)
#define TEXPIPE_KILL (2<<18)
#define TEXBLEND_ARG0 0
#define TEXBLEND_ARG1 (1<<15)
#define TEXBLEND_ARG2 (2<<15)
#define TEXBLEND_ARG3 (3<<15)
#define TEXBLENDARG_MODIFY_PARMS (1<<6)
#define TEXBLENDARG_REPLICATE_ALPHA (1<<5)
#define TEXBLENDARG_INV_ARG (1<<4)
#define TEXBLENDARG_ONE 0
#define TEXBLENDARG_FACTOR 0x01
#define TEXBLENDARG_ACCUM 0x02
#define TEXBLENDARG_DIFFUSE 0x03
#define TEXBLENDARG_SPEC 0x04
#define TEXBLENDARG_CURRENT 0x05
#define TEXBLENDARG_TEXEL0 0x06
#define TEXBLENDARG_TEXEL1 0x07
#define TEXBLENDARG_TEXEL2 0x08
#define TEXBLENDARG_TEXEL3 0x09
#define TEXBLENDARG_FACTOR_N 0x0e
/* _3DSTATE_MAP_BLEND_OP, p155 */
#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20))
#if 0
# define TEXPIPE_COLOR 0
# define TEXPIPE_ALPHA (1<<18)
# define TEXPIPE_KILL (2<<18)
#endif
#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17)
#define TEXOP_OUTPUT_CURRENT 0
#define TEXOP_OUTPUT_ACCUM (1<<15)
#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11))
#define DISABLE_TEX_CNTRL_STAGE (1<<12)
#define TEXOP_SCALE_SHIFT 9
#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT)
#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT)
#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT)
#define TEXOP_MODIFY_PARMS (1<<8)
#define TEXOP_LAST_STAGE (1<<7)
#define TEXBLENDOP_KILLPIXEL 0x02
#define TEXBLENDOP_ARG1 0x01
#define TEXBLENDOP_ARG2 0x02
#define TEXBLENDOP_MODULATE 0x03
#define TEXBLENDOP_ADD 0x06
#define TEXBLENDOP_ADDSIGNED 0x07
#define TEXBLENDOP_BLEND 0x08
#define TEXBLENDOP_BLEND_AND_ADD 0x09
#define TEXBLENDOP_SUBTRACT 0x0a
#define TEXBLENDOP_DOT3 0x0b
#define TEXBLENDOP_DOT4 0x0c
#define TEXBLENDOP_MODULATE_AND_ADD 0x0d
#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e
#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f
/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */
/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */
#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16))
#define DISABLE_TEX_TRANSFORM (1<<28)
#define TEXTURE_SET(x) (x<<29)
#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16))
#define DISABLE_VIEWPORT_TRANSFORM (1<<31)
#define DISABLE_PERSPECTIVE_DIVIDE (1<<29)
/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */
#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12))
#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8))
#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4))
#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1)
#define TEXBIND_SET3(x) ((x)<<12)
#define TEXBIND_SET2(x) ((x)<<8)
#define TEXBIND_SET1(x) ((x)<<4)
#define TEXBIND_SET0(x) (x)
#define TEXCOORDSRC_KEEP 0
#define TEXCOORDSRC_DEFAULT 0x01
#define TEXCOORDSRC_VTXSET_0 0x08
#define TEXCOORDSRC_VTXSET_1 0x09
#define TEXCOORDSRC_VTXSET_2 0x0a
#define TEXCOORDSRC_VTXSET_3 0x0b
#define TEXCOORDSRC_VTXSET_4 0x0c
#define TEXCOORDSRC_VTXSET_5 0x0d
#define TEXCOORDSRC_VTXSET_6 0x0e
#define TEXCOORDSRC_VTXSET_7 0x0f
#define MAP_UNIT(unit) ((unit)<<16)
#define MAP_UNIT_MASK (0x7<<16)
/* _3DSTATE_MAP_COORD_SETS, p164 */
#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19))
#define ENABLE_TEXCOORD_PARAMS (1<<15)
#define TEXCOORDS_ARE_NORMAL (1<<14)
#define TEXCOORDS_ARE_IN_TEXELUNITS 0
#define TEXCOORDTYPE_CARTESIAN 0
#define TEXCOORDTYPE_HOMOGENEOUS (1<<11)
#define TEXCOORDTYPE_VECTOR (2<<11)
#define TEXCOORDTYPE_MASK (0x7<<11)
#define ENABLE_ADDR_V_CNTL (1<<7)
#define ENABLE_ADDR_U_CNTL (1<<3)
#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4)
#define TEXCOORD_ADDR_U_MODE(x) (x)
#define TEXCOORDMODE_WRAP 0
#define TEXCOORDMODE_MIRROR 1
#define TEXCOORDMODE_CLAMP 2
#define TEXCOORDMODE_WRAP_SHORTEST 3
#define TEXCOORDMODE_CLAMP_BORDER 4
#define TEXCOORD_ADDR_V_MASK 0x70
#define TEXCOORD_ADDR_U_MASK 0x7
/* _3DSTATE_MAP_CUBE, p168 TODO */
#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19))
#define CUBE_NEGX_ENABLE (1<<5)
#define CUBE_POSX_ENABLE (1<<4)
#define CUBE_NEGY_ENABLE (1<<3)
#define CUBE_POSY_ENABLE (1<<2)
#define CUBE_NEGZ_ENABLE (1<<1)
#define CUBE_POSZ_ENABLE (1<<0)
/* _3DSTATE_MODES_1, p190 */
#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24))
#define BLENDFUNC_MASK 0x3f0000
#define ENABLE_COLR_BLND_FUNC (1<<21)
#define BLENDFUNC_ADD 0
#define BLENDFUNC_SUB (1<<16)
#define BLENDFUNC_RVRSE_SUB (2<<16)
#define BLENDFUNC_MIN (3<<16)
#define BLENDFUNC_MAX (4<<16)
#define SRC_DST_BLND_MASK 0xfff
#define ENABLE_SRC_BLND_FACTOR (1<<11)
#define ENABLE_DST_BLND_FACTOR (1<<5)
#define SRC_BLND_FACT(x) ((x)<<6)
#define DST_BLND_FACT(x) (x)
/* _3DSTATE_MODES_2, p192 */
#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24))
#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22)
#define GLOBAL_DEPTH_BIAS(x) ((x)<<14)
#define ENABLE_ALPHA_TEST_FUNC (1<<13)
#define ENABLE_ALPHA_REF_VALUE (1<<8)
#define ALPHA_TEST_FUNC(x) ((x)<<9)
#define ALPHA_REF_VALUE(x) (x)
#define ALPHA_TEST_REF_MASK 0x3fff
/* _3DSTATE_MODES_3, p193 */
#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24))
#define DEPTH_TEST_FUNC_MASK 0x1f0000
#define ENABLE_DEPTH_TEST_FUNC (1<<20)
/* Uses COMPAREFUNC */
#define DEPTH_TEST_FUNC(x) ((x)<<16)
#define ENABLE_ALPHA_SHADE_MODE (1<<11)
#define ENABLE_FOG_SHADE_MODE (1<<9)
#define ENABLE_SPEC_SHADE_MODE (1<<7)
#define ENABLE_COLOR_SHADE_MODE (1<<5)
#define ALPHA_SHADE_MODE(x) ((x)<<10)
#define FOG_SHADE_MODE(x) ((x)<<8)
#define SPEC_SHADE_MODE(x) ((x)<<6)
#define COLOR_SHADE_MODE(x) ((x)<<4)
#define CULLMODE_MASK 0xf
#define ENABLE_CULL_MODE (1<<3)
#define CULLMODE_BOTH 0
#define CULLMODE_NONE 1
#define CULLMODE_CW 2
#define CULLMODE_CCW 3
#define SHADE_MODE_LINEAR 0
#define SHADE_MODE_FLAT 0x1
/* _3DSTATE_MODES_4, p195 */
#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24))
#define ENABLE_LOGIC_OP_FUNC (1<<23)
#define LOGIC_OP_FUNC(x) ((x)<<18)
#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21))
#define LOGICOP_CLEAR 0
#define LOGICOP_NOR 0x1
#define LOGICOP_AND_INV 0x2
#define LOGICOP_COPY_INV 0x3
#define LOGICOP_AND_RVRSE 0x4
#define LOGICOP_INV 0x5
#define LOGICOP_XOR 0x6
#define LOGICOP_NAND 0x7
#define LOGICOP_AND 0x8
#define LOGICOP_EQUIV 0x9
#define LOGICOP_NOOP 0xa
#define LOGICOP_OR_INV 0xb
#define LOGICOP_COPY 0xc
#define LOGICOP_OR_RVRSE 0xd
#define LOGICOP_OR 0xe
#define LOGICOP_SET 0xf
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
#define ENABLE_STENCIL_TEST_MASK (1<<17)
#define STENCIL_TEST_MASK(x) ((x)<<8)
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
/* _3DSTATE_MODES_5, p196 */
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
#define ENABLE_SPRITE_POINT_TEX (1<<23)
#define SPRITE_POINT_TEX_ON (1<<22)
#define SPRITE_POINT_TEX_OFF 0
#define FLUSH_RENDER_CACHE (1<<18)
#define FLUSH_TEXTURE_CACHE (1<<16)
#define FIXED_LINE_WIDTH_MASK 0xfc00
#define ENABLE_FIXED_LINE_WIDTH (1<<15)
#define FIXED_LINE_WIDTH(x) ((x)<<10)
#define FIXED_POINT_WIDTH_MASK 0x3ff
#define ENABLE_FIXED_POINT_WIDTH (1<<9)
#define FIXED_POINT_WIDTH(x) (x)
/* _3DSTATE_RASTERIZATION_RULES, p198 */
#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24))
#define ENABLE_POINT_RASTER_RULE (1<<15)
#define OGL_POINT_RASTER_RULE (1<<13)
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
#define TRI_STRIP_PROVOKE_VRTX(x) (x)
/* _3DSTATE_SCISSOR_ENABLE, p200 */
#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19))
#define ENABLE_SCISSOR_RECT ((1<<1) | 1)
#define DISABLE_SCISSOR_RECT (1<<1)
/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */
#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1)
/* Dword 1 */
#define SCISSOR_RECT_0_YMIN(x) ((x)<<16)
#define SCISSOR_RECT_0_XMIN(x) (x)
/* Dword 2 */
#define SCISSOR_RECT_0_YMAX(x) ((x)<<16)
#define SCISSOR_RECT_0_XMAX(x) (x)
/* _3DSTATE_STENCIL_TEST, p202 */
#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24))
#define ENABLE_STENCIL_PARMS (1<<23)
#define STENCIL_OPS_MASK (0xffc000)
#define STENCIL_FAIL_OP(x) ((x)<<20)
#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17)
#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14)
#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9))
#define ENABLE_STENCIL_TEST_FUNC (1<<13)
/* Uses COMPAREFUNC */
#define STENCIL_TEST_FUNC(x) ((x)<<9)
#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff)
#define ENABLE_STENCIL_REF_VALUE (1<<8)
#define STENCIL_REF_VALUE(x) (x)
/* _3DSTATE_VERTEX_FORMAT, p204 */
#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24))
#define VFT0_POINT_WIDTH (1<<12)
#define VFT0_TEX_COUNT_MASK (7<<8)
#define VFT0_TEX_COUNT_SHIFT 8
#define VFT0_TEX_COUNT(x) ((x)<<8)
#define VFT0_SPEC (1<<7)
#define VFT0_DIFFUSE (1<<6)
#define VFT0_DEPTH_OFFSET (1<<5)
#define VFT0_XYZ (1<<1)
#define VFT0_XYZW (2<<1)
#define VFT0_XY (3<<1)
#define VFT0_XYW (4<<1)
#define VFT0_XYZW_MASK (7<<1)
/* _3DSTATE_VERTEX_FORMAT_2, p206 */
#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24))
#define VFT1_TEX7_FMT(x) ((x)<<14)
#define VFT1_TEX6_FMT(x) ((x)<<12)
#define VFT1_TEX5_FMT(x) ((x)<<10)
#define VFT1_TEX4_FMT(x) ((x)<<8)
#define VFT1_TEX3_FMT(x) ((x)<<6)
#define VFT1_TEX2_FMT(x) ((x)<<4)
#define VFT1_TEX1_FMT(x) ((x)<<2)
#define VFT1_TEX0_FMT(x) (x)
#define VFT1_TEX0_MASK 3
#define VFT1_TEX1_SHIFT 2
#define TEXCOORDFMT_2D 0
#define TEXCOORDFMT_3D 1
#define TEXCOORDFMT_4D 2
#define TEXCOORDFMT_1D 3
/*New stuff picked up along the way */
#define MLC_LOD_BIAS_MASK ((1<<7)-1)
/* _3DSTATE_VERTEX_TRANSFORM, p207 */
#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0)
#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6)
/* Dword 1 */
#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30))
#define DISABLE_VIEWPORT_TRANSFORM (1<<31)
#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28))
#define DISABLE_PERSP_DIVIDE (1<<29)
#define VRTX_TRANS_LOAD_MATRICES 0x7421
#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000
/* Dword 2 -> 7 are matrix elements */
/* _3DSTATE_W_STATE, p209 */
#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1)
/* Dword 1 */
#define MAGIC_W_STATE_DWORD1 0x00000008
/* Dword 2 */
#define WFAR_VALUE(x) (x)
/* Stipple command, carried over from the i810, apparently:
*/
#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
#define ST1_ENABLE (1<<16)
#define ST1_MASK (0xffff)
#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
#define LOAD_TEXTURE_MAP0 (1<<11)
#define LOAD_GLOBAL_COLOR_FACTOR (1<<6)
#define TM0S0_ADDRESS_MASK 0xfffffffc
#define TM0S0_USE_FENCE (1<<1)
#define TM0S1_HEIGHT_SHIFT 21
#define TM0S1_WIDTH_SHIFT 10
#define TM0S1_PALETTE_SELECT (1<<9)
#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6)
#define TM0S1_MAPSURF_FORMAT_SHIFT 6
#define MAPSURF_8BIT_INDEXED (0<<6)
#define MAPSURF_8BIT (1<<6)
#define MAPSURF_16BIT (2<<6)
#define MAPSURF_32BIT (3<<6)
#define MAPSURF_411 (4<<6)
#define MAPSURF_422 (5<<6)
#define MAPSURF_COMPRESSED (6<<6)
#define MAPSURF_4BIT_INDEXED (7<<6)
#define TM0S1_MT_FORMAT_MASK (0x7 << 3)
#define TM0S1_MT_FORMAT_SHIFT 3
#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */
#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */
#define MT_8BIT_IDX_ARGB1555 (1<<3)
#define MT_8BIT_IDX_ARGB4444 (2<<3)
#define MT_8BIT_IDX_AY88 (3<<3)
#define MT_8BIT_IDX_ABGR8888 (4<<3)
#define MT_8BIT_IDX_BUMP_88DVDU (5<<3)
#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3)
#define MT_8BIT_IDX_ARGB8888 (7<<3)
#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */
#define MT_8BIT_L8 (1<<3)
#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */
#define MT_16BIT_ARGB1555 (1<<3)
#define MT_16BIT_ARGB4444 (2<<3)
#define MT_16BIT_AY88 (3<<3)
#define MT_16BIT_DIB_ARGB1555_8888 (4<<3)
#define MT_16BIT_BUMP_88DVDU (5<<3)
#define MT_16BIT_BUMP_655LDVDU (6<<3)
#define MT_16BIT_DIB_RGB565_8888 (7<<3)
#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */
#define MT_32BIT_ABGR8888 (1<<3)
#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3)
#define MT_32BIT_DIB_8888 (7<<3)
#define MT_411_YUV411 (0<<3) /* SURFACE_411 */
#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */
#define MT_422_YCRCB_NORMAL (1<<3)
#define MT_422_YCRCB_SWAPUV (2<<3)
#define MT_422_YCRCB_SWAPUVY (3<<3)
#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */
#define MT_COMPRESS_DXT2_3 (1<<3)
#define MT_COMPRESS_DXT4_5 (2<<3)
#define MT_COMPRESS_FXT1 (3<<3)
#define TM0S1_COLORSPACE_CONVERSION (1 << 2)
#define TM0S1_TILED_SURFACE (1 << 1)
#define TM0S1_TILE_WALK (1 << 0)
#define TM0S2_PITCH_SHIFT 21
#define TM0S2_CUBE_FACE_ENA_SHIFT 15
#define TM0S2_CUBE_FACE_ENA_MASK (1<<15)
#define TM0S2_MAP_FORMAT (1<<14)
#define TM0S2_VERTICAL_LINE_STRIDE (1<<13)
#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12)
#define TM0S2_OUTPUT_CHAN_SHIFT 10
#define TM0S2_OUTPUT_CHAN_MASK (3<<10)
#define TM0S3_MIP_FILTER_MASK (0x3<<30)
#define TM0S3_MIP_FILTER_SHIFT 30
#define MIPFILTER_NONE 0
#define MIPFILTER_NEAREST 1
#define MIPFILTER_LINEAR 3
#define TM0S3_MAG_FILTER_MASK (0x3<<28)
#define TM0S3_MAG_FILTER_SHIFT 28
#define TM0S3_MIN_FILTER_MASK (0x3<<26)
#define TM0S3_MIN_FILTER_SHIFT 26
#define FILTER_NEAREST 0
#define FILTER_LINEAR 1
#define FILTER_ANISOTROPIC 2
#define TM0S3_LOD_BIAS_SHIFT 17
#define TM0S3_LOD_BIAS_MASK (0x1ff<<17)
#define TM0S3_MAX_MIP_SHIFT 9
#define TM0S3_MAX_MIP_MASK (0xff<<9)
#define TM0S3_MIN_MIP_SHIFT 3
#define TM0S3_MIN_MIP_MASK (0x3f<<3)
#define TM0S3_KILL_PIXEL (1<<2)
#define TM0S3_KEYED_FILTER (1<<1)
#define TM0S3_CHROMA_KEY (1<<0)
/* _3DSTATE_MAP_TEXEL_STREAM, p188 */
#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19))
#define DISABLE_TEX_STREAM_BUMP (1<<12)
#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11))
#define TEX_MODIFY_UNIT_0 0
#define TEX_MODIFY_UNIT_1 (1<<8)
#define ENABLE_TEX_STREAM_COORD_SET (1<<7)
#define TEX_STREAM_COORD_SET(x) ((x)<<4)
#define ENABLE_TEX_STREAM_MAP_IDX (1<<3)
#define TEX_STREAM_MAP_IDX(x) (x)
#define MI_FLUSH ((0<<29)|(4<<23))
#define FLUSH_MAP_CACHE (1<<0)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,356 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "simple_list.h"
#include "enums.h"
#include "image.h"
#include "texstore.h"
#include "texformat.h"
#include "texmem.h"
#include "swrast/swrast.h"
#include "mm.h"
#include "intel_ioctl.h"
#include "i830_context.h"
#include "i830_reg.h"
/**
* Set the texture wrap modes.
*
* The i830M (and related graphics cores) do not support GL_CLAMP. The Intel
* drivers for "other operating systems" implement GL_CLAMP as
* GL_CLAMP_TO_EDGE, so the same is done here.
*
* \param t Texture object whose wrap modes are to be set
* \param swrap Wrap mode for the \a s texture coordinate
* \param twrap Wrap mode for the \a t texture coordinate
*/
static void i830SetTexWrapping(i830TextureObjectPtr tex,
GLenum swrap,
GLenum twrap)
{
tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK);
switch( swrap ) {
case GL_REPEAT:
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP);
break;
case GL_CLAMP:
case GL_CLAMP_TO_EDGE:
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP);
break;
case GL_CLAMP_TO_BORDER:
tex->Setup[I830_TEXREG_MCS] |=
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER);
break;
case GL_MIRRORED_REPEAT:
tex->Setup[I830_TEXREG_MCS] |=
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR);
break;
default:
break;
}
switch( twrap ) {
case GL_REPEAT:
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP);
break;
case GL_CLAMP:
case GL_CLAMP_TO_EDGE:
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP);
break;
case GL_CLAMP_TO_BORDER:
tex->Setup[I830_TEXREG_MCS] |=
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER);
break;
case GL_MIRRORED_REPEAT:
tex->Setup[I830_TEXREG_MCS] |=
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR);
break;
default:
break;
}
}
/**
* Set the texture magnification and minification modes.
*
* \param t Texture whose filter modes are to be set
* \param minf Texture minification mode
* \param magf Texture magnification mode
* \param bias LOD bias for this texture unit.
*/
static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf,
GLfloat maxanisotropy )
{
int minFilt = 0, mipFilt = 0, magFilt = 0;
if(INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( maxanisotropy > 1.0 ) {
minFilt = FILTER_ANISOTROPIC;
magFilt = FILTER_ANISOTROPIC;
}
else {
switch (minf) {
case GL_NEAREST:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_NONE;
break;
case GL_LINEAR:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_NONE;
break;
case GL_NEAREST_MIPMAP_NEAREST:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_NEAREST;
break;
case GL_LINEAR_MIPMAP_NEAREST:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_LINEAR;
break;
case GL_LINEAR_MIPMAP_LINEAR:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_LINEAR;
break;
default:
break;
}
switch (magf) {
case GL_NEAREST:
magFilt = FILTER_NEAREST;
break;
case GL_LINEAR:
magFilt = FILTER_LINEAR;
break;
default:
break;
}
}
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK;
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK;
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK;
t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
(mipFilt << TM0S3_MIP_FILTER_SHIFT) |
(magFilt << TM0S3_MAG_FILTER_SHIFT));
}
static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
{
if(INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
t->Setup[I830_TEXREG_TM0S4] =
INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]);
}
/**
* Allocate space for and load the mesa images into the texture memory block.
* This will happen before drawing with a new texture, or drawing with a
* texture after it was swapped out or teximaged again.
*/
intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
{
i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object );
if ( !t )
return NULL;
texObj->DriverData = t;
t->intel.base.tObj = texObj;
t->intel.dirty = I830_UPLOAD_TEX_ALL;
make_empty_list( &t->intel.base );
t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */
t->Setup[I830_TEXREG_TM0S0] = 0;
t->Setup[I830_TEXREG_TM0S1] = 0;
t->Setup[I830_TEXREG_TM0S2] = 0;
t->Setup[I830_TEXREG_TM0S3] = 0;
t->Setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD |
MAP_UNIT(0) |
ENABLE_TEXCOORD_PARAMS |
TEXCOORDS_ARE_NORMAL |
TEXCOORDTYPE_CARTESIAN |
ENABLE_ADDR_V_CNTL |
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
ENABLE_ADDR_U_CNTL |
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter,
texObj->MaxAnisotropy );
i830SetTexBorderColor( t, texObj->_BorderChan );
return &t->intel;
}
static void i830TexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
{
i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
if (!t)
return;
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter,
tObj->MaxAnisotropy);
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
break;
case GL_TEXTURE_BORDER_COLOR:
i830SetTexBorderColor( t, tObj->_BorderChan );
break;
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MAX_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
/* The i830 and its successors can do a lot of this without
* reloading the textures. A project for someone?
*/
intelFlush( ctx );
driSwapOutTextureObject( (driTextureObject *) t );
break;
default:
return;
}
t->intel.dirty = I830_UPLOAD_TEX_ALL;
}
static void i830TexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
i830ContextPtr i830 = I830_CONTEXT( ctx );
GLuint unit = ctx->Texture.CurrentUnit;
switch (pname) {
case GL_TEXTURE_ENV_COLOR:
#if 0
{
GLubyte r, g, b, a;
GLuint col;
UNCLAMPED_FLOAT_TO_UBYTE(r, param[RCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(g, param[GCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(b, param[BCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(a, param[ACOMP]);
col = ((a << 24) | (r << 16) | (g << 8) | b);
if (col != i830->state.TexEnv[unit][I830_TEXENVREG_COL1]) {
I830_STATECHANGE(i830, I830_UPLOAD_TEXENV);
i830->state.TexEnv[unit][I830_TEXENVREG_COL1] = col;
}
break;
}
#endif
case GL_TEXTURE_ENV_MODE:
case GL_COMBINE_RGB:
case GL_COMBINE_ALPHA:
case GL_SOURCE0_RGB:
case GL_SOURCE1_RGB:
case GL_SOURCE2_RGB:
case GL_SOURCE0_ALPHA:
case GL_SOURCE1_ALPHA:
case GL_SOURCE2_ALPHA:
case GL_OPERAND0_RGB:
case GL_OPERAND1_RGB:
case GL_OPERAND2_RGB:
case GL_OPERAND0_ALPHA:
case GL_OPERAND1_ALPHA:
case GL_OPERAND2_ALPHA:
case GL_RGB_SCALE:
case GL_ALPHA_SCALE:
break;
case GL_TEXTURE_LOD_BIAS: {
int b = (int) ((*param) * 16.0);
if (b > 63) b = 63;
if (b < -64) b = -64;
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
i830->state.Tex[unit][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
i830->state.Tex[unit][I830_TEXREG_TM0S3] |=
((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK);
break;
}
default:
break;
}
}
static void i830BindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj )
{
i830TextureObjectPtr tex;
if (!texObj->DriverData)
i830AllocTexObj( texObj );
tex = (i830TextureObjectPtr)texObj->DriverData;
}
void i830InitTextureFuncs( struct dd_function_table *functions )
{
functions->BindTexture = i830BindTexture;
functions->TexEnv = i830TexEnv;
functions->TexParameter = i830TexParameter;
}

View File

@ -1,465 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
#include "texstore.h"
#include "mm.h"
#include "intel_screen.h"
#include "intel_ioctl.h"
#include "intel_tex.h"
#include "i830_context.h"
#include "i830_reg.h"
/* ================================================================
* Texture combine functions
*/
static GLuint pass_through( GLuint *state, GLuint blendUnit )
{
state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
TEXPIPE_COLOR |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXBLENDOP_ARG1);
state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
TEXPIPE_ALPHA |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
TEXOP_SCALE_1X |
TEXOP_MODIFY_PARMS |
TEXBLENDOP_ARG1);
state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
TEXPIPE_COLOR |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
TEXPIPE_ALPHA |
TEXBLEND_ARG1 |
TEXBLENDARG_MODIFY_PARMS |
TEXBLENDARG_CURRENT);
return 4;
}
static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count,
const GLfloat *factor )
{
GLubyte r, g, b, a;
GLuint col;
if (0)
fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n",
blendUnit, factor[0], factor[1], factor[2], factor[3]);
UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]);
UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]);
UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]);
UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]);
col = ((a << 24) | (r << 16) | (g << 8) | b);
state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit);
state[count++] = col;
return count;
}
static __inline__ GLuint GetTexelOp(GLint unit)
{
switch(unit) {
case 0: return TEXBLENDARG_TEXEL0;
case 1: return TEXBLENDARG_TEXEL1;
case 2: return TEXBLENDARG_TEXEL2;
case 3: return TEXBLENDARG_TEXEL3;
default: return TEXBLENDARG_TEXEL0;
}
}
/**
* Calculate the hardware instuctions to setup the current texture enviromnemt
* settings. Since \c gl_texture_unit::_CurrentCombine is used, both
* "classic" texture enviroments and GL_ARB_texture_env_combine type texture
* environments are treated identically.
*
* \todo
* This function should return \c GLboolean. When \c GL_FALSE is returned,
* it means that an environment is selected that the hardware cannot do. This
* is the way the Radeon and R200 drivers work.
*
* \todo
* Looking at i830_3d_regs.h, it seems the i830 can do part of
* GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and
* \c GL_ZERO as combine inputs (which the code already supports). It can
* also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating
* partial support for the extension?
*/
GLuint
i830SetTexEnvCombine(i830ContextPtr i830,
const struct gl_tex_env_combine_state * combine,
GLint blendUnit,
GLuint texel_op,
GLuint *state,
const GLfloat *factor )
{
const GLuint numColorArgs = combine->_NumArgsRGB;
const GLuint numAlphaArgs = combine->_NumArgsA;
GLuint blendop;
GLuint ablendop;
GLuint args_RGB[3];
GLuint args_A[3];
GLuint rgb_shift;
GLuint alpha_shift;
GLboolean need_factor = 0;
int i;
unsigned used;
static const GLuint tex_blend_rgb[3] = {
TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS,
TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS,
TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS,
};
static const GLuint tex_blend_a[3] = {
TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS,
TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS,
TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS,
};
if(INTEL_DEBUG&DEBUG_TEXTURE)
fprintf(stderr, "%s\n", __FUNCTION__);
/* The EXT version of the DOT3 extension does not support the
* scale factor, but the ARB version (and the version in OpenGL
* 1.3) does.
*/
switch (combine->ModeRGB) {
case GL_DOT3_RGB_EXT:
alpha_shift = combine->ScaleShiftA;
rgb_shift = 0;
break;
case GL_DOT3_RGBA_EXT:
alpha_shift = 0;
rgb_shift = 0;
break;
default:
rgb_shift = combine->ScaleShiftRGB;
alpha_shift = combine->ScaleShiftA;
break;
}
switch(combine->ModeRGB) {
case GL_REPLACE:
blendop = TEXBLENDOP_ARG1;
break;
case GL_MODULATE:
blendop = TEXBLENDOP_MODULATE;
break;
case GL_ADD:
blendop = TEXBLENDOP_ADD;
break;
case GL_ADD_SIGNED:
blendop = TEXBLENDOP_ADDSIGNED;
break;
case GL_INTERPOLATE:
blendop = TEXBLENDOP_BLEND;
break;
case GL_SUBTRACT:
blendop = TEXBLENDOP_SUBTRACT;
break;
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGB:
blendop = TEXBLENDOP_DOT3;
break;
case GL_DOT3_RGBA_EXT:
case GL_DOT3_RGBA:
blendop = TEXBLENDOP_DOT3;
break;
default:
return pass_through( state, blendUnit );
}
blendop |= (rgb_shift << TEXOP_SCALE_SHIFT);
/* Handle RGB args */
for(i = 0; i < 3; i++) {
switch(combine->SourceRGB[i]) {
case GL_TEXTURE:
args_RGB[i] = texel_op;
break;
case GL_TEXTURE0:
case GL_TEXTURE1:
case GL_TEXTURE2:
case GL_TEXTURE3:
args_RGB[i] = GetTexelOp( combine->SourceRGB[i] - GL_TEXTURE0 );
break;
case GL_CONSTANT:
args_RGB[i] = TEXBLENDARG_FACTOR_N;
need_factor = 1;
break;
case GL_PRIMARY_COLOR:
args_RGB[i] = TEXBLENDARG_DIFFUSE;
break;
case GL_PREVIOUS:
args_RGB[i] = TEXBLENDARG_CURRENT;
break;
default:
return pass_through( state, blendUnit );
}
switch(combine->OperandRGB[i]) {
case GL_SRC_COLOR:
args_RGB[i] |= 0;
break;
case GL_ONE_MINUS_SRC_COLOR:
args_RGB[i] |= TEXBLENDARG_INV_ARG;
break;
case GL_SRC_ALPHA:
args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA |
TEXBLENDARG_INV_ARG);
break;
default:
return pass_through( state, blendUnit );
}
}
/* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to
* match the spec. Can't use DOT3 as it won't propogate values
* into alpha as required:
*
* Note - the global factor is set up with alpha == .5, so
* the alpha part of the DOT4 calculation should be zero.
*/
if ( combine->ModeRGB == GL_DOT3_RGBA_EXT ||
combine->ModeRGB == GL_DOT3_RGBA ) {
ablendop = TEXBLENDOP_DOT4;
args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */
args_A[1] = TEXBLENDARG_FACTOR;
args_A[2] = TEXBLENDARG_FACTOR;
}
else {
switch(combine->ModeA) {
case GL_REPLACE:
ablendop = TEXBLENDOP_ARG1;
break;
case GL_MODULATE:
ablendop = TEXBLENDOP_MODULATE;
break;
case GL_ADD:
ablendop = TEXBLENDOP_ADD;
break;
case GL_ADD_SIGNED:
ablendop = TEXBLENDOP_ADDSIGNED;
break;
case GL_INTERPOLATE:
ablendop = TEXBLENDOP_BLEND;
break;
case GL_SUBTRACT:
ablendop = TEXBLENDOP_SUBTRACT;
break;
default:
return pass_through( state, blendUnit );
}
ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT);
/* Handle A args */
for(i = 0; i < 3; i++) {
switch(combine->SourceA[i]) {
case GL_TEXTURE:
args_A[i] = texel_op;
break;
case GL_TEXTURE0:
case GL_TEXTURE1:
case GL_TEXTURE2:
case GL_TEXTURE3:
args_A[i] = GetTexelOp( combine->SourceA[i] - GL_TEXTURE0 );
break;
case GL_CONSTANT:
args_A[i] = TEXBLENDARG_FACTOR_N;
need_factor = 1;
break;
case GL_PRIMARY_COLOR:
args_A[i] = TEXBLENDARG_DIFFUSE;
break;
case GL_PREVIOUS:
args_A[i] = TEXBLENDARG_CURRENT;
break;
default:
return pass_through( state, blendUnit );
}
switch(combine->OperandA[i]) {
case GL_SRC_ALPHA:
args_A[i] |= 0;
break;
case GL_ONE_MINUS_SRC_ALPHA:
args_A[i] |= TEXBLENDARG_INV_ARG;
break;
default:
return pass_through( state, blendUnit );
}
}
}
/* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */
/* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */
/* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */
/* When we render we need to figure out which is the last really enabled
* tex unit, and put last stage on it
*/
/* Build color & alpha pipelines */
used = 0;
state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
TEXPIPE_COLOR |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
DISABLE_TEX_CNTRL_STAGE |
TEXOP_MODIFY_PARMS |
blendop);
state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
TEXPIPE_ALPHA |
ENABLE_TEXOUTPUT_WRT_SEL |
TEXOP_OUTPUT_CURRENT |
TEXOP_MODIFY_PARMS |
ablendop);
for ( i = 0 ; i < numColorArgs ; i++ ) {
state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
tex_blend_rgb[i] | args_RGB[i]);
}
for ( i = 0 ; i < numAlphaArgs ; i++ ) {
state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
tex_blend_a[i] | args_A[i]);
}
if (need_factor)
return emit_factor( blendUnit, state, used, factor );
else
return used;
}
static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit,
GLboolean last_stage )
{
struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit];
GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;
if (0) fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
/* Update i830->state.TexBlend
*/
tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit,
GetTexelOp(unit), tmp,
texUnit->EnvColor );
if (last_stage)
tmp[0] |= TEXOP_LAST_STAGE;
if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] ||
memcmp( tmp, i830->state.TexBlend[blendUnit], tmp_sz * sizeof(GLuint))) {
I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(blendUnit) );
memcpy( i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint));
i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz;
}
I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE);
}
static void emit_passthrough( i830ContextPtr i830 )
{
GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;
GLuint unit = 0;
tmp_sz = pass_through( tmp, unit );
tmp[0] |= TEXOP_LAST_STAGE;
if (tmp_sz != i830->state.TexBlendWordsUsed[unit] ||
memcmp( tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) {
I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(unit) );
memcpy( i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint));
i830->state.TexBlendWordsUsed[unit] = tmp_sz;
}
I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE);
}
void i830EmitTextureBlend( i830ContextPtr i830 )
{
GLcontext *ctx = &i830->intel.ctx;
GLuint unit, last_stage = 0, blendunit = 0;
I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE);
if (ctx->Texture._EnabledUnits) {
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
if (ctx->Texture.Unit[unit]._ReallyEnabled)
last_stage = unit;
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
if (ctx->Texture.Unit[unit]._ReallyEnabled)
emit_texblend( i830, unit, blendunit++, last_stage == unit );
}
else {
emit_passthrough( i830 );
}
}

View File

@ -1,483 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
#include "texstore.h"
#include "mm.h"
#include "intel_screen.h"
#include "intel_ioctl.h"
#include "intel_tex.h"
#include "i830_context.h"
#include "i830_reg.h"
static const GLint initial_offsets[6][2] = { {0,0},
{0,2},
{1,0},
{1,2},
{1,1},
{1,3} };
static const GLint step_offsets[6][2] = { {0,2},
{0,2},
{-1,2},
{-1,2},
{-1,1},
{-1,1} };
#define I830_TEX_UNIT_ENABLED(unit) (1<<unit)
static GLboolean i830SetTexImages( i830ContextPtr i830,
struct gl_texture_object *tObj )
{
GLuint total_height, pitch, i, textureFormat;
i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
GLint firstLevel, lastLevel, numLevels;
switch( baseImage->TexFormat->MesaFormat ) {
case MESA_FORMAT_L8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_L8;
break;
case MESA_FORMAT_I8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_I8;
break;
case MESA_FORMAT_A8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_I8; /* Kludge -- check with conform, glean */
break;
case MESA_FORMAT_AL88:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_AY88;
break;
case MESA_FORMAT_RGB565:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
break;
case MESA_FORMAT_ARGB1555:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
break;
case MESA_FORMAT_ARGB4444:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444;
break;
case MESA_FORMAT_ARGB8888:
t->intel.texelBytes = 4;
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
break;
case MESA_FORMAT_YCBCR_REV:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL |
TM0S1_COLORSPACE_CONVERSION);
break;
case MESA_FORMAT_YCBCR:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */
TM0S1_COLORSPACE_CONVERSION);
break;
case MESA_FORMAT_RGB_FXT1:
case MESA_FORMAT_RGBA_FXT1:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_COMPRESSED | MT_COMPRESS_FXT1;
break;
case MESA_FORMAT_RGBA_DXT1:
case MESA_FORMAT_RGB_DXT1:
/*
* DXTn pitches are Width/4 * blocksize in bytes
* for DXT1: blocksize=8 so Width/4*8 = Width * 2
* for DXT3/5: blocksize=16 so Width/4*16 = Width * 4
*/
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
break;
case MESA_FORMAT_RGBA_DXT3:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
break;
case MESA_FORMAT_RGBA_DXT5:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
break;
default:
fprintf(stderr, "%s: bad image format\n", __FUNCTION__);
abort();
}
/* Compute which mipmap levels we really want to send to the hardware.
* This depends on the base image size, GL_TEXTURE_MIN_LOD,
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
* Yes, this looks overly complicated, but it's all needed.
*/
driCalculateTextureFirstLastLevel( (driTextureObject *) t );
/* Figure out the amount of memory required to hold all the mipmap
* levels. Choose the smallest pitch to accomodate the largest
* mipmap:
*/
firstLevel = t->intel.base.firstLevel;
lastLevel = t->intel.base.lastLevel;
numLevels = lastLevel - firstLevel + 1;
/* All images must be loaded at this pitch. Count the number of
* lines required:
*/
switch (tObj->Target) {
case GL_TEXTURE_CUBE_MAP: {
const GLuint dim = tObj->Image[0][firstLevel]->Width;
GLuint face;
pitch = dim * t->intel.texelBytes;
pitch *= 2; /* double pitch for cube layouts */
pitch = (pitch + 3) & ~3;
total_height = dim * 4;
for ( face = 0 ; face < 6 ; face++) {
GLuint x = initial_offsets[face][0] * dim;
GLuint y = initial_offsets[face][1] * dim;
GLuint d = dim;
t->intel.base.dirty_images[face] = ~0;
assert(tObj->Image[face][firstLevel]->Width == dim);
assert(tObj->Image[face][firstLevel]->Height == dim);
for (i = 0; i < numLevels; i++) {
t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
if (!t->intel.image[face][i].image) {
fprintf(stderr, "no image %d %d\n", face, i);
break; /* can't happen */
}
t->intel.image[face][i].offset =
y * pitch + x * t->intel.texelBytes;
t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
break;
}
default:
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
pitch = (pitch + 3) & ~3;
t->intel.base.dirty_images[0] = ~0;
for ( total_height = i = 0 ; i < numLevels ; i++ ) {
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
if (!t->intel.image[0][i].image)
break;
t->intel.image[0][i].offset = total_height * pitch;
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
if (t->intel.image[0][i].image->IsCompressed)
{
if (t->intel.image[0][i].image->Height > 4)
total_height += t->intel.image[0][i].image->Height/4;
else
total_height += 1;
}
else
total_height += MAX2(2, t->intel.image[0][i].image->Height);
}
break;
}
t->intel.Pitch = pitch;
t->intel.base.totalSize = total_height*pitch;
t->intel.max_level = i-1;
t->Setup[I830_TEXREG_TM0S1] =
(((tObj->Image[0][firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) |
((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) |
textureFormat);
t->Setup[I830_TEXREG_TM0S2] =
(((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) |
TM0S2_CUBE_FACE_ENA_MASK;
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
t->intel.dirty = I830_UPLOAD_TEX_ALL;
return intelUploadTexImages( &i830->intel, &t->intel, 0 );
}
static void i830_import_tex_unit( i830ContextPtr i830,
i830TextureObjectPtr t,
GLuint unit )
{
if(INTEL_DEBUG&DEBUG_TEXTURE)
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
if (i830->intel.CurrentTexObj[unit])
i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
t->intel.base.bound |= (1 << unit);
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) );
i830->state.Tex[unit][I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
(LOAD_TEXTURE_MAP0 << unit) | 4);
i830->state.Tex[unit][I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE |
t->intel.TextureOffset);
i830->state.Tex[unit][I830_TEXREG_TM0S1] = t->Setup[I830_TEXREG_TM0S1];
i830->state.Tex[unit][I830_TEXREG_TM0S2] = t->Setup[I830_TEXREG_TM0S2];
i830->state.Tex[unit][I830_TEXREG_TM0S3] &= TM0S3_LOD_BIAS_MASK;
i830->state.Tex[unit][I830_TEXREG_TM0S3] |= (t->Setup[I830_TEXREG_TM0S3] &
~TM0S3_LOD_BIAS_MASK);
i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4];
i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] &
~MAP_UNIT_MASK);
i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE];
i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit);
t->intel.dirty &= ~I830_UPLOAD_TEX(unit);
}
static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
if (0) fprintf(stderr, "%s\n", __FUNCTION__);
/* Fallback if there's a texture border */
if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
fprintf(stderr, "Texture border\n");
return GL_FALSE;
}
/* Upload teximages (not pipelined)
*/
if (t->intel.base.dirty_images[0]) {
if (!i830SetTexImages( i830, tObj )) {
return GL_FALSE;
}
}
/* Update state if this is a different texture object to last
* time.
*/
if (i830->intel.CurrentTexObj[unit] != &t->intel ||
(t->intel.dirty & I830_UPLOAD_TEX(unit))) {
i830_import_tex_unit( i830, t, unit);
}
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE);
return GL_TRUE;
}
static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS];
mcs &= ~TEXCOORDS_ARE_NORMAL;
mcs |= TEXCOORDS_ARE_IN_TEXELUNITS;
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
|| (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
i830->state.Tex[unit][I830_TEXREG_CUBE] = 0;
}
return GL_TRUE;
}
static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS];
mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS;
mcs |= TEXCOORDS_ARE_NORMAL;
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
|| (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
i830->state.Tex[unit][I830_TEXREG_CUBE] = 0;
}
return GL_TRUE;
}
static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS];
const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE
| CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE
| CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE;
GLuint face;
mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS;
mcs |= TEXCOORDS_ARE_NORMAL;
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
|| (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
i830->state.Tex[unit][I830_TEXREG_CUBE] = cube;
}
/* Upload teximages (not pipelined)
*/
if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] ||
t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] ||
t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) {
i830SetTexImages( i830, tObj );
}
/* upload (per face) */
for (face = 0; face < 6; face++) {
if (t->intel.base.dirty_images[face]) {
if (!intelUploadTexImages( &i830->intel, &t->intel, face )) {
return GL_FALSE;
}
}
}
return GL_TRUE;
}
static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
/* This is happening too often. I need to conditionally send diffuse
* state to the card. Perhaps a diffuse dirty flag of some kind.
* Will need to change this logic if more than 2 texture units are
* used. We need to only do this up to the last unit enabled, or unit
* one if nothing is enabled.
*/
if ( i830->intel.CurrentTexObj[unit] != NULL ) {
/* The old texture is no longer bound to this texture unit.
* Mark it as such.
*/
i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
i830->intel.CurrentTexObj[unit] = NULL;
}
return GL_TRUE;
}
static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
if (texUnit->_ReallyEnabled &&
INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
return GL_FALSE;
switch(texUnit->_ReallyEnabled) {
case TEXTURE_1D_BIT:
case TEXTURE_2D_BIT:
return (enable_tex_common( ctx, unit ) &&
enable_tex_2d( ctx, unit ));
case TEXTURE_RECT_BIT:
return (enable_tex_common( ctx, unit ) &&
enable_tex_rect( ctx, unit ));
case TEXTURE_CUBE_BIT:
return (enable_tex_common( ctx, unit ) &&
enable_tex_cube( ctx, unit ));
case 0:
return disable_tex( ctx, unit );
default:
return GL_FALSE;
}
}
void i830UpdateTextureState( intelContextPtr intel )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
GLcontext *ctx = &intel->ctx;
GLboolean ok;
if (0) fprintf(stderr, "%s\n", __FUNCTION__);
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX_ALL, GL_FALSE);
ok = (i830UpdateTexUnit( ctx, 0 ) &&
i830UpdateTexUnit( ctx, 1 ) &&
i830UpdateTexUnit( ctx, 2 ) &&
i830UpdateTexUnit( ctx, 3 ));
FALLBACK( intel, I830_FALLBACK_TEXTURE, !ok );
if (ok)
i830EmitTextureBlend( i830 );
}

View File

@ -1,540 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "i830_context.h"
#include "i830_reg.h"
#include "intel_batchbuffer.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
static GLboolean i830_check_vertex_size( intelContextPtr intel,
GLuint expected );
#define SZ_TO_HW(sz) ((sz-2)&0x3)
#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1)
#define EMIT_ATTR( ATTR, STYLE, V0 ) \
do { \
intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \
intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \
intel->vertex_attr_count++; \
v0 |= V0; \
} while (0)
#define EMIT_PAD( N ) \
do { \
intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \
intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \
intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \
intel->vertex_attr_count++; \
} while (0)
#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2))
#define TEXBIND_SET(n, x) ((x)<<((n)*4))
static void
i830_render_prevalidate(struct intel_context *intel)
{
}
static void i830_render_start( intelContextPtr intel )
{
GLcontext *ctx = &intel->ctx;
i830ContextPtr i830 = I830_CONTEXT(intel);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
DECLARE_RENDERINPUTS(index_bitset);
GLuint v0 = _3DSTATE_VFT0_CMD;
GLuint v2 = _3DSTATE_VFT1_CMD;
GLuint mcsb1 = 0;
RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
intel->vertex_attr_count = 0;
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW );
intel->coloroffset = 4;
}
else {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ );
intel->coloroffset = 3;
}
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH );
}
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE );
intel->specoffset = 0;
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
intel->specoffset = intel->coloroffset + 1;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC );
}
else
EMIT_PAD( 3 );
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC );
else
EMIT_PAD( 1 );
}
if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
int i, count = 0;
for (i = 0; i < I830_TEX_UNITS; i++) {
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
GLuint sz = VB->TexCoordPtr[i]->size;
GLuint emit;
GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
~TEXCOORDTYPE_MASK);
switch (sz) {
case 1:
case 2:
emit = EMIT_2F;
sz = 2;
mcs |= TEXCOORDTYPE_CARTESIAN;
break;
case 3:
emit = EMIT_3F;
sz = 3;
mcs |= TEXCOORDTYPE_VECTOR;
break;
case 4:
emit = EMIT_3F_XYW;
sz = 3;
mcs |= TEXCOORDTYPE_HOMOGENEOUS;
break;
default:
continue;
};
EMIT_ATTR( _TNL_ATTRIB_TEX0+i, emit, 0 );
v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz));
mcsb1 |= (count+8)<<(i*4);
if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) {
I830_STATECHANGE(i830, I830_UPLOAD_TEX(i));
i830->state.Tex[i][I830_TEXREG_MCS] = mcs;
}
count++;
}
}
v0 |= VFT0_TEX_COUNT(count);
}
/* Only need to change the vertex emit code if there has been a
* statechange to a new hardware vertex format:
*/
if (v0 != i830->state.Ctx[I830_CTXREG_VF] ||
v2 != i830->state.Ctx[I830_CTXREG_VF2] ||
mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] ||
!RENDERINPUTS_EQUAL( index_bitset, i830->last_index_bitset )) {
I830_STATECHANGE( i830, I830_UPLOAD_CTX );
/* Must do this *after* statechange, so as not to affect
* buffered vertices reliant on the old state:
*/
intel->vertex_size =
_tnl_install_attrs( ctx,
intel->vertex_attrs,
intel->vertex_attr_count,
intel->ViewportMatrix.m, 0 );
intel->vertex_size >>= 2;
i830->state.Ctx[I830_CTXREG_VF] = v0;
i830->state.Ctx[I830_CTXREG_VF2] = v2;
i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1;
RENDERINPUTS_COPY( i830->last_index_bitset, index_bitset );
assert(i830_check_vertex_size( intel, intel->vertex_size ));
}
}
static void i830_reduced_primitive_state( intelContextPtr intel,
GLenum rprim )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
GLuint st1 = i830->state.Stipple[I830_STPREG_ST1];
st1 &= ~ST1_ENABLE;
switch (rprim) {
case GL_TRIANGLES:
if (intel->ctx.Polygon.StippleFlag &&
intel->hw_stipple)
st1 |= ST1_ENABLE;
break;
case GL_LINES:
case GL_POINTS:
default:
break;
}
i830->intel.reduced_primitive = rprim;
if (st1 != i830->state.Stipple[I830_STPREG_ST1]) {
I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
i830->state.Stipple[I830_STPREG_ST1] = st1;
}
}
/* Pull apart the vertex format registers and figure out how large a
* vertex is supposed to be.
*/
static GLboolean i830_check_vertex_size( intelContextPtr intel,
GLuint expected )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
int vft0 = i830->current->Ctx[I830_CTXREG_VF];
int vft1 = i830->current->Ctx[I830_CTXREG_VF2];
int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT;
int i, sz = 0;
switch (vft0 & VFT0_XYZW_MASK) {
case VFT0_XY: sz = 2; break;
case VFT0_XYZ: sz = 3; break;
case VFT0_XYW: sz = 3; break;
case VFT0_XYZW: sz = 4; break;
default:
fprintf(stderr, "no xyzw specified\n");
return 0;
}
if (vft0 & VFT0_SPEC) sz++;
if (vft0 & VFT0_DIFFUSE) sz++;
if (vft0 & VFT0_DEPTH_OFFSET) sz++;
if (vft0 & VFT0_POINT_WIDTH) sz++;
for (i = 0 ; i < nrtex ; i++) {
switch (vft1 & VFT1_TEX0_MASK) {
case TEXCOORDFMT_2D: sz += 2; break;
case TEXCOORDFMT_3D: sz += 3; break;
case TEXCOORDFMT_4D: sz += 4; break;
case TEXCOORDFMT_1D: sz += 1; break;
}
vft1 >>= VFT1_TEX1_SHIFT;
}
if (sz != expected)
fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected);
return sz == expected;
}
static void i830_emit_invarient_state( intelContextPtr intel )
{
BATCH_LOCALS;
BEGIN_BATCH( 40 );
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2));
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(3));
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_FOG_MODE_CMD);
OUT_BATCH(FOGFUNC_ENABLE |
FOG_LINEAR_CONST |
FOGSRC_INDEX_Z |
ENABLE_FOG_DENSITY);
OUT_BATCH(0);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
MAP_UNIT(0) |
DISABLE_TEX_STREAM_BUMP |
ENABLE_TEX_STREAM_COORD_SET |
TEX_STREAM_COORD_SET(0) |
ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0));
OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
MAP_UNIT(1) |
DISABLE_TEX_STREAM_BUMP |
ENABLE_TEX_STREAM_COORD_SET |
TEX_STREAM_COORD_SET(1) |
ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1));
OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
MAP_UNIT(2) |
DISABLE_TEX_STREAM_BUMP |
ENABLE_TEX_STREAM_COORD_SET |
TEX_STREAM_COORD_SET(2) |
ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2));
OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD |
MAP_UNIT(3) |
DISABLE_TEX_STREAM_BUMP |
ENABLE_TEX_STREAM_COORD_SET |
TEX_STREAM_COORD_SET(3) |
ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3));
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0));
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1));
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2));
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |
ENABLE_LINE_STRIP_PROVOKE_VRTX |
ENABLE_TRI_FAN_PROVOKE_VRTX |
ENABLE_TRI_STRIP_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) |
TRI_FAN_PROVOKE_VRTX(2) |
TRI_STRIP_PROVOKE_VRTX(2));
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD);
OUT_BATCH(0);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
OUT_BATCH(_3DSTATE_W_STATE_CMD);
OUT_BATCH(MAGIC_W_STATE_DWORD1);
OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ );
OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD);
OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */
ADVANCE_BATCH();
}
#define emit( intel, state, size ) \
do { \
int k; \
BEGIN_BATCH( size / sizeof(GLuint)); \
for (k = 0 ; k < size / sizeof(GLuint) ; k++) \
OUT_BATCH(state[k]); \
ADVANCE_BATCH(); \
} while (0);
static GLuint get_state_size( struct i830_hw_state *state )
{
GLuint dirty = state->active & ~state->emitted;
GLuint sz = 0;
GLuint i;
if (dirty & I830_UPLOAD_INVARIENT)
sz += 40 * sizeof(int);
if (dirty & I830_UPLOAD_CTX)
sz += sizeof(state->Ctx);
if (dirty & I830_UPLOAD_BUFFERS)
sz += sizeof(state->Buffer);
if (dirty & I830_UPLOAD_STIPPLE)
sz += sizeof(state->Stipple);
for (i = 0; i < I830_TEX_UNITS; i++) {
if ((dirty & I830_UPLOAD_TEX(i)))
sz += sizeof(state->Tex[i]);
if (dirty & I830_UPLOAD_TEXBLEND(i))
sz += state->TexBlendWordsUsed[i] * 4;
}
return sz;
}
/* Push the state into the sarea and/or texture memory.
*/
static void i830_emit_state( intelContextPtr intel )
{
i830ContextPtr i830 = I830_CONTEXT(intel);
struct i830_hw_state *state = i830->current;
int i;
GLuint dirty = state->active & ~state->emitted;
GLuint counter = intel->batch.counter;
BATCH_LOCALS;
if (intel->batch.space < get_state_size(state)) {
intelFlushBatch(intel, GL_TRUE);
dirty = state->active & ~state->emitted;
counter = intel->batch.counter;
}
if (dirty & I830_UPLOAD_INVARIENT) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_INVARIENT:\n");
i830_emit_invarient_state( intel );
}
if (dirty & I830_UPLOAD_CTX) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_CTX:\n");
emit( i830, state->Ctx, sizeof(state->Ctx) );
}
if (dirty & I830_UPLOAD_BUFFERS) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_BUFFERS:\n");
emit( i830, state->Buffer, sizeof(state->Buffer) );
}
if (dirty & I830_UPLOAD_STIPPLE) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_STIPPLE:\n");
emit( i830, state->Stipple, sizeof(state->Stipple) );
}
for (i = 0; i < I830_TEX_UNITS; i++) {
if ((dirty & I830_UPLOAD_TEX(i))) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i);
emit( i830, state->Tex[i], sizeof(state->Tex[i]));
}
if (dirty & I830_UPLOAD_TEXBLEND(i)) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i);
emit( i830, state->TexBlend[i],
state->TexBlendWordsUsed[i] * 4 );
}
}
state->emitted |= dirty;
intel->batch.last_emit_state = counter;
assert(counter == intel->batch.counter);
}
static void i830_destroy_context( intelContextPtr intel )
{
_tnl_free_vertices(&intel->ctx);
}
static void
i830_set_color_region(intelContextPtr intel, const intelRegion *region)
{
i830ContextPtr i830 = I830_CONTEXT(intel);
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_CBUFADDR2] = region->offset;
}
static void
i830_set_z_region(intelContextPtr intel, const intelRegion *region)
{
i830ContextPtr i830 = I830_CONTEXT(intel);
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR2] = region->offset;
}
static void
i830_update_color_z_regions(intelContextPtr intel,
const intelRegion *colorRegion,
const intelRegion *depthRegion)
{
i830ContextPtr i830 = I830_CONTEXT(intel);
i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset;
i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset;
}
/* This isn't really handled at the moment.
*/
static void i830_lost_hardware( intelContextPtr intel )
{
I830_CONTEXT(intel)->state.emitted = 0;
}
static void i830_emit_flush( intelContextPtr intel )
{
BATCH_LOCALS;
BEGIN_BATCH(2);
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE );
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
void i830InitVtbl( i830ContextPtr i830 )
{
i830->intel.vtbl.alloc_tex_obj = i830AllocTexObj;
i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
i830->intel.vtbl.clear_with_tris = i830ClearWithTris;
i830->intel.vtbl.rotate_window = i830RotateWindow;
i830->intel.vtbl.destroy = i830_destroy_context;
i830->intel.vtbl.emit_state = i830_emit_state;
i830->intel.vtbl.lost_hardware = i830_lost_hardware;
i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state;
i830->intel.vtbl.set_color_region = i830_set_color_region;
i830->intel.vtbl.set_z_region = i830_set_z_region;
i830->intel.vtbl.update_color_z_regions = i830_update_color_z_regions;
i830->intel.vtbl.update_texture_state = i830UpdateTextureState;
i830->intel.vtbl.emit_flush = i830_emit_flush;
i830->intel.vtbl.render_start = i830_render_start;
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
}

View File

@ -1,186 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "i915_context.h"
#include "imports.h"
#include "intel_tex.h"
#include "intel_tris.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "vbo/vbo.h"
#include "utils.h"
#include "i915_reg.h"
/***************************************
* Mesa's Driver Functions
***************************************/
static const struct dri_extension i915_extensions[] =
{
{ "GL_ARB_depth_texture", NULL },
{ "GL_ARB_fragment_program", NULL },
{ "GL_ARB_shadow", NULL },
{ "GL_ARB_texture_env_crossbar", NULL },
{ "GL_EXT_shadow_funcs", NULL },
/* ARB extn won't work if not enabled */
{ "GL_SGIX_depth_texture", NULL },
{ NULL, NULL }
};
/* Override intel default.
*/
static void i915InvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
_vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
/* Todo: gather state values under which tracked parameters become
* invalidated, add callbacks for things like
* ProgramLocalParameters, etc.
*/
{
struct i915_fragment_program *p =
(struct i915_fragment_program *)ctx->FragmentProgram._Current;
if (p && p->nr_params)
p->params_uptodate = 0;
}
if (new_state & (_NEW_FOG|_NEW_HINT|_NEW_PROGRAM))
i915_update_fog(ctx);
}
static void i915InitDriverFunctions( struct dd_function_table *functions )
{
intelInitDriverFunctions( functions );
i915InitStateFunctions( functions );
i915InitTextureFuncs( functions );
i915InitFragProgFuncs( functions );
functions->UpdateState = i915InvalidateState;
}
GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
struct dd_function_table functions;
i915ContextPtr i915 = (i915ContextPtr) CALLOC_STRUCT(i915_context);
intelContextPtr intel = &i915->intel;
GLcontext *ctx = &intel->ctx;
GLuint i;
if (!i915) return GL_FALSE;
i915InitVtbl( i915 );
i915InitDriverFunctions( &functions );
if (!intelInitContext( intel, mesaVis, driContextPriv,
sharedContextPrivate, &functions )) {
FREE(i915);
return GL_FALSE;
}
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
intel->nr_heaps = 1;
intel->texture_heaps[0] =
driCreateTextureHeap( 0, intel,
intel->intelScreen->tex.size,
12,
I830_NR_TEX_REGIONS,
intel->sarea->texList,
(unsigned *) & intel->sarea->texAge,
& intel->swapped,
sizeof( struct i915_texture_object ),
(destroy_texture_object_t *)intelDestroyTexObj );
/* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are
* tightly packed, but they're not in Intel graphics
* hardware.
*/
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
i = driQueryOptioni( &intel->optionCache, "allow_large_textures");
driCalculateMaxTextureLevels( intel->texture_heaps,
intel->nr_heaps,
&intel->ctx.Const,
4,
11, /* max 2D texture size is 2048x2048 */
8, /* 3D texture */
11, /* cube texture. */
11, /* rect texture */
12,
GL_FALSE,
i );
/* GL_ARB_fragment_program limits - don't think Mesa actually
* validates programs against these, and in any case one ARB
* instruction can translate to more than one HW instruction, so
* we'll still have to check and fallback each time.
*/
ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY;
ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */
ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT;
ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN;
ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN;
ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN +
I915_MAX_TEX_INSN);
ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
driInitExtensions( ctx, i915_extensions, GL_FALSE );
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
36 * sizeof(GLfloat) );
intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf;
i915InitState( i915 );
return GL_TRUE;
}

View File

@ -1,358 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef I915CONTEXT_INC
#define I915CONTEXT_INC
#include "intel_context.h"
#define I915_FALLBACK_TEXTURE 0x1000
#define I915_FALLBACK_COLORMASK 0x2000
#define I915_FALLBACK_STENCIL 0x4000
#define I915_FALLBACK_STIPPLE 0x8000
#define I915_FALLBACK_PROGRAM 0x10000
#define I915_FALLBACK_LOGICOP 0x20000
#define I915_FALLBACK_POLYGON_SMOOTH 0x40000
#define I915_FALLBACK_POINT_SMOOTH 0x80000
#define I915_UPLOAD_CTX 0x1
#define I915_UPLOAD_BUFFERS 0x2
#define I915_UPLOAD_STIPPLE 0x4
#define I915_UPLOAD_PROGRAM 0x8
#define I915_UPLOAD_CONSTANTS 0x10
#define I915_UPLOAD_FOG 0x20
#define I915_UPLOAD_INVARIENT 0x40
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
#define I915_UPLOAD_TEX_0_SHIFT 16
/* State structure offsets - these will probably disappear.
*/
#define I915_DESTREG_CBUFADDR0 0
#define I915_DESTREG_CBUFADDR1 1
#define I915_DESTREG_CBUFADDR2 2
#define I915_DESTREG_DBUFADDR0 3
#define I915_DESTREG_DBUFADDR1 4
#define I915_DESTREG_DBUFADDR2 5
#define I915_DESTREG_DV0 6
#define I915_DESTREG_DV1 7
#define I915_DESTREG_SENABLE 8
#define I915_DESTREG_SR0 9
#define I915_DESTREG_SR1 10
#define I915_DESTREG_SR2 11
#define I915_DEST_SETUP_SIZE 12
#define I915_CTXREG_STATE4 0
#define I915_CTXREG_LI 1
#define I915_CTXREG_LIS2 2
#define I915_CTXREG_LIS4 3
#define I915_CTXREG_LIS5 4
#define I915_CTXREG_LIS6 5
#define I915_CTXREG_IAB 6
#define I915_CTXREG_BLENDCOLOR0 7
#define I915_CTXREG_BLENDCOLOR1 8
#define I915_CTX_SETUP_SIZE 9
#define I915_FOGREG_COLOR 0
#define I915_FOGREG_MODE0 1
#define I915_FOGREG_MODE1 2
#define I915_FOGREG_MODE2 3
#define I915_FOGREG_MODE3 4
#define I915_FOG_SETUP_SIZE 5
#define I915_STPREG_ST0 0
#define I915_STPREG_ST1 1
#define I915_STP_SETUP_SIZE 2
#define I915_TEXREG_MS2 0
#define I915_TEXREG_MS3 1
#define I915_TEXREG_MS4 2
#define I915_TEXREG_SS2 3
#define I915_TEXREG_SS3 4
#define I915_TEXREG_SS4 5
#define I915_TEX_SETUP_SIZE 6
#define I915_MAX_CONSTANT 32
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT))
#define I915_PROGRAM_SIZE 192
/* Hardware version of a parsed fragment program. "Derived" from the
* mesa fragment_program struct.
*/
struct i915_fragment_program {
struct gl_fragment_program FragProg;
GLboolean translated;
GLboolean params_uptodate;
GLboolean on_hardware;
GLboolean error; /* If program is malformed for any reason. */
GLuint nr_tex_indirect;
GLuint nr_tex_insn;
GLuint nr_alu_insn;
GLuint nr_decl_insn;
/* TODO: split between the stored representation of a program and
* the state used to build that representation.
*/
GLcontext *ctx;
GLuint declarations[I915_PROGRAM_SIZE];
GLuint program[I915_PROGRAM_SIZE];
GLfloat constant[I915_MAX_CONSTANT][4];
GLuint constant_flags[I915_MAX_CONSTANT];
GLuint nr_constants;
GLuint *csr; /* Cursor, points into program.
*/
GLuint *decl; /* Cursor, points into declarations.
*/
GLuint decl_s; /* flags for which s regs need to be decl'd */
GLuint decl_t; /* flags for which t regs need to be decl'd */
GLuint temp_flag; /* Tracks temporary regs which are in
* use.
*/
GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in
* use.
*/
/* Helpers for i915_fragprog.c:
*/
GLuint wpos_tex;
GLboolean depth_written;
struct {
GLuint reg; /* Hardware constant idx */
const GLfloat *values; /* Pointer to tracked values */
} param[I915_MAX_CONSTANT];
GLuint nr_params;
/* Helpers for i915_texprog.c:
*/
GLuint src_texture; /* Reg containing sampled texture color,
* else UREG_BAD.
*/
GLuint src_previous; /* Reg containing color from previous
* stage. May need to be decl'd.
*/
GLuint last_tex_stage; /* Number of last enabled texture unit */
struct vertex_buffer *VB;
};
struct i915_texture_object
{
struct intel_texture_object intel;
GLenum lastTarget;
GLboolean refs_border_color;
GLuint Setup[I915_TEX_SETUP_SIZE];
};
#define I915_TEX_UNITS 8
struct i915_hw_state {
GLuint Ctx[I915_CTX_SETUP_SIZE];
GLuint Buffer[I915_DEST_SETUP_SIZE];
GLuint Stipple[I915_STP_SETUP_SIZE];
GLuint Fog[I915_FOG_SETUP_SIZE];
GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE];
GLuint Constant[I915_CONSTANT_SIZE];
GLuint ConstantSize;
GLuint Program[I915_PROGRAM_SIZE];
GLuint ProgramSize;
GLuint active; /* I915_UPLOAD_* */
GLuint emitted; /* I915_UPLOAD_* */
};
#define I915_FOG_PIXEL 2
#define I915_FOG_VERTEX 1
#define I915_FOG_NONE 0
struct i915_context
{
struct intel_context intel;
GLuint last_ReallyEnabled;
GLuint vertex_fog;
struct i915_fragment_program tex_program;
struct i915_fragment_program *current_program;
struct i915_hw_state meta, initial, state, *current;
};
typedef struct i915_context *i915ContextPtr;
typedef struct i915_texture_object *i915TextureObjectPtr;
#define I915_CONTEXT(ctx) ((i915ContextPtr)(ctx))
#define I915_STATECHANGE(i915, flag) \
do { \
if (0) fprintf(stderr, "I915_STATECHANGE %x in %s\n", flag, __FUNCTION__); \
INTEL_FIREVERTICES( &(i915)->intel ); \
(i915)->state.emitted &= ~(flag); \
} while (0)
#define I915_ACTIVESTATE(i915, flag, mode) \
do { \
if (0) fprintf(stderr, "I915_ACTIVESTATE %x %d in %s\n", \
flag, mode, __FUNCTION__); \
INTEL_FIREVERTICES( &(i915)->intel ); \
if (mode) \
(i915)->state.active |= (flag); \
else \
(i915)->state.active &= ~(flag); \
} while (0)
/*======================================================================
* i915_vtbl.c
*/
extern void i915InitVtbl( i915ContextPtr i915 );
#define SZ_TO_HW(sz) ((sz-2)&0x3)
#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1)
#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \
do { \
intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \
intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \
s4 |= S4; \
intel->vertex_attr_count++; \
offset += (SZ); \
} while (0)
#define EMIT_PAD( N ) \
do { \
intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \
intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \
intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \
intel->vertex_attr_count++; \
offset += (N); \
} while (0)
/*======================================================================
* i915_context.c
*/
extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
/*======================================================================
* i915_texprog.c
*/
extern void i915ValidateTextureProgram( i915ContextPtr i915 );
/*======================================================================
* i915_debug.c
*/
extern void i915_disassemble_program( const GLuint *program, GLuint sz );
extern void i915_print_ureg( const char *msg, GLuint ureg );
/*======================================================================
* i915_state.c
*/
extern void i915InitStateFunctions( struct dd_function_table *functions );
extern void i915InitState( i915ContextPtr i915 );
extern void i915_update_fog(GLcontext *ctxx);
/*======================================================================
* i915_tex.c
*/
extern void i915UpdateTextureState( intelContextPtr intel );
extern void i915InitTextureFuncs( struct dd_function_table *functions );
extern intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj );
/*======================================================================
* i915_metaops.c
*/
extern GLboolean
i915TryTextureReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels );
extern GLboolean
i915TryTextureDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
extern void
i915ClearWithTris( intelContextPtr intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
extern void
i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuf);
/*======================================================================
* i915_fragprog.c
*/
extern void i915ValidateFragmentProgram( i915ContextPtr i915 );
extern void i915InitFragProgFuncs( struct dd_function_table *functions );
#endif

View File

@ -1,299 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "i915_reg.h"
#include "i915_context.h"
#include <stdio.h>
static const char *opcodes[0x20] = {
"NOP",
"ADD",
"MOV",
"MUL",
"MAD",
"DP2ADD",
"DP3",
"DP4",
"FRC",
"RCP",
"RSQ",
"EXP",
"LOG",
"CMP",
"MIN",
"MAX",
"FLR",
"MOD",
"TRC",
"SGE",
"SLT",
"TEXLD",
"TEXLDP",
"TEXLDB",
"TEXKILL",
"DCL",
"0x1a",
"0x1b",
"0x1c",
"0x1d",
"0x1e",
"0x1f",
};
static const int args[0x20] = {
0, /* 0 nop */
2, /* 1 add */
1, /* 2 mov */
2, /* 3 m ul */
3, /* 4 mad */
3, /* 5 dp2add */
2, /* 6 dp3 */
2, /* 7 dp4 */
1, /* 8 frc */
1, /* 9 rcp */
1, /* a rsq */
1, /* b exp */
1, /* c log */
3, /* d cmp */
2, /* e min */
2, /* f max */
1, /* 10 flr */
1, /* 11 mod */
1, /* 12 trc */
2, /* 13 sge */
2, /* 14 slt */
1,
1,
1,
1,
0,
0,
0,
0,
0,
0,
0,
};
static const char *regname[0x8] = {
"R",
"T",
"CONST",
"S",
"OC",
"OD",
"U",
"UNKNOWN",
};
static void print_reg_type_nr( GLuint type, GLuint nr )
{
switch (type) {
case REG_TYPE_T:
switch (nr) {
case T_DIFFUSE: fprintf(stderr, "T_DIFFUSE"); return;
case T_SPECULAR: fprintf(stderr, "T_SPECULAR"); return;
case T_FOG_W: fprintf(stderr, "T_FOG_W"); return;
default: fprintf(stderr, "T_TEX%d", nr); return;
}
case REG_TYPE_OC:
if (nr == 0) {
fprintf(stderr, "oC");
return;
}
break;
case REG_TYPE_OD:
if (nr == 0) {
fprintf(stderr, "oD");
return;
}
break;
default:
break;
}
fprintf(stderr, "%s[%d]", regname[type], nr);
}
#define REG_SWIZZLE_MASK 0x7777
#define REG_NEGATE_MASK 0x8888
#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \
(SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \
(SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \
(SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
static void print_reg_neg_swizzle( GLuint reg )
{
int i;
if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW &&
(reg & REG_NEGATE_MASK) == 0)
return;
fprintf(stderr, ".");
for (i = 3 ; i >= 0; i--) {
if (reg & (1<<((i*4)+3)))
fprintf(stderr, "-");
switch ((reg>>(i*4)) & 0x7) {
case 0: fprintf(stderr, "x"); break;
case 1: fprintf(stderr, "y"); break;
case 2: fprintf(stderr, "z"); break;
case 3: fprintf(stderr, "w"); break;
case 4: fprintf(stderr, "0"); break;
case 5: fprintf(stderr, "1"); break;
default: fprintf(stderr, "?"); break;
}
}
}
static void print_src_reg( GLuint dword )
{
GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK;
GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK;
print_reg_type_nr( type, nr );
print_reg_neg_swizzle( dword );
}
void i915_print_ureg( const char *msg, GLuint ureg )
{
fprintf(stderr, "%s: ", msg);
print_src_reg( ureg >> 8 );
fprintf(stderr, "\n");
}
static void print_dest_reg( GLuint dword )
{
GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK;
GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK;
print_reg_type_nr( type, nr );
if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL)
return;
fprintf(stderr, ".");
if (dword & A0_DEST_CHANNEL_X) fprintf(stderr, "x");
if (dword & A0_DEST_CHANNEL_Y) fprintf(stderr, "y");
if (dword & A0_DEST_CHANNEL_Z) fprintf(stderr, "z");
if (dword & A0_DEST_CHANNEL_W) fprintf(stderr, "w");
}
#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT))
#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT))
#define GET_SRC2_REG(r) (r)
static void print_arith_op( GLuint opcode, const GLuint *program )
{
if (opcode != A0_NOP) {
print_dest_reg(program[0]);
if (program[0] & A0_DEST_SATURATE)
fprintf(stderr, " = SATURATE ");
else
fprintf(stderr, " = ");
}
fprintf(stderr, "%s ", opcodes[opcode]);
print_src_reg(GET_SRC0_REG(program[0], program[1]));
if (args[opcode] == 1) {
fprintf(stderr, "\n");
return;
}
fprintf(stderr, ", ");
print_src_reg(GET_SRC1_REG(program[1], program[2]));
if (args[opcode] == 2) {
fprintf(stderr, "\n");
return;
}
fprintf(stderr, ", ");
print_src_reg(GET_SRC2_REG(program[2]));
fprintf(stderr, "\n");
return;
}
static void print_tex_op( GLuint opcode, const GLuint *program )
{
print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
fprintf(stderr, " = ");
fprintf(stderr, "%s ", opcodes[opcode]);
fprintf(stderr, "S[%d],",
program[0] & T0_SAMPLER_NR_MASK);
print_reg_type_nr( (program[1]>>T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK,
(program[1]>>T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK );
fprintf(stderr, "\n");
}
static void print_dcl_op( GLuint opcode, const GLuint *program )
{
fprintf(stderr, "%s ", opcodes[opcode]);
print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
fprintf(stderr, "\n");
}
void i915_disassemble_program( const GLuint *program, GLuint sz )
{
GLuint size = program[0] & 0x1ff;
GLint i;
fprintf(stderr, "BEGIN\n");
if (size+2 != sz) {
fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__,
size+2, sz);
exit(1);
}
program ++;
for (i = 1 ; i < sz ; i+=3, program+=3) {
GLuint opcode = program[0] & (0x1f<<24);
if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT)
print_arith_op(opcode >> 24, program);
else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL)
print_tex_op(opcode >> 24, program);
else if (opcode == D0_DCL)
print_dcl_op(opcode >> 24, program);
else
fprintf(stderr, "Unknown opcode 0x%x\n", opcode);
}
fprintf(stderr, "END\n\n");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,711 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "utils.h"
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "intel_rotate.h"
#include "i915_context.h"
#include "i915_reg.h"
/* A large amount of state doesn't need to be uploaded.
*/
#define ACTIVE (I915_UPLOAD_INVARIENT | \
I915_UPLOAD_PROGRAM | \
I915_UPLOAD_STIPPLE | \
I915_UPLOAD_CTX | \
I915_UPLOAD_BUFFERS | \
I915_UPLOAD_TEX(0))
#define SET_STATE( i915, STATE ) \
do { \
i915->current->emitted &= ~ACTIVE; \
i915->current = &i915->STATE; \
i915->current->emitted &= ~ACTIVE; \
} while (0)
/* Operations where the 3D engine is decoupled temporarily from the
* current GL state and used for other purposes than simply rendering
* incoming triangles.
*/
static void set_initial_state( i915ContextPtr i915 )
{
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
i915->meta.active = ACTIVE;
i915->meta.emitted = 0;
}
static void set_no_depth_stencil_write( i915ContextPtr i915 )
{
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
*/
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
S5_STENCIL_WRITE_ENABLE);
/* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
*/
i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE |
S6_DEPTH_WRITE_ENABLE);
i915->meta.emitted &= ~I915_UPLOAD_CTX;
}
/* Set stencil unit to replace always with the reference value.
*/
static void set_stencil_replace( i915ContextPtr i915,
GLuint s_mask,
GLuint s_clear)
{
GLuint op = STENCILOP_REPLACE;
GLuint func = COMPAREFUNC_ALWAYS;
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE )
*/
i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE |
S5_STENCIL_WRITE_ENABLE);
/* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
*/
i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE |
S6_DEPTH_WRITE_ENABLE);
/* ctx->Driver.StencilMask( ctx, s_mask )
*/
i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(s_mask));
/* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
*/
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
S5_STENCIL_PASS_Z_FAIL_MASK |
S5_STENCIL_PASS_Z_PASS_MASK);
i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) |
(op << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
(op << S5_STENCIL_PASS_Z_PASS_SHIFT));
/* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 )
*/
i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
STENCIL_TEST_MASK(0xff));
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |
S5_STENCIL_TEST_FUNC_MASK);
i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) |
(func << S5_STENCIL_TEST_FUNC_SHIFT));
i915->meta.emitted &= ~I915_UPLOAD_CTX;
}
static void set_color_mask( i915ContextPtr i915, GLboolean state )
{
const GLuint mask = (S5_WRITEDISABLE_RED |
S5_WRITEDISABLE_GREEN |
S5_WRITEDISABLE_BLUE |
S5_WRITEDISABLE_ALPHA);
/* Copy colormask state from "regular" hw context.
*/
if (state) {
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask;
i915->meta.Ctx[I915_CTXREG_LIS5] |=
(i915->state.Ctx[I915_CTXREG_LIS5] & mask);
}
else
i915->meta.Ctx[I915_CTXREG_LIS5] |= mask;
i915->meta.emitted &= ~I915_UPLOAD_CTX;
}
#define REG( type, nr ) (((type)<<5)|(nr))
#define REG_R(x) REG(REG_TYPE_R, x)
#define REG_T(x) REG(REG_TYPE_T, x)
#define REG_CONST(x) REG(REG_TYPE_CONST, x)
#define REG_S(x) REG(REG_TYPE_S, x)
#define REG_OC REG(REG_TYPE_OC, 0)
#define REG_OD REG(REG_TYPE_OD, 0)
#define REG_U(x) REG(REG_TYPE_U, x)
#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE)
#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR)
#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W)
#define REG_T_TEX(x) REG(REG_TYPE_T, x)
#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT )
#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT )
#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT )
#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT )
#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT )
#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT )
#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT )
#define T0_SAMPLER( unit ) ((unit)<<T0_SAMPLER_NR_SHIFT)
#define T1_ADDRESS_REG( type, nr ) (((type)<<T1_ADDRESS_REG_TYPE_SHIFT)| \
((nr)<<T1_ADDRESS_REG_NR_SHIFT))
#define A1_SRC0_XYZW ((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \
(SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \
(SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \
(SRC_W << A1_SRC0_CHANNEL_W_SHIFT))
#define A1_SRC1_XY ((SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \
(SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT))
#define A2_SRC1_ZW ((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \
(SRC_W << A2_SRC1_CHANNEL_W_SHIFT))
#define A2_SRC2_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \
(SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \
(SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \
(SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
static void set_no_texture( i915ContextPtr i915 )
{
static const GLuint prog[] = {
_3DSTATE_PIXEL_SHADER_PROGRAM,
/* Declare incoming diffuse color:
*/
(D0_DCL |
D0_DECL_REG( REG_T_DIFFUSE ) |
D0_CHANNEL_ALL),
D1_MBZ,
D2_MBZ,
/* output-color = mov(t_diffuse)
*/
(A0_MOV |
A0_DEST_REG( REG_OC ) |
A0_DEST_CHANNEL_ALL |
A0_SRC0_REG( REG_T_DIFFUSE )),
(A1_SRC0_XYZW),
0,
};
memcpy( i915->meta.Program, prog, sizeof(prog) );
i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog);
i915->meta.Program[0] |= i915->meta.ProgramSize - 2;
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
}
static void enable_texture_blend_replace( i915ContextPtr i915 )
{
static const GLuint prog[] = {
_3DSTATE_PIXEL_SHADER_PROGRAM,
/* Declare the sampler:
*/
(D0_DCL |
D0_DECL_REG( REG_S(0) ) |
D0_SAMPLE_TYPE_2D |
D0_CHANNEL_NONE),
D1_MBZ,
D2_MBZ,
/* Declare the interpolated texture coordinate:
*/
(D0_DCL |
D0_DECL_REG( REG_T_TEX(0) ) |
D0_CHANNEL_ALL),
D1_MBZ,
D2_MBZ,
/* output-color = texld(sample0, texcoord0)
*/
(T0_TEXLD |
T0_DEST_REG( REG_OC ) |
T0_SAMPLER( 0 )),
T1_ADDRESS_REG(REG_TYPE_T, 0),
T2_MBZ
};
memcpy( i915->meta.Program, prog, sizeof(prog) );
i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog);
i915->meta.Program[0] |= i915->meta.ProgramSize - 2;
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
}
/* Set up an arbitary piece of memory as a rectangular texture
* (including the front or back buffer).
*/
static void set_tex_rect_source( i915ContextPtr i915,
GLuint offset,
GLuint width,
GLuint height,
GLuint pitch, /* in bytes! */
GLuint textureFormat )
{
GLuint unit = 0;
GLint numLevels = 1;
GLuint *state = i915->meta.Tex[0];
#if 0
printf("TexRect source offset 0x%x pitch %d\n", offset, pitch);
#endif
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
state[I915_TEXREG_MS2] = offset;
state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) |
((width - 1) << MS3_WIDTH_SHIFT) |
textureFormat |
MS3_USE_FENCE_REGS);
state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) |
(MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) |
(FILTER_NEAREST << SS2_MAG_FILTER_SHIFT));
state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) |
(TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) |
(TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) |
(unit<<SS3_TEXTUREMAP_INDEX_SHIFT));
state[I915_TEXREG_SS4] = 0;
i915->meta.emitted &= ~I915_UPLOAD_TEX(0);
}
/* Select between front and back draw buffers.
*/
static void set_draw_region( i915ContextPtr i915, const intelRegion *region )
{
#if 0
printf("Rotate into region: offset 0x%x pitch %d\n",
region->offset, region->pitch);
#endif
i915->meta.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = region->offset;
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
}
#if 0
/* Setup an arbitary draw format, useful for targeting texture or agp
* memory.
*/
static void set_draw_format( i915ContextPtr i915,
GLuint format,
GLuint depth_format)
{
i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
format |
LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL |
depth_format);
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
/* fprintf(stderr, "%s: DV1: %x\n", */
/* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */
}
#endif
static void set_vertex_format( i915ContextPtr i915 )
{
i915->meta.Ctx[I915_CTXREG_LIS2] =
(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK;
i915->meta.Ctx[I915_CTXREG_LIS4] |=
(S4_VFMT_COLOR |
S4_VFMT_SPEC_FOG |
S4_VFMT_XYZW);
i915->meta.emitted &= ~I915_UPLOAD_CTX;
}
static void draw_quad(i915ContextPtr i915,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1 )
{
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
PRIM3D_TRIFAN,
4 * vertex_size,
vertex_size );
intelVertex tmp;
int i;
if (0)
fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n",
__FUNCTION__,
x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1);
/* initial vertex, left bottom */
tmp.v.x = x0;
tmp.v.y = y0;
tmp.v.z = 1.0;
tmp.v.w = 1.0;
tmp.v.color.red = red;
tmp.v.color.green = green;
tmp.v.color.blue = blue;
tmp.v.color.alpha = alpha;
tmp.v.specular.red = 0;
tmp.v.specular.green = 0;
tmp.v.specular.blue = 0;
tmp.v.specular.alpha = 0;
tmp.v.u0 = s0;
tmp.v.v0 = t0;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* right bottom */
vb += vertex_size;
tmp.v.x = x1;
tmp.v.u0 = s1;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* right top */
vb += vertex_size;
tmp.v.y = y1;
tmp.v.v0 = t1;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
/* left top */
vb += vertex_size;
tmp.v.x = x0;
tmp.v.u0 = s0;
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
}
static void draw_poly(i915ContextPtr i915,
GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha,
GLuint numVerts,
/*const*/ GLfloat verts[][2],
/*const*/ GLfloat texcoords[][2])
{
GLuint vertex_size = 8;
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
PRIM3D_TRIFAN,
numVerts * vertex_size,
vertex_size );
intelVertex tmp;
int i, k;
/* initial constant vertex fields */
tmp.v.z = 1.0;
tmp.v.w = 1.0;
tmp.v.color.red = red;
tmp.v.color.green = green;
tmp.v.color.blue = blue;
tmp.v.color.alpha = alpha;
tmp.v.specular.red = 0;
tmp.v.specular.green = 0;
tmp.v.specular.blue = 0;
tmp.v.specular.alpha = 0;
for (k = 0; k < numVerts; k++) {
tmp.v.x = verts[k][0];
tmp.v.y = verts[k][1];
tmp.v.u0 = texcoords[k][0];
tmp.v.v0 = texcoords[k][1];
for (i = 0 ; i < vertex_size ; i++)
vb[i] = tmp.ui[i];
vb += vertex_size;
}
}
void
i915ClearWithTris(intelContextPtr intel, GLbitfield buffers,
GLboolean allFoo,
GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo)
{
i915ContextPtr i915 = I915_CONTEXT( intel );
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
GLint cx, cy, cw, ch;
GLboolean all;
SET_STATE( i915, meta );
set_initial_state( i915 );
set_no_texture( i915 );
set_vertex_format( i915 );
LOCK_HARDWARE(intel);
/* get clear bounds after locking */
cx = intel->ctx.DrawBuffer->_Xmin;
cy = intel->ctx.DrawBuffer->_Ymin;
cw = intel->ctx.DrawBuffer->_Xmax - cx;
ch = intel->ctx.DrawBuffer->_Ymax - cy;
all = (cw == intel->ctx.DrawBuffer->Width &&
ch == intel->ctx.DrawBuffer->Height);
if (!all) {
x0 = cx;
y0 = cy;
x1 = x0 + cw;
y1 = y0 + ch;
} else {
x0 = 0;
y0 = 0;
x1 = x0 + dPriv->w;
y1 = y0 + dPriv->h;
}
/* Don't do any clipping to screen - these are window coordinates.
* The active cliprects will be applied as for any other geometry.
*/
if (buffers & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
set_draw_region( i915, &screen->front );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if (buffers & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
set_draw_region( i915, &screen->back );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
0, 0, 0, 0);
}
if (buffers & BUFFER_BIT_STENCIL) {
set_stencil_replace( i915,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
set_color_mask( i915, GL_FALSE );
set_draw_region( i915, &screen->front ); /* could be either? */
draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
UNLOCK_HARDWARE(intel);
SET_STATE( i915, state );
}
/**
* Copy the window contents named by dPriv to the rotated (or reflected)
* color buffer.
* srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
*/
void
i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuf)
{
i915ContextPtr i915 = I915_CONTEXT( intel );
intelScreenPrivate *screen = intel->intelScreen;
const GLuint cpp = screen->cpp;
drm_clip_rect_t fullRect;
GLuint textureFormat, srcOffset, srcPitch;
const drm_clip_rect_t *clipRects;
int numClipRects;
int i;
int xOrig, yOrig;
int origNumClipRects;
drm_clip_rect_t *origRects;
/*
* set up hardware state
*/
intelFlush( &intel->ctx );
SET_STATE( i915, meta );
set_initial_state( i915 );
set_no_texture( i915 );
set_vertex_format( i915 );
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
LOCK_HARDWARE(intel);
/* save current drawing origin and cliprects (restored at end) */
xOrig = intel->drawX;
yOrig = intel->drawY;
origNumClipRects = intel->numClipRects;
origRects = intel->pClipRects;
if (!intel->numClipRects)
goto done;
/*
* set drawing origin, cliprects for full-screen access to rotated screen
*/
fullRect.x1 = 0;
fullRect.y1 = 0;
fullRect.x2 = screen->rotatedWidth;
fullRect.y2 = screen->rotatedHeight;
intel->drawX = 0;
intel->drawY = 0;
intel->numClipRects = 1;
intel->pClipRects = &fullRect;
set_draw_region( i915, &screen->rotated );
if (cpp == 4)
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
else
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
if (srcBuf == BUFFER_BIT_FRONT_LEFT) {
srcPitch = screen->front.pitch; /* in bytes */
srcOffset = screen->front.offset; /* bytes */
clipRects = dPriv->pClipRects;
numClipRects = dPriv->numClipRects;
}
else {
srcPitch = screen->back.pitch; /* in bytes */
srcOffset = screen->back.offset; /* bytes */
clipRects = dPriv->pBackClipRects;
numClipRects = dPriv->numBackClipRects;
}
/* set the whole screen up as a texture to avoid alignment issues */
set_tex_rect_source(i915,
srcOffset,
screen->width,
screen->height,
srcPitch,
textureFormat);
enable_texture_blend_replace(i915);
/*
* loop over the source window's cliprects
*/
for (i = 0; i < numClipRects; i++) {
int srcX0 = clipRects[i].x1;
int srcY0 = clipRects[i].y1;
int srcX1 = clipRects[i].x2;
int srcY1 = clipRects[i].y2;
GLfloat verts[4][2], tex[4][2];
int j;
/* build vertices for four corners of clip rect */
verts[0][0] = srcX0; verts[0][1] = srcY0;
verts[1][0] = srcX1; verts[1][1] = srcY0;
verts[2][0] = srcX1; verts[2][1] = srcY1;
verts[3][0] = srcX0; verts[3][1] = srcY1;
/* .. and texcoords */
tex[0][0] = srcX0; tex[0][1] = srcY0;
tex[1][0] = srcX1; tex[1][1] = srcY0;
tex[2][0] = srcX1; tex[2][1] = srcY1;
tex[3][0] = srcX0; tex[3][1] = srcY1;
/* transform coords to rotated screen coords */
for (j = 0; j < 4; j++) {
matrix23TransformCoordf(&screen->rotMatrix,
&verts[j][0], &verts[j][1]);
}
/* draw polygon to map source image to dest region */
draw_poly(i915, 255, 255, 255, 255, 4, verts, tex);
} /* cliprect loop */
intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE );
done:
/* restore original drawing origin and cliprects */
intel->drawX = xOrig;
intel->drawY = yOrig;
intel->numClipRects = origNumClipRects;
intel->pClipRects = origRects;
UNLOCK_HARDWARE(intel);
SET_STATE( i915, state );
}

View File

@ -1,499 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <strings.h>
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "tnl/t_context.h"
#include "intel_batchbuffer.h"
#include "i915_reg.h"
#include "i915_context.h"
#include "i915_program.h"
#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
/* These are special, and don't have swizzle/negate bits.
*/
#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
(GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
/* Macros for translating UREG's into the various register fields used
* by the I915 programmable unit.
*/
#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
#define UREG_MASK 0xffffff00
#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
(REG_NR_MASK << UREG_NR_SHIFT))
#define I915_CONSTFLAG_PARAM 0x1f
GLuint i915_get_temp( struct i915_fragment_program *p )
{
int bit = ffs( ~p->temp_flag );
if (!bit) {
fprintf(stderr, "%s: out of temporaries\n", __FILE__);
exit(1);
}
p->temp_flag |= 1<<(bit-1);
return UREG(REG_TYPE_R, (bit-1));
}
GLuint i915_get_utemp( struct i915_fragment_program *p )
{
int bit = ffs( ~p->utemp_flag );
if (!bit) {
fprintf(stderr, "%s: out of temporaries\n", __FILE__);
exit(1);
}
p->utemp_flag |= 1<<(bit-1);
return UREG(REG_TYPE_U, (bit-1));
}
void i915_release_utemps( struct i915_fragment_program *p )
{
p->utemp_flag = ~0x7;
}
GLuint i915_emit_decl( struct i915_fragment_program *p,
GLuint type, GLuint nr, GLuint d0_flags )
{
GLuint reg = UREG(type, nr);
if (type == REG_TYPE_T) {
if (p->decl_t & (1<<nr))
return reg;
p->decl_t |= (1<<nr);
}
else if (type == REG_TYPE_S) {
if (p->decl_s & (1<<nr))
return reg;
p->decl_s |= (1<<nr);
}
else
return reg;
*(p->decl++) = (D0_DCL | D0_DEST( reg ) | d0_flags);
*(p->decl++) = D1_MBZ;
*(p->decl++) = D2_MBZ;
p->nr_decl_insn++;
return reg;
}
GLuint i915_emit_arith( struct i915_fragment_program *p,
GLuint op,
GLuint dest,
GLuint mask,
GLuint saturate,
GLuint src0,
GLuint src1,
GLuint src2 )
{
GLuint c[3];
GLuint nr_const = 0;
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) c[nr_const++] = 0;
if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) c[nr_const++] = 1;
if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) c[nr_const++] = 2;
/* Recursively call this function to MOV additional const values
* into temporary registers. Use utemp registers for this -
* currently shouldn't be possible to run out, but keep an eye on
* this.
*/
if (nr_const > 1) {
GLuint s[3], first, i, old_utemp_flag;
s[0] = src0;
s[1] = src1;
s[2] = src2;
old_utemp_flag = p->utemp_flag;
first = GET_UREG_NR(s[c[0]]);
for (i = 1 ; i < nr_const ; i++) {
if (GET_UREG_NR(s[c[i]]) != first) {
GLuint tmp = i915_get_utemp(p);
i915_emit_arith( p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
s[c[i]], 0, 0 );
s[c[i]] = tmp;
}
}
src0 = s[0];
src1 = s[1];
src2 = s[2];
p->utemp_flag = old_utemp_flag; /* restore */
}
*(p->csr++) = (op |
A0_DEST( dest ) |
mask |
saturate |
A0_SRC0( src0 ));
*(p->csr++) = (A1_SRC0( src0 ) |
A1_SRC1( src1 ));
*(p->csr++) = (A2_SRC1( src1 ) |
A2_SRC2( src2 ));
p->nr_alu_insn++;
return dest;
}
GLuint i915_emit_texld( struct i915_fragment_program *p,
GLuint dest,
GLuint destmask,
GLuint sampler,
GLuint coord,
GLuint op )
{
if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
/* No real way to work around this in the general case - need to
* allocate and declare a new temporary register (a utemp won't
* do). Will fallback for now.
*/
i915_program_error(p, "Can't (yet) swizzle TEX arguments");
return 0;
}
/* Don't worry about saturate as we only support
*/
if (destmask != A0_DEST_CHANNEL_ALL) {
GLuint tmp = i915_get_utemp(p);
i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
return dest;
}
else {
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
p->nr_tex_indirect++;
}
*(p->csr++) = (op |
T0_DEST( dest ) |
T0_SAMPLER( sampler ));
*(p->csr++) = T1_ADDRESS_REG( coord );
*(p->csr++) = T2_MBZ;
p->nr_tex_insn++;
return dest;
}
}
GLuint i915_emit_const1f( struct i915_fragment_program *p, GLfloat c0 )
{
GLint reg, idx;
if (c0 == 0.0) return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
if (c0 == 1.0) return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE );
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
continue;
for (idx = 0; idx < 4; idx++) {
if (!(p->constant_flags[reg] & (1<<idx)) ||
p->constant[reg][idx] == c0) {
p->constant[reg][idx] = c0;
p->constant_flags[reg] |= 1<<idx;
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
return swizzle(UREG(REG_TYPE_CONST, reg),idx,ZERO,ZERO,ONE);
}
}
}
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
p->error = 1;
return 0;
}
GLuint i915_emit_const2f( struct i915_fragment_program *p,
GLfloat c0, GLfloat c1 )
{
GLint reg, idx;
if (c0 == 0.0) return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
if (c0 == 1.0) return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
if (c1 == 0.0) return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
if (c1 == 1.0) return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (p->constant_flags[reg] == 0xf ||
p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
continue;
for (idx = 0; idx < 3; idx++) {
if (!(p->constant_flags[reg] & (3<<idx))) {
p->constant[reg][idx] = c0;
p->constant[reg][idx+1] = c1;
p->constant_flags[reg] |= 3<<idx;
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
return swizzle(UREG(REG_TYPE_CONST, reg),idx,idx+1,ZERO,ONE);
}
}
}
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
p->error = 1;
return 0;
}
GLuint i915_emit_const4f( struct i915_fragment_program *p,
GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3 )
{
GLint reg;
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (p->constant_flags[reg] == 0xf &&
p->constant[reg][0] == c0 &&
p->constant[reg][1] == c1 &&
p->constant[reg][2] == c2 &&
p->constant[reg][3] == c3) {
return UREG(REG_TYPE_CONST, reg);
}
else if (p->constant_flags[reg] == 0) {
p->constant[reg][0] = c0;
p->constant[reg][1] = c1;
p->constant[reg][2] = c2;
p->constant[reg][3] = c3;
p->constant_flags[reg] = 0xf;
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
return UREG(REG_TYPE_CONST, reg);
}
}
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
p->error = 1;
return 0;
}
GLuint i915_emit_const4fv( struct i915_fragment_program *p, const GLfloat *c )
{
return i915_emit_const4f( p, c[0], c[1], c[2], c[3] );
}
GLuint i915_emit_param4fv( struct i915_fragment_program *p,
const GLfloat *values )
{
GLint reg, i;
for (i = 0; i < p->nr_params; i++) {
if (p->param[i].values == values)
return UREG(REG_TYPE_CONST, p->param[i].reg);
}
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (p->constant_flags[reg] == 0) {
p->constant_flags[reg] = I915_CONSTFLAG_PARAM;
i = p->nr_params++;
p->param[i].values = values;
p->param[i].reg = reg;
p->params_uptodate = 0;
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
return UREG(REG_TYPE_CONST, reg);
}
}
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
p->error = 1;
return 0;
}
void i915_program_error( struct i915_fragment_program *p, const char *msg )
{
_mesa_problem(NULL, "i915_program_error: %s", msg);
p->error = 1;
}
void i915_init_program( i915ContextPtr i915, struct i915_fragment_program *p )
{
GLcontext *ctx = &i915->intel.ctx;
TNLcontext *tnl = TNL_CONTEXT( ctx );
p->translated = 0;
p->params_uptodate = 0;
p->on_hardware = 0;
p->error = 0;
p->nr_tex_indirect = 1; /* correct? */
p->nr_tex_insn = 0;
p->nr_alu_insn = 0;
p->nr_decl_insn = 0;
p->ctx = ctx;
memset( p->constant_flags, 0, sizeof(p->constant_flags) );
p->nr_constants = 0;
p->csr = p->program;
p->decl = p->declarations;
p->decl_s = 0;
p->decl_t = 0;
p->temp_flag = 0xffff000;
p->utemp_flag = ~0x7;
p->wpos_tex = -1;
p->depth_written = 0;
p->nr_params = 0;
p->src_texture = UREG_BAD;
p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE);
p->last_tex_stage = 0;
p->VB = &tnl->vb;
*(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
}
void i915_fini_program( struct i915_fragment_program *p )
{
GLuint program_size = p->csr - p->program;
GLuint decl_size = p->decl - p->declarations;
if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
i915_program_error(p, "Exceeded max nr indirect texture lookups");
if (p->nr_tex_insn > I915_MAX_TEX_INSN)
i915_program_error(p, "Exceeded max TEX instructions");
if (p->nr_alu_insn > I915_MAX_ALU_INSN)
i915_program_error(p, "Exceeded max ALU instructions");
if (p->nr_decl_insn > I915_MAX_DECL_INSN)
i915_program_error(p, "Exceeded max DECL instructions");
if (p->error) {
p->FragProg.Base.NumNativeInstructions = 0;
p->FragProg.Base.NumNativeAluInstructions = 0;
p->FragProg.Base.NumNativeTexInstructions = 0;
p->FragProg.Base.NumNativeTexIndirections = 0;
}
else {
p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
p->nr_tex_insn +
p->nr_decl_insn);
p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn;
p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn;
p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect;
}
p->declarations[0] |= program_size + decl_size - 2;
}
void i915_upload_program( i915ContextPtr i915, struct i915_fragment_program *p )
{
GLuint program_size = p->csr - p->program;
GLuint decl_size = p->decl - p->declarations;
FALLBACK( &i915->intel, I915_FALLBACK_PROGRAM, p->error );
/* Could just go straight to the batchbuffer from here:
*/
if (i915->state.ProgramSize != (program_size + decl_size) ||
memcmp(i915->state.Program + decl_size, p->program,
program_size*sizeof(int)) != 0) {
I915_STATECHANGE( i915, I915_UPLOAD_PROGRAM );
memcpy(i915->state.Program, p->declarations, decl_size*sizeof(int));
memcpy(i915->state.Program + decl_size, p->program,
program_size*sizeof(int));
i915->state.ProgramSize = decl_size + program_size;
}
/* Always seemed to get a failure if I used memcmp() to
* shortcircuit this state upload. Needs further investigation?
*/
if (p->nr_constants) {
GLuint nr = p->nr_constants;
I915_ACTIVESTATE( i915, I915_UPLOAD_CONSTANTS, 1 );
I915_STATECHANGE( i915, I915_UPLOAD_CONSTANTS );
i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4);
i915->state.Constant[1] = (1<<(nr-1)) | ((1<<(nr-1))-1);
memcpy(&i915->state.Constant[2], p->constant, 4*sizeof(int)*(nr));
i915->state.ConstantSize = 2 + (nr) * 4;
if (0) {
GLuint i;
for (i = 0; i < nr; i++) {
fprintf(stderr, "const[%d]: %f %f %f %f\n", i,
p->constant[i][0],
p->constant[i][1],
p->constant[i][2],
p->constant[i][3]);
}
}
}
else {
I915_ACTIVESTATE( i915, I915_UPLOAD_CONSTANTS, 0 );
}
p->on_hardware = 1;
}

View File

@ -1,163 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef I915_PROGRAM_H
#define I915_PROGRAM_H
#include "i915_context.h"
#include "i915_reg.h"
/* Having zero and one in here makes the definition of swizzle a lot
* easier.
*/
#define UREG_TYPE_SHIFT 29
#define UREG_NR_SHIFT 24
#define UREG_CHANNEL_X_NEGATE_SHIFT 23
#define UREG_CHANNEL_X_SHIFT 20
#define UREG_CHANNEL_Y_NEGATE_SHIFT 19
#define UREG_CHANNEL_Y_SHIFT 16
#define UREG_CHANNEL_Z_NEGATE_SHIFT 15
#define UREG_CHANNEL_Z_SHIFT 12
#define UREG_CHANNEL_W_NEGATE_SHIFT 11
#define UREG_CHANNEL_W_SHIFT 8
#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5
#define UREG_CHANNEL_ZERO_SHIFT 4
#define UREG_CHANNEL_ONE_NEGATE_MBZ 1
#define UREG_CHANNEL_ONE_SHIFT 0
#define UREG_BAD 0xffffffff /* not a valid ureg */
#define X SRC_X
#define Y SRC_Y
#define Z SRC_Z
#define W SRC_W
#define ZERO SRC_ZERO
#define ONE SRC_ONE
/* Construct a ureg:
*/
#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \
((nr) << UREG_NR_SHIFT) | \
(X << UREG_CHANNEL_X_SHIFT) | \
(Y << UREG_CHANNEL_Y_SHIFT) | \
(Z << UREG_CHANNEL_Z_SHIFT) | \
(W << UREG_CHANNEL_W_SHIFT) | \
(ZERO << UREG_CHANNEL_ZERO_SHIFT) | \
(ONE << UREG_CHANNEL_ONE_SHIFT))
#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)&REG_TYPE_MASK)
#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)&REG_NR_MASK)
#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
/* One neat thing about the UREG representation:
*/
static __inline int swizzle( int reg, int x, int y, int z, int w )
{
return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
CHANNEL_SRC( GET_CHANNEL_SRC( reg, x ), 0 ) |
CHANNEL_SRC( GET_CHANNEL_SRC( reg, y ), 1 ) |
CHANNEL_SRC( GET_CHANNEL_SRC( reg, z ), 2 ) |
CHANNEL_SRC( GET_CHANNEL_SRC( reg, w ), 3 ));
}
/* Another neat thing about the UREG representation:
*/
static __inline int negate( int reg, int x, int y, int z, int w )
{
return reg ^ (((x&1)<<UREG_CHANNEL_X_NEGATE_SHIFT)|
((y&1)<<UREG_CHANNEL_Y_NEGATE_SHIFT)|
((z&1)<<UREG_CHANNEL_Z_NEGATE_SHIFT)|
((w&1)<<UREG_CHANNEL_W_NEGATE_SHIFT));
}
extern GLuint i915_get_temp( struct i915_fragment_program *p );
extern GLuint i915_get_utemp( struct i915_fragment_program *p );
extern void i915_release_utemps( struct i915_fragment_program *p );
extern GLuint i915_emit_texld( struct i915_fragment_program *p,
GLuint dest,
GLuint destmask,
GLuint sampler,
GLuint coord,
GLuint op );
extern GLuint i915_emit_arith( struct i915_fragment_program *p,
GLuint op,
GLuint dest,
GLuint mask,
GLuint saturate,
GLuint src0,
GLuint src1,
GLuint src2 );
extern GLuint i915_emit_decl( struct i915_fragment_program *p,
GLuint type, GLuint nr, GLuint d0_flags );
extern GLuint i915_emit_const1f( struct i915_fragment_program *p,
GLfloat c0 );
extern GLuint i915_emit_const2f( struct i915_fragment_program *p,
GLfloat c0, GLfloat c1 );
extern GLuint i915_emit_const4fv( struct i915_fragment_program *p,
const GLfloat *c );
extern GLuint i915_emit_const4f( struct i915_fragment_program *p,
GLfloat c0, GLfloat c1,
GLfloat c2, GLfloat c3 );
extern GLuint i915_emit_param4fv( struct i915_fragment_program *p,
const GLfloat *values );
extern void i915_program_error( struct i915_fragment_program *p,
const char *msg );
extern void i915_init_program( i915ContextPtr i915,
struct i915_fragment_program *p );
extern void i915_upload_program( i915ContextPtr i915,
struct i915_fragment_program *p );
extern void i915_fini_program( struct i915_fragment_program *p );
#endif

View File

@ -1,835 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _I915_REG_H_
#define _I915_REG_H_
#include "intel_reg.h"
#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
#define CMD_3D (0x3<<29)
#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
#define PRIM3D_TRILIST (0x0<<18)
#define PRIM3D_TRISTRIP (0x1<<18)
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
#define PRIM3D_TRIFAN (0x3<<18)
#define PRIM3D_POLY (0x4<<18)
#define PRIM3D_LINELIST (0x5<<18)
#define PRIM3D_LINESTRIP (0x6<<18)
#define PRIM3D_RECTLIST (0x7<<18)
#define PRIM3D_POINTLIST (0x8<<18)
#define PRIM3D_DIB (0x9<<18)
#define PRIM3D_CLEAR_RECT (0xa<<18)
#define PRIM3D_ZONE_INIT (0xd<<18)
#define PRIM3D_MASK (0x1f<<18)
/* p137 */
#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24))
#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16)
#define AA_LINE_ECAAR_WIDTH_0_5 0
#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14)
#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14)
#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14)
#define AA_LINE_REGION_WIDTH_ENABLE (1<<8)
#define AA_LINE_REGION_WIDTH_0_5 0
#define AA_LINE_REGION_WIDTH_1_0 (1<<6)
#define AA_LINE_REGION_WIDTH_2_0 (2<<6)
#define AA_LINE_REGION_WIDTH_4_0 (3<<6)
/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/
#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24))
#define BFO_ENABLE_STENCIL_REF (1<<23)
#define BFO_STENCIL_REF_SHIFT 15
#define BFO_STENCIL_REF_MASK (0xff<<15)
#define BFO_ENABLE_STENCIL_FUNCS (1<<14)
#define BFO_STENCIL_TEST_SHIFT 11
#define BFO_STENCIL_TEST_MASK (0x7<<11)
#define BFO_STENCIL_FAIL_SHIFT 8
#define BFO_STENCIL_FAIL_MASK (0x7<<8)
#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5
#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5)
#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2
#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2)
#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1)
#define BFO_STENCIL_TWO_SIDE (1<<0)
/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */
#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24))
#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17)
#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16)
#define BFM_STENCIL_TEST_MASK_SHIFT 8
#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8)
#define BFM_STENCIL_WRITE_MASK_SHIFT 0
#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0)
/* 3DSTATE_BIN_CONTROL p141 */
/* p143 */
#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
/* Dword 1 */
#define BUF_3D_ID_COLOR_BACK (0x3<<24)
#define BUF_3D_ID_DEPTH (0x7<<24)
#define BUF_3D_USE_FENCE (1<<23)
#define BUF_3D_TILED_SURFACE (1<<22)
#define BUF_3D_TILE_WALK_X 0
#define BUF_3D_TILE_WALK_Y (1<<21)
#define BUF_3D_PITCH(x) (((x)/4)<<2)
/* Dword 2 */
#define BUF_3D_ADDR(x) ((x) & ~0x3)
/* 3DSTATE_CHROMA_KEY */
/* 3DSTATE_CLEAR_PARAMETERS, p150 */
/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */
#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16))
/* 3DSTATE_COORD_SET_BINDINGS, p154 */
#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24))
#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3))
/* p156 */
#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16))
/* p157 */
#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16))
/* p158 */
#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16))
/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */
#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16))
/* scale in dword 1 */
/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */
#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | 0x2)
/* p161 */
#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16))
/* Dword 1 */
#define TEX_DEFAULT_COLOR_OGL (0<<30)
#define TEX_DEFAULT_COLOR_D3D (1<<30)
#define ZR_EARLY_DEPTH (1<<29)
#define LOD_PRECLAMP_OGL (1<<28)
#define LOD_PRECLAMP_D3D (0<<28)
#define DITHER_FULL_ALWAYS (0<<26)
#define DITHER_FULL_ON_FB_BLEND (1<<26)
#define DITHER_CLAMPED_ALWAYS (2<<26)
#define LINEAR_GAMMA_BLEND_32BPP (1<<25)
#define DEBUG_DISABLE_ENH_DITHER (1<<24)
#define DSTORG_HORT_BIAS(x) ((x)<<20)
#define DSTORG_VERT_BIAS(x) ((x)<<16)
#define COLOR_4_2_2_CHNL_WRT_ALL 0
#define COLOR_4_2_2_CHNL_WRT_Y (1<<12)
#define COLOR_4_2_2_CHNL_WRT_CR (2<<12)
#define COLOR_4_2_2_CHNL_WRT_CB (3<<12)
#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12)
#define COLR_BUF_8BIT 0
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
#define DEPTH_FRMT_16_FIXED 0
#define DEPTH_FRMT_16_FLOAT (1<<2)
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
#define VERT_LINE_STRIDE_1 (1<<1)
#define VERT_LINE_STRIDE_0 (0<<1)
#define VERT_LINE_STRIDE_OFS_1 1
#define VERT_LINE_STRIDE_OFS_0 0
/* p166 */
#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3)
/* Dword 1 */
#define DRAW_RECT_DIS_DEPTH_OFS (1<<30)
#define DRAW_DITHER_OFS_X(x) ((x)<<26)
#define DRAW_DITHER_OFS_Y(x) ((x)<<24)
/* Dword 2 */
#define DRAW_YMIN(x) ((x)<<16)
#define DRAW_XMIN(x) (x)
/* Dword 3 */
#define DRAW_YMAX(x) ((x)<<16)
#define DRAW_XMAX(x) (x)
/* Dword 4 */
#define DRAW_YORG(x) ((x)<<16)
#define DRAW_XORG(x) (x)
/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */
/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */
/* _3DSTATE_FOG_COLOR, p173 */
#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24))
#define FOG_COLOR_RED(x) ((x)<<16)
#define FOG_COLOR_GREEN(x) ((x)<<8)
#define FOG_COLOR_BLUE(x) (x)
/* _3DSTATE_FOG_MODE, p174 */
#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2)
/* Dword 1 */
#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31)
#define FMC1_FOGFUNC_VERTEX (0<<28)
#define FMC1_FOGFUNC_PIXEL_EXP (1<<28)
#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28)
#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28)
#define FMC1_FOGFUNC_MASK (3<<28)
#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27)
#define FMC1_FOGINDEX_Z (0<<25)
#define FMC1_FOGINDEX_W (1<<25)
#define FMC1_C1_C2_MODIFY_ENABLE (1<<24)
#define FMC1_DENSITY_MODIFY_ENABLE (1<<23)
#define FMC1_C1_ONE (1<<13)
#define FMC1_C1_MASK (0xffff<<4)
/* Dword 2 */
#define FMC2_C2_ONE (1<<16)
/* Dword 3 */
#define FMC3_D_ONE (1<<16)
/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */
#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24))
#define IAB_MODIFY_ENABLE (1<<23)
#define IAB_ENABLE (1<<22)
#define IAB_MODIFY_FUNC (1<<21)
#define IAB_FUNC_SHIFT 16
#define IAB_MODIFY_SRC_FACTOR (1<<11)
#define IAB_SRC_FACTOR_SHIFT 6
#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6)
#define IAB_MODIFY_DST_FACTOR (1<<5)
#define IAB_DST_FACTOR_SHIFT 0
#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0)
#define BLENDFUNC_ADD 0x0
#define BLENDFUNC_SUBTRACT 0x1
#define BLENDFUNC_REVERSE_SUBTRACT 0x2
#define BLENDFUNC_MIN 0x3
#define BLENDFUNC_MAX 0x4
#define BLENDFUNC_MASK 0x7
/* 3DSTATE_LOAD_INDIRECT, p180 */
#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16))
#define LI0_STATE_STATIC_INDIRECT (0x01<<8)
#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8)
#define LI0_STATE_SAMPLER (0x04<<8)
#define LI0_STATE_MAP (0x08<<8)
#define LI0_STATE_PROGRAM (0x10<<8)
#define LI0_STATE_CONSTANTS (0x20<<8)
#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define SIS0_FORCE_LOAD (1<<1)
#define SIS0_BUFFER_VALID (1<<0)
#define SIS1_BUFFER_LENGTH(x) ((x)&0xff)
#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define DIS0_BUFFER_RESET (1<<1)
#define DIS0_BUFFER_VALID (1<<0)
#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define SSB0_FORCE_LOAD (1<<1)
#define SSB0_BUFFER_VALID (1<<0)
#define SSB1_BUFFER_LENGTH(x) ((x)&0xff)
#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define MSB0_FORCE_LOAD (1<<1)
#define MSB0_BUFFER_VALID (1<<0)
#define MSB1_BUFFER_LENGTH(x) ((x)&0xff)
#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define PSP0_FORCE_LOAD (1<<1)
#define PSP0_BUFFER_VALID (1<<0)
#define PSP1_BUFFER_LENGTH(x) ((x)&0xff)
#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3)
#define PSC0_FORCE_LOAD (1<<1)
#define PSC0_BUFFER_VALID (1<<0)
#define PSC1_BUFFER_LENGTH(x) ((x)&0xff)
/* _3DSTATE_RASTERIZATION_RULES */
#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24))
#define ENABLE_POINT_RASTER_RULE (1<<15)
#define OGL_POINT_RASTER_RULE (1<<13)
#define ENABLE_TEXKILL_3D_4D (1<<10)
#define TEXKILL_3D (0<<9)
#define TEXKILL_4D (1<<9)
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
/* _3DSTATE_SCISSOR_ENABLE, p256 */
#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19))
#define ENABLE_SCISSOR_RECT ((1<<1) | 1)
#define DISABLE_SCISSOR_RECT (1<<1)
/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */
#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1)
/* Dword 1 */
#define SCISSOR_RECT_0_YMIN(x) ((x)<<16)
#define SCISSOR_RECT_0_XMIN(x) (x)
/* Dword 2 */
#define SCISSOR_RECT_0_YMAX(x) ((x)<<16)
#define SCISSOR_RECT_0_XMAX(x) (x)
/* p189 */
#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16))
#define I1_LOAD_S(n) (1<<(4+n))
#define S0_VB_OFFSET_MASK 0xffffffc
#define S0_AUTO_CACHE_INV_DISABLE (1<<0)
#define S1_VERTEX_WIDTH_SHIFT 24
#define S1_VERTEX_WIDTH_MASK (0x3f<<24)
#define S1_VERTEX_PITCH_SHIFT 16
#define S1_VERTEX_PITCH_MASK (0x3f<<16)
#define TEXCOORDFMT_2D 0x0
#define TEXCOORDFMT_3D 0x1
#define TEXCOORDFMT_4D 0x2
#define TEXCOORDFMT_1D 0x3
#define TEXCOORDFMT_2D_16 0x4
#define TEXCOORDFMT_4D_16 0x5
#define TEXCOORDFMT_NOT_PRESENT 0xf
#define S2_TEXCOORD_FMT0_MASK 0xf
#define S2_TEXCOORD_FMT1_SHIFT 4
#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4))
#define S2_TEXCOORD_NONE (~0)
/* S3 not interesting */
#define S4_POINT_WIDTH_SHIFT 23
#define S4_POINT_WIDTH_MASK (0x1ff<<23)
#define S4_LINE_WIDTH_SHIFT 19
#define S4_LINE_WIDTH_ONE (0x2<<19)
#define S4_LINE_WIDTH_MASK (0xf<<19)
#define S4_FLATSHADE_ALPHA (1<<18)
#define S4_FLATSHADE_FOG (1<<17)
#define S4_FLATSHADE_SPECULAR (1<<16)
#define S4_FLATSHADE_COLOR (1<<15)
#define S4_CULLMODE_BOTH (0<<13)
#define S4_CULLMODE_NONE (1<<13)
#define S4_CULLMODE_CW (2<<13)
#define S4_CULLMODE_CCW (3<<13)
#define S4_CULLMODE_MASK (3<<13)
#define S4_VFMT_POINT_WIDTH (1<<12)
#define S4_VFMT_SPEC_FOG (1<<11)
#define S4_VFMT_COLOR (1<<10)
#define S4_VFMT_DEPTH_OFFSET (1<<9)
#define S4_VFMT_XYZ (1<<6)
#define S4_VFMT_XYZW (2<<6)
#define S4_VFMT_XY (3<<6)
#define S4_VFMT_XYW (4<<6)
#define S4_VFMT_XYZW_MASK (7<<6)
#define S4_FORCE_DEFAULT_DIFFUSE (1<<5)
#define S4_FORCE_DEFAULT_SPECULAR (1<<4)
#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3)
#define S4_VFMT_FOG_PARAM (1<<2)
#define S4_SPRITE_POINT_ENABLE (1<<1)
#define S4_LINE_ANTIALIAS_ENABLE (1<<0)
#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \
S4_VFMT_SPEC_FOG | \
S4_VFMT_COLOR | \
S4_VFMT_DEPTH_OFFSET | \
S4_VFMT_XYZW_MASK | \
S4_VFMT_FOG_PARAM)
#define S5_WRITEDISABLE_ALPHA (1<<31)
#define S5_WRITEDISABLE_RED (1<<30)
#define S5_WRITEDISABLE_GREEN (1<<29)
#define S5_WRITEDISABLE_BLUE (1<<28)
#define S5_WRITEDISABLE_MASK (0xf<<28)
#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27)
#define S5_LAST_PIXEL_ENABLE (1<<26)
#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25)
#define S5_FOG_ENABLE (1<<24)
#define S5_STENCIL_REF_SHIFT 16
#define S5_STENCIL_REF_MASK (0xff<<16)
#define S5_STENCIL_TEST_FUNC_SHIFT 13
#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13)
#define S5_STENCIL_FAIL_SHIFT 10
#define S5_STENCIL_FAIL_MASK (0x7<<10)
#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7
#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7)
#define S5_STENCIL_PASS_Z_PASS_SHIFT 4
#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4)
#define S5_STENCIL_WRITE_ENABLE (1<<3)
#define S5_STENCIL_TEST_ENABLE (1<<2)
#define S5_COLOR_DITHER_ENABLE (1<<1)
#define S5_LOGICOP_ENABLE (1<<0)
#define S6_ALPHA_TEST_ENABLE (1<<31)
#define S6_ALPHA_TEST_FUNC_SHIFT 28
#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28)
#define S6_ALPHA_REF_SHIFT 20
#define S6_ALPHA_REF_MASK (0xff<<20)
#define S6_DEPTH_TEST_ENABLE (1<<19)
#define S6_DEPTH_TEST_FUNC_SHIFT 16
#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16)
#define S6_CBUF_BLEND_ENABLE (1<<15)
#define S6_CBUF_BLEND_FUNC_SHIFT 12
#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12)
#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8
#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8)
#define S6_CBUF_DST_BLEND_FACT_SHIFT 4
#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4)
#define S6_DEPTH_WRITE_ENABLE (1<<3)
#define S6_COLOR_WRITE_ENABLE (1<<2)
#define S6_TRISTRIP_PV_SHIFT 0
#define S6_TRISTRIP_PV_MASK (0x3<<0)
#define S7_DEPTH_OFFSET_CONST_MASK ~0
/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */
/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */
/* _3DSTATE_MODES_4, p218 */
#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24))
#define ENABLE_LOGIC_OP_FUNC (1<<23)
#define LOGIC_OP_FUNC(x) ((x)<<18)
#define LOGICOP_MASK (0xf<<18)
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
#define ENABLE_STENCIL_TEST_MASK (1<<17)
#define STENCIL_TEST_MASK(x) ((x)<<8)
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
/* _3DSTATE_MODES_5, p220 */
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
#define PIPELINE_FLUSH_RENDER_CACHE (1<<18)
#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16)
/* p221 */
#define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16))
#define PS1_REG(n) (1<<(n))
#define PS2_CONST_X(n) (n)
#define PS3_CONST_Y(n) (n)
#define PS4_CONST_Z(n) (n)
#define PS5_CONST_W(n) (n)
/* p222 */
#define I915_MAX_TEX_INDIRECT 4
#define I915_MAX_TEX_INSN 32
#define I915_MAX_ALU_INSN 64
#define I915_MAX_DECL_INSN 27
#define I915_MAX_TEMPORARY 16
/* Each instruction is 3 dwords long, though most don't require all
* this space. Maximum of 123 instructions. Smaller maxes per insn
* type.
*/
#define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16))
#define REG_TYPE_R 0 /* temporary regs, no need to
* dcl, must be written before
* read -- Preserved between
* phases.
*/
#define REG_TYPE_T 1 /* Interpolated values, must be
* dcl'ed before use.
*
* 0..7: texture coord,
* 8: diffuse spec,
* 9: specular color,
* 10: fog parameter in w.
*/
#define REG_TYPE_CONST 2 /* Restriction: only one const
* can be referenced per
* instruction, though it may be
* selected for multiple inputs.
* Constants not initialized
* default to zero.
*/
#define REG_TYPE_S 3 /* sampler */
#define REG_TYPE_OC 4 /* output color (rgba) */
#define REG_TYPE_OD 5 /* output depth (w), xyz are
* temporaries. If not written,
* interpolated depth is used?
*/
#define REG_TYPE_U 6 /* unpreserved temporaries */
#define REG_TYPE_MASK 0x7
#define REG_NR_MASK 0xf
/* REG_TYPE_T:
*/
#define T_TEX0 0
#define T_TEX1 1
#define T_TEX2 2
#define T_TEX3 3
#define T_TEX4 4
#define T_TEX5 5
#define T_TEX6 6
#define T_TEX7 7
#define T_DIFFUSE 8
#define T_SPECULAR 9
#define T_FOG_W 10 /* interpolated fog is in W coord */
/* Arithmetic instructions */
/* .replicate_swizzle == selection and replication of a particular
* scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
*/
#define A0_NOP (0x0<<24) /* no operation */
#define A0_ADD (0x1<<24) /* dst = src0 + src1 */
#define A0_MOV (0x2<<24) /* dst = src0 */
#define A0_MUL (0x3<<24) /* dst = src0 * src1 */
#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */
#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */
#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */
#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */
#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */
#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */
#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */
#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */
#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */
#define A0_FLR (0x10<<24) /* dst = floor(src0) */
#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */
#define A0_TRC (0x12<<24) /* dst = int(src0) */
#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */
#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */
#define A0_DEST_SATURATE (1<<22)
#define A0_DEST_TYPE_SHIFT 19
/* Allow: R, OC, OD, U */
#define A0_DEST_NR_SHIFT 14
/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
#define A0_DEST_CHANNEL_X (1<<10)
#define A0_DEST_CHANNEL_Y (2<<10)
#define A0_DEST_CHANNEL_Z (4<<10)
#define A0_DEST_CHANNEL_W (8<<10)
#define A0_DEST_CHANNEL_ALL (0xf<<10)
#define A0_DEST_CHANNEL_SHIFT 10
#define A0_SRC0_TYPE_SHIFT 7
#define A0_SRC0_NR_SHIFT 2
#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
#define SRC_X 0
#define SRC_Y 1
#define SRC_Z 2
#define SRC_W 3
#define SRC_ZERO 4
#define SRC_ONE 5
#define A1_SRC0_CHANNEL_X_NEGATE (1<<31)
#define A1_SRC0_CHANNEL_X_SHIFT 28
#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27)
#define A1_SRC0_CHANNEL_Y_SHIFT 24
#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23)
#define A1_SRC0_CHANNEL_Z_SHIFT 20
#define A1_SRC0_CHANNEL_W_NEGATE (1<<19)
#define A1_SRC0_CHANNEL_W_SHIFT 16
#define A1_SRC1_TYPE_SHIFT 13
#define A1_SRC1_NR_SHIFT 8
#define A1_SRC1_CHANNEL_X_NEGATE (1<<7)
#define A1_SRC1_CHANNEL_X_SHIFT 4
#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3)
#define A1_SRC1_CHANNEL_Y_SHIFT 0
#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31)
#define A2_SRC1_CHANNEL_Z_SHIFT 28
#define A2_SRC1_CHANNEL_W_NEGATE (1<<27)
#define A2_SRC1_CHANNEL_W_SHIFT 24
#define A2_SRC2_TYPE_SHIFT 21
#define A2_SRC2_NR_SHIFT 16
#define A2_SRC2_CHANNEL_X_NEGATE (1<<15)
#define A2_SRC2_CHANNEL_X_SHIFT 12
#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11)
#define A2_SRC2_CHANNEL_Y_SHIFT 8
#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7)
#define A2_SRC2_CHANNEL_Z_SHIFT 4
#define A2_SRC2_CHANNEL_W_NEGATE (1<<3)
#define A2_SRC2_CHANNEL_W_SHIFT 0
/* Texture instructions */
#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared
* sampler and address, and output
* filtered texel data to destination
* register */
#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a
* perspective divide of the texture
* coordinate .xyz values by .w before
* sampling. */
#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the
* computed LOD by w. Only S4.6 two's
* comp is used. This implies that a
* float to fixed conversion is
* done. */
#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling
* operation. Simply kills the pixel
* if any channel of the address
* register is < 0.0. */
#define T0_DEST_TYPE_SHIFT 19
/* Allow: R, OC, OD, U */
/* Note: U (unpreserved) regs do not retain their values between
* phases (cannot be used for feedback)
*
* Note: oC and OD registers can only be used as the destination of a
* texture instruction once per phase (this is an implementation
* restriction).
*/
#define T0_DEST_NR_SHIFT 14
/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */
#define T0_SAMPLER_NR_MASK (0xf<<0)
#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */
/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
#define T1_ADDRESS_REG_NR_SHIFT 17
#define T2_MBZ 0
/* Declaration instructions */
#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib)
* register or an s (sampler)
* register. */
#define D0_SAMPLE_TYPE_SHIFT 22
#define D0_SAMPLE_TYPE_2D (0x0<<22)
#define D0_SAMPLE_TYPE_CUBE (0x1<<22)
#define D0_SAMPLE_TYPE_VOLUME (0x2<<22)
#define D0_SAMPLE_TYPE_MASK (0x3<<22)
#define D0_TYPE_SHIFT 19
/* Allow: T, S */
#define D0_NR_SHIFT 14
/* Allow T: 0..10, S: 0..15 */
#define D0_CHANNEL_X (1<<10)
#define D0_CHANNEL_Y (2<<10)
#define D0_CHANNEL_Z (4<<10)
#define D0_CHANNEL_W (8<<10)
#define D0_CHANNEL_ALL (0xf<<10)
#define D0_CHANNEL_NONE (0<<10)
#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y)
#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z)
/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
* or specular declarations.
*
* For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw)
*
* Must be zero for S (sampler) dcls
*/
#define D1_MBZ 0
#define D2_MBZ 0
/* p207 */
#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16))
#define MS1_MAPMASK_SHIFT 0
#define MS1_MAPMASK_MASK (0x8fff<<0)
#define MS2_UNTRUSTED_SURFACE (1<<31)
#define MS2_ADDRESS_MASK 0xfffffffc
#define MS2_VERTICAL_LINE_STRIDE (1<<1)
#define MS2_VERTICAL_OFFSET (1<<1)
#define MS3_HEIGHT_SHIFT 21
#define MS3_WIDTH_SHIFT 10
#define MS3_PALETTE_SELECT (1<<9)
#define MS3_MAPSURF_FORMAT_SHIFT 7
#define MS3_MAPSURF_FORMAT_MASK (0x7<<7)
#define MAPSURF_8BIT (1<<7)
#define MAPSURF_16BIT (2<<7)
#define MAPSURF_32BIT (3<<7)
#define MAPSURF_422 (5<<7)
#define MAPSURF_COMPRESSED (6<<7)
#define MAPSURF_4BIT_INDEXED (7<<7)
#define MS3_MT_FORMAT_MASK (0x7 << 3)
#define MS3_MT_FORMAT_SHIFT 3
#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */
#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */
#define MT_8BIT_L8 (1<<3)
#define MT_8BIT_A8 (4<<3)
#define MT_8BIT_MONO8 (5<<3)
#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */
#define MT_16BIT_ARGB1555 (1<<3)
#define MT_16BIT_ARGB4444 (2<<3)
#define MT_16BIT_AY88 (3<<3)
#define MT_16BIT_88DVDU (5<<3)
#define MT_16BIT_BUMP_655LDVDU (6<<3)
#define MT_16BIT_I16 (7<<3)
#define MT_16BIT_L16 (8<<3)
#define MT_16BIT_A16 (9<<3)
#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */
#define MT_32BIT_ABGR8888 (1<<3)
#define MT_32BIT_XRGB8888 (2<<3)
#define MT_32BIT_XBGR8888 (3<<3)
#define MT_32BIT_QWVU8888 (4<<3)
#define MT_32BIT_AXVU8888 (5<<3)
#define MT_32BIT_LXVU8888 (6<<3)
#define MT_32BIT_XLVU8888 (7<<3)
#define MT_32BIT_ARGB2101010 (8<<3)
#define MT_32BIT_ABGR2101010 (9<<3)
#define MT_32BIT_AWVU2101010 (0xA<<3)
#define MT_32BIT_GR1616 (0xB<<3)
#define MT_32BIT_VU1616 (0xC<<3)
#define MT_32BIT_xI824 (0xD<<3)
#define MT_32BIT_xA824 (0xE<<3)
#define MT_32BIT_xL824 (0xF<<3)
#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */
#define MT_422_YCRCB_NORMAL (1<<3)
#define MT_422_YCRCB_SWAPUV (2<<3)
#define MT_422_YCRCB_SWAPUVY (3<<3)
#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */
#define MT_COMPRESS_DXT2_3 (1<<3)
#define MT_COMPRESS_DXT4_5 (2<<3)
#define MT_COMPRESS_FXT1 (3<<3)
#define MT_COMPRESS_DXT1_RGB (4<<3)
#define MS3_USE_FENCE_REGS (1<<2)
#define MS3_TILED_SURFACE (1<<1)
#define MS3_TILE_WALK (1<<0)
#define MS4_PITCH_SHIFT 21
#define MS4_CUBE_FACE_ENA_NEGX (1<<20)
#define MS4_CUBE_FACE_ENA_POSX (1<<19)
#define MS4_CUBE_FACE_ENA_NEGY (1<<18)
#define MS4_CUBE_FACE_ENA_POSY (1<<17)
#define MS4_CUBE_FACE_ENA_NEGZ (1<<16)
#define MS4_CUBE_FACE_ENA_POSZ (1<<15)
#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15)
#define MS4_MAX_LOD_SHIFT 9
#define MS4_MAX_LOD_MASK (0x3f<<9)
#define MS4_MIP_LAYOUT_LEGACY (0<<8)
#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8)
#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8)
#define MS4_VOLUME_DEPTH_SHIFT 0
#define MS4_VOLUME_DEPTH_MASK (0xff<<0)
/* p244 */
#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16))
#define SS1_MAPMASK_SHIFT 0
#define SS1_MAPMASK_MASK (0x8fff<<0)
#define SS2_REVERSE_GAMMA_ENABLE (1<<31)
#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30)
#define SS2_COLORSPACE_CONVERSION (1<<29)
#define SS2_CHROMAKEY_SHIFT 27
#define SS2_BASE_MIP_LEVEL_SHIFT 22
#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22)
#define SS2_MIP_FILTER_SHIFT 20
#define SS2_MIP_FILTER_MASK (0x3<<20)
#define MIPFILTER_NONE 0
#define MIPFILTER_NEAREST 1
#define MIPFILTER_LINEAR 3
#define SS2_MAG_FILTER_SHIFT 17
#define SS2_MAG_FILTER_MASK (0x7<<17)
#define FILTER_NEAREST 0
#define FILTER_LINEAR 1
#define FILTER_ANISOTROPIC 2
#define FILTER_4X4_1 3
#define FILTER_4X4_2 4
#define FILTER_4X4_FLAT 5
#define FILTER_6X5_MONO 6 /* XXX - check */
#define SS2_MIN_FILTER_SHIFT 14
#define SS2_MIN_FILTER_MASK (0x7<<14)
#define SS2_LOD_BIAS_SHIFT 5
#define SS2_LOD_BIAS_ONE (0x10<<5)
#define SS2_LOD_BIAS_MASK (0x1ff<<5)
/* Shadow requires:
* MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format
* FILTER_4X4_x MIN and MAG filters
*/
#define SS2_SHADOW_ENABLE (1<<4)
#define SS2_MAX_ANISO_MASK (1<<3)
#define SS2_MAX_ANISO_2 (0<<3)
#define SS2_MAX_ANISO_4 (1<<3)
#define SS2_SHADOW_FUNC_SHIFT 0
#define SS2_SHADOW_FUNC_MASK (0x7<<0)
/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */
#define SS3_MIN_LOD_SHIFT 24
#define SS3_MIN_LOD_ONE (0x10<<24)
#define SS3_MIN_LOD_MASK (0xff<<24)
#define SS3_KILL_PIXEL_ENABLE (1<<17)
#define SS3_TCX_ADDR_MODE_SHIFT 12
#define SS3_TCX_ADDR_MODE_MASK (0x7<<12)
#define TEXCOORDMODE_WRAP 0
#define TEXCOORDMODE_MIRROR 1
#define TEXCOORDMODE_CLAMP_EDGE 2
#define TEXCOORDMODE_CUBE 3
#define TEXCOORDMODE_CLAMP_BORDER 4
#define TEXCOORDMODE_MIRROR_ONCE 5
#define SS3_TCY_ADDR_MODE_SHIFT 9
#define SS3_TCY_ADDR_MODE_MASK (0x7<<9)
#define SS3_TCZ_ADDR_MODE_SHIFT 6
#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6)
#define SS3_NORMALIZED_COORDS (1<<5)
#define SS3_TEXTUREMAP_INDEX_SHIFT 1
#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1)
#define SS3_DEINTERLACER_ENABLE (1<<0)
#define SS4_BORDER_COLOR_MASK (~0)
/* 3DSTATE_SPAN_STIPPLE, p258
*/
#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
#define ST1_ENABLE (1<<16)
#define ST1_MASK (0xffff)
#define MI_FLUSH ((0<<29)|(4<<23))
#define FLUSH_MAP_CACHE (1<<0)
#define FLUSH_RENDER_CACHE (1<<1)
#endif

View File

@ -1,970 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "dd.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "texmem.h"
#include "drivers/common/driverfuncs.h"
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "i915_context.h"
#include "i915_reg.h"
static void
i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
GLuint mask)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
mask = mask & 0xff;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(func), ref, mask);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
STENCIL_TEST_MASK(mask));
i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |
S5_STENCIL_TEST_FUNC_MASK);
i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |
(test << S5_STENCIL_TEST_FUNC_SHIFT));
}
static void
i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
mask = mask & 0xff;
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(mask));
}
static void
i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
GLenum zpass)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int fop = intel_translate_stencil_op(fail);
int dfop = intel_translate_stencil_op(zfail);
int dpop = intel_translate_stencil_op(zpass);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(fail),
_mesa_lookup_enum_by_nr(zfail),
_mesa_lookup_enum_by_nr(zpass));
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
S5_STENCIL_PASS_Z_FAIL_MASK |
S5_STENCIL_PASS_Z_PASS_MASK);
i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |
(dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
(dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));
}
static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
GLubyte refByte;
UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK |
S6_ALPHA_REF_MASK);
i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |
(((GLuint)refByte) << S6_ALPHA_REF_SHIFT));
}
/* This function makes sure that the proper enables are
* set for LogicOp, Independant Alpha Blend, and Blending.
* It needs to be called from numerous places where we
* could change the LogicOp or Independant Alpha Blend without subsequent
* calls to glEnable.
*/
static void i915EvalLogicOpBlendState(GLcontext *ctx)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (RGBA_LOGICOP_ENABLED(ctx)) {
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
} else {
i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE;
if (ctx->Color.BlendEnabled) {
i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE;
} else {
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
}
}
}
static void i915BlendColor(GLcontext *ctx, const GLfloat color[4])
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
GLubyte r, g, b, a;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);
UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b;
}
#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT)
#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT)
#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT)
#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT)
static GLuint translate_blend_equation( GLenum mode )
{
switch (mode) {
case GL_FUNC_ADD: return BLENDFUNC_ADD;
case GL_MIN: return BLENDFUNC_MIN;
case GL_MAX: return BLENDFUNC_MAX;
case GL_FUNC_SUBTRACT: return BLENDFUNC_SUBTRACT;
case GL_FUNC_REVERSE_SUBTRACT: return BLENDFUNC_REVERSE_SUBTRACT;
default: return 0;
}
}
static void i915UpdateBlendState( GLcontext *ctx )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
~(IAB_SRC_FACTOR_MASK |
IAB_DST_FACTOR_MASK |
(BLENDFUNC_MASK << IAB_FUNC_SHIFT) |
IAB_ENABLE));
GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] &
~(S6_CBUF_SRC_BLEND_FACT_MASK |
S6_CBUF_DST_BLEND_FACT_MASK |
S6_CBUF_BLEND_FUNC_MASK));
GLuint eqRGB = ctx->Color.BlendEquationRGB;
GLuint eqA = ctx->Color.BlendEquationA;
GLuint srcRGB = ctx->Color.BlendSrcRGB;
GLuint dstRGB = ctx->Color.BlendDstRGB;
GLuint srcA = ctx->Color.BlendSrcA;
GLuint dstA = ctx->Color.BlendDstA;
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
srcRGB = dstRGB = GL_ONE;
}
if (eqA == GL_MIN || eqA == GL_MAX) {
srcA = dstA = GL_ONE;
}
lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB));
lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB));
lis6 |= translate_blend_equation( eqRGB ) << S6_CBUF_BLEND_FUNC_SHIFT;
iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA));
iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA));
iab |= translate_blend_equation( eqA ) << IAB_FUNC_SHIFT;
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB)
iab |= IAB_ENABLE;
if (iab != i915->state.Ctx[I915_CTXREG_IAB] ||
lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) {
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_IAB] = iab;
i915->state.Ctx[I915_CTXREG_LIS6] = lis6;
}
/* This will catch a logicop blend equation */
i915EvalLogicOpBlendState(ctx);
}
static void i915BlendFuncSeparate(GLcontext *ctx, GLenum srcRGB,
GLenum dstRGB, GLenum srcA,
GLenum dstA )
{
i915UpdateBlendState( ctx );
}
static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB,
GLenum eqA)
{
i915UpdateBlendState( ctx );
}
static void i915DepthFunc(GLcontext *ctx, GLenum func)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int test = intel_translate_compare_func( func );
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK;
i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT;
}
static void i915DepthMask(GLcontext *ctx, GLboolean flag)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (flag && ctx->Depth.Test)
i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE;
}
/* =============================================================
* Polygon stipple
*
* The i915 supports a 4x4 stipple natively, GL wants 32x32.
* Fortunately stipple is usually a repeating pattern.
*/
static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
const GLubyte *m = mask;
GLubyte p[4];
int i,j,k;
int active = (ctx->Polygon.StippleFlag &&
i915->intel.reduced_primitive == GL_TRIANGLES);
GLuint newMask;
if (active) {
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;
}
p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
for (k = 0 ; k < 8 ; k++)
for (j = 3 ; j >= 0; j--)
for (i = 0 ; i < 4 ; i++, m++)
if (*m != p[j]) {
i915->intel.hw_stipple = 0;
return;
}
newMask = (((p[0] & 0xf) << 0) |
((p[1] & 0xf) << 4) |
((p[2] & 0xf) << 8) |
((p[3] & 0xf) << 12));
if (newMask == 0xffff || newMask == 0x0) {
/* this is needed to make conform pass */
i915->intel.hw_stipple = 0;
return;
}
i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff;
i915->state.Stipple[I915_STPREG_ST1] |= newMask;
i915->intel.hw_stipple = 1;
if (active)
i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;
}
/* =============================================================
* Hardware clipping
*/
static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
intelScreenPrivate *screen = i915->intel.intelScreen;
int x1, y1, x2, y2;
if (!i915->intel.driDrawable)
return;
x1 = x;
y1 = i915->intel.driDrawable->h - (y + h);
x2 = x + w - 1;
y2 = y1 + h - 1;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__,
x, y, w, h);
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 < 0) x2 = 0;
if (y2 < 0) y2 = 0;
if (x2 >= screen->width) x2 = screen->width-1;
if (y2 >= screen->height) y2 = screen->height-1;
if (x1 >= screen->width) x1 = screen->width-1;
if (y1 >= screen->height) y1 = screen->height-1;
I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
}
static void i915LogicOp(GLcontext *ctx, GLenum opcode)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int tmp = intel_translate_logic_op(opcode);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK;
i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
}
static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
GLuint mode;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!ctx->Polygon.CullFlag) {
mode = S4_CULLMODE_NONE;
}
else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
mode = S4_CULLMODE_CW;
if (ctx->Polygon.CullFaceMode == GL_FRONT)
mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
if (ctx->Polygon.FrontFace != GL_CCW)
mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
}
else {
mode = S4_CULLMODE_BOTH;
}
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK;
i915->state.Ctx[I915_CTXREG_LIS4] |= mode;
}
static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
int width;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
width = (int)(widthf * 2);
CLAMP_SELF(width, 1, 0xf);
lis4 |= width << S4_LINE_WIDTH_SHIFT;
if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS4] = lis4;
}
}
static void i915PointSize(GLcontext *ctx, GLfloat size)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
GLint point_size = (int)size;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
CLAMP_SELF(point_size, 1, 255);
lis4 |= point_size << S4_POINT_WIDTH_SHIFT;
if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS4] = lis4;
}
}
/* =============================================================
* Color masks
*/
static void i915ColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a)
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK;
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
if (!r) tmp |= S5_WRITEDISABLE_RED;
if (!g) tmp |= S5_WRITEDISABLE_GREEN;
if (!b) tmp |= S5_WRITEDISABLE_BLUE;
if (!a) tmp |= S5_WRITEDISABLE_ALPHA;
if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) {
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
i915->state.Ctx[I915_CTXREG_LIS5] = tmp;
}
}
static void update_specular( GLcontext *ctx )
{
/* A hack to trigger the rebuild of the fragment program.
*/
INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE;
I915_CONTEXT(ctx)->tex_program.translated = 0;
}
static void i915LightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
update_specular( ctx );
}
}
static void i915ShadeModel(GLcontext *ctx, GLenum mode)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (mode == GL_SMOOTH) {
i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA |
S4_FLATSHADE_COLOR |
S4_FLATSHADE_SPECULAR);
} else {
i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA |
S4_FLATSHADE_COLOR |
S4_FLATSHADE_SPECULAR);
}
}
/* =============================================================
* Fog
*/
void i915_update_fog( GLcontext *ctx )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
GLenum mode;
GLboolean enabled;
GLboolean try_pixel_fog;
if (ctx->FragmentProgram._Active) {
/* Pull in static fog state from program */
mode = ctx->FragmentProgram._Current->FogOption;
enabled = (mode != GL_NONE);
try_pixel_fog = 0;
}
else {
enabled = ctx->Fog.Enabled;
mode = ctx->Fog.Mode;
#if 0
/* XXX - DISABLED -- Need ortho fallback */
try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT
&&ctx->Hint.Fog == GL_NICEST);
#else
try_pixel_fog = 0;
#endif
}
if (!enabled) {
i915->vertex_fog = I915_FOG_NONE;
}
else if (try_pixel_fog) {
I915_STATECHANGE(i915, I915_UPLOAD_FOG);
i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK;
i915->vertex_fog = I915_FOG_PIXEL;
switch (mode) {
case GL_LINEAR:
if (ctx->Fog.End <= ctx->Fog.Start) {
/* XXX - this won't work with fragment programs. Need to
* either fallback or append fog instructions to end of
* program in the case of linear fog.
*/
i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX;
i915->vertex_fog = I915_FOG_VERTEX;
}
else {
GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start);
GLfloat c1 = ctx->Fog.End * c2;
i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK;
i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR;
i915->state.Fog[I915_FOGREG_MODE1] |=
((GLuint)(c1 * FMC1_C1_ONE)) & FMC1_C1_MASK;
if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) {
i915->state.Fog[I915_FOGREG_MODE2]
= (GLuint)(c2 * FMC2_C2_ONE);
}
else {
fi_type fi;
fi.f = c2;
i915->state.Fog[I915_FOGREG_MODE2] = fi.i;
}
}
break;
case GL_EXP:
i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP;
break;
case GL_EXP2:
i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2;
break;
default:
break;
}
}
else /* if (i915->vertex_fog != I915_FOG_VERTEX) */ {
I915_STATECHANGE(i915, I915_UPLOAD_FOG);
i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK;
i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX;
i915->vertex_fog = I915_FOG_VERTEX;
}
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled);
if (enabled)
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE;
/* Always enable pixel fog. Vertex fog using fog coord will conflict
* with fog code appended onto fragment program.
*/
_tnl_allow_vertex_fog( ctx, 0 );
_tnl_allow_pixel_fog( ctx, 1 );
}
static void
i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
switch (pname) {
case GL_FOG_COORDINATE_SOURCE_EXT:
case GL_FOG_MODE:
case GL_FOG_START:
case GL_FOG_END:
break;
case GL_FOG_DENSITY:
I915_STATECHANGE(i915, I915_UPLOAD_FOG);
if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) {
i915->state.Fog[I915_FOGREG_MODE3]
= (GLuint)(ctx->Fog.Density * FMC3_D_ONE);
}
else {
union { float f; int i; } fi;
fi.f = ctx->Fog.Density;
i915->state.Fog[I915_FOGREG_MODE3] = fi.i;
}
break;
case GL_FOG_COLOR:
I915_STATECHANGE(i915, I915_UPLOAD_FOG);
i915->state.Fog[I915_FOGREG_COLOR] =
(_3DSTATE_FOG_COLOR_CMD |
((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
break;
default:
break;
}
}
static void i915Hint(GLcontext *ctx, GLenum target, GLenum state)
{
switch (target) {
case GL_FOG_HINT:
break;
default:
break;
}
}
/* =============================================================
*/
static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
switch(cap) {
case GL_TEXTURE_2D:
break;
case GL_LIGHTING:
case GL_COLOR_SUM:
update_specular( ctx );
break;
case GL_ALPHA_TEST:
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (state)
i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE;
break;
case GL_BLEND:
i915EvalLogicOpBlendState(ctx);
break;
case GL_COLOR_LOGIC_OP:
i915EvalLogicOpBlendState(ctx);
/* Logicop doesn't seem to work at 16bpp:
*/
if (i915->intel.intelScreen->cpp == 2)
FALLBACK( &i915->intel, I915_FALLBACK_LOGICOP, state );
break;
case GL_FRAGMENT_PROGRAM_ARB:
break;
case GL_DITHER:
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (state)
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE;
break;
case GL_DEPTH_TEST:
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (state)
i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE;
i915DepthMask( ctx, ctx->Depth.Mask );
break;
case GL_SCISSOR_TEST:
I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
if (state)
i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
ENABLE_SCISSOR_RECT);
else
i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
break;
case GL_LINE_SMOOTH:
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (state)
i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE;
else
i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE;
break;
case GL_FOG:
break;
case GL_CULL_FACE:
i915CullFaceFrontFace(ctx, 0);
break;
case GL_STENCIL_TEST:
if (i915->intel.hw_stencil) {
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
if (state)
i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE |
S5_STENCIL_WRITE_ENABLE);
else
i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
S5_STENCIL_WRITE_ENABLE);
} else {
FALLBACK( &i915->intel, I915_FALLBACK_STENCIL, state );
}
break;
case GL_POLYGON_STIPPLE:
/* The stipple command worked on my 855GM box, but not my 845G.
* I'll do more testing later to find out exactly which hardware
* supports it. Disabled for now.
*/
if (i915->intel.hw_stipple &&
i915->intel.reduced_primitive == GL_TRIANGLES)
{
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
if (state)
i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;
else
i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;
}
break;
case GL_POLYGON_SMOOTH:
FALLBACK( &i915->intel, I915_FALLBACK_POLYGON_SMOOTH, state );
break;
case GL_POINT_SMOOTH:
FALLBACK( &i915->intel, I915_FALLBACK_POINT_SMOOTH, state );
break;
default:
;
}
}
static void i915_init_packets( i915ContextPtr i915 )
{
intelScreenPrivate *screen = i915->intel.intelScreen;
/* Zero all state */
memset(&i915->state, 0, sizeof(i915->state));
{
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
/* Probably don't want to upload all this stuff every time one
* piece changes.
*/
i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(2) |
I1_LOAD_S(4) |
I1_LOAD_S(5) |
I1_LOAD_S(6) |
(3));
i915->state.Ctx[I915_CTXREG_LIS2] = 0;
i915->state.Ctx[I915_CTXREG_LIS4] = 0;
i915->state.Ctx[I915_CTXREG_LIS5] = 0;
if (screen->cpp == 2)
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE |
(2 << S6_TRISTRIP_PV_SHIFT));
i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD |
ENABLE_LOGIC_OP_FUNC |
LOGIC_OP_FUNC(LOGICOP_COPY) |
ENABLE_STENCIL_TEST_MASK |
STENCIL_TEST_MASK(0xff) |
ENABLE_STENCIL_WRITE_MASK |
STENCIL_WRITE_MASK(0xff));
i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
IAB_MODIFY_ENABLE |
IAB_MODIFY_FUNC |
IAB_MODIFY_SRC_FACTOR |
IAB_MODIFY_DST_FACTOR);
i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0;
}
{
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE;
}
{
I915_STATECHANGE(i915, I915_UPLOAD_FOG);
i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD;
i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE |
FMC1_FOGFUNC_VERTEX |
FMC1_FOGINDEX_MODIFY_ENABLE |
FMC1_FOGINDEX_W |
FMC1_C1_C2_MODIFY_ENABLE |
FMC1_DENSITY_MODIFY_ENABLE);
i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD;
}
{
I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
/* color buffer offset/stride */
i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
/*i915->state.Buffer[I915_DESTREG_CBUFADDR2] is the offset */
/* depth/Z buffer offset/stride */
i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset;
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
/* color/depth pixel format */
switch (screen->fbFormat) {
case DV_PF_555:
case DV_PF_565:
i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL |
DITHER_FULL_ALWAYS |
screen->fbFormat |
DEPTH_FRMT_16_FIXED);
break;
case DV_PF_8888:
i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */
LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL |
screen->fbFormat |
DEPTH_FRMT_24_FIXED_8_OTHER);
break;
}
/* scissor */
i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
i915->state.Buffer[I915_DESTREG_SR1] = 0;
i915->state.Buffer[I915_DESTREG_SR2] = 0;
}
/* These will be emitted every at the head of every buffer, unless
* we get hardware contexts working.
*/
i915->state.active = (I915_UPLOAD_PROGRAM |
I915_UPLOAD_STIPPLE |
I915_UPLOAD_CTX |
I915_UPLOAD_BUFFERS |
I915_UPLOAD_INVARIENT);
}
void i915InitStateFunctions( struct dd_function_table *functions )
{
functions->AlphaFunc = i915AlphaFunc;
functions->BlendColor = i915BlendColor;
functions->BlendEquationSeparate = i915BlendEquationSeparate;
functions->BlendFuncSeparate = i915BlendFuncSeparate;
functions->ColorMask = i915ColorMask;
functions->CullFace = i915CullFaceFrontFace;
functions->DepthFunc = i915DepthFunc;
functions->DepthMask = i915DepthMask;
functions->Enable = i915Enable;
functions->Fogfv = i915Fogfv;
functions->FrontFace = i915CullFaceFrontFace;
functions->Hint = i915Hint;
functions->LightModelfv = i915LightModelfv;
functions->LineWidth = i915LineWidth;
functions->LogicOpcode = i915LogicOp;
functions->PointSize = i915PointSize;
functions->PolygonStipple = i915PolygonStipple;
functions->Scissor = i915Scissor;
functions->ShadeModel = i915ShadeModel;
functions->StencilFuncSeparate = i915StencilFuncSeparate;
functions->StencilMaskSeparate = i915StencilMaskSeparate;
functions->StencilOpSeparate = i915StencilOpSeparate;
}
void i915InitState( i915ContextPtr i915 )
{
GLcontext *ctx = &i915->intel.ctx;
i915_init_packets( i915 );
_mesa_init_driver_state(ctx);
memcpy( &i915->initial, &i915->state, sizeof(i915->state) );
i915->current = &i915->state;
}

View File

@ -1,187 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "simple_list.h"
#include "enums.h"
#include "image.h"
#include "texstore.h"
#include "texformat.h"
#include "texmem.h"
#include "swrast/swrast.h"
#include "mm.h"
#include "intel_ioctl.h"
#include "i915_context.h"
#include "i915_reg.h"
/**
* Allocate space for and load the mesa images into the texture memory block.
* This will happen before drawing with a new texture, or drawing with a
* texture after it was swapped out or teximaged again.
*/
intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj )
{
i915TextureObjectPtr t = CALLOC_STRUCT( i915_texture_object );
if ( !t )
return NULL;
texObj->DriverData = t;
t->intel.base.tObj = texObj;
t->intel.dirty = I915_UPLOAD_TEX_ALL;
make_empty_list( &t->intel.base );
return &t->intel;
}
static void i915TexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
{
i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
case GL_TEXTURE_BORDER_COLOR:
t->intel.dirty = I915_UPLOAD_TEX_ALL;
break;
case GL_TEXTURE_COMPARE_MODE:
t->intel.dirty = I915_UPLOAD_TEX_ALL;
break;
case GL_TEXTURE_COMPARE_FUNC:
t->intel.dirty = I915_UPLOAD_TEX_ALL;
break;
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MAX_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
/* The i915 and its successors can do a lot of this without
* reloading the textures. A project for someone?
*/
intelFlush( ctx );
driSwapOutTextureObject( (driTextureObject *) t );
t->intel.dirty = I915_UPLOAD_TEX_ALL;
break;
default:
return;
}
}
static void i915TexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
GLuint unit = ctx->Texture.CurrentUnit;
switch (pname) {
case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */
case GL_TEXTURE_ENV_MODE:
case GL_COMBINE_RGB:
case GL_COMBINE_ALPHA:
case GL_SOURCE0_RGB:
case GL_SOURCE1_RGB:
case GL_SOURCE2_RGB:
case GL_SOURCE0_ALPHA:
case GL_SOURCE1_ALPHA:
case GL_SOURCE2_ALPHA:
case GL_OPERAND0_RGB:
case GL_OPERAND1_RGB:
case GL_OPERAND2_RGB:
case GL_OPERAND0_ALPHA:
case GL_OPERAND1_ALPHA:
case GL_OPERAND2_ALPHA:
case GL_RGB_SCALE:
case GL_ALPHA_SCALE:
i915->tex_program.translated = 0;
break;
case GL_TEXTURE_LOD_BIAS: {
int b = (int) ((*param) * 16.0);
if (b > 255) b = 255;
if (b < -256) b = -256;
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK;
i915->state.Tex[unit][I915_TEXREG_SS2] |=
((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
break;
}
default:
break;
}
}
static void i915BindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj )
{
i915TextureObjectPtr tex;
if (!texObj->DriverData)
i915AllocTexObj( texObj );
tex = (i915TextureObjectPtr)texObj->DriverData;
if (tex->lastTarget != texObj->Target) {
tex->intel.dirty = I915_UPLOAD_TEX_ALL;
tex->lastTarget = texObj->Target;
}
/* Need this if image format changes between bound textures.
* Could try and shortcircuit by checking for differences in
* state between incoming and outgoing textures:
*/
I915_CONTEXT(ctx)->tex_program.translated = 0;
}
void i915InitTextureFuncs( struct dd_function_table *functions )
{
functions->BindTexture = i915BindTexture;
functions->TexEnv = i915TexEnv;
functions->TexParameter = i915TexParameter;
}

View File

@ -1,676 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <strings.h>
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "tnl/t_context.h"
#include "intel_batchbuffer.h"
#include "i915_reg.h"
#include "i915_context.h"
#include "i915_program.h"
static GLuint translate_tex_src_bit( struct i915_fragment_program *p,
GLubyte bit )
{
switch (bit) {
case TEXTURE_1D_BIT: return D0_SAMPLE_TYPE_2D;
case TEXTURE_2D_BIT: return D0_SAMPLE_TYPE_2D;
case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D;
case TEXTURE_3D_BIT: return D0_SAMPLE_TYPE_VOLUME;
case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE;
default: i915_program_error(p, "TexSrcBit"); return 0;
}
}
static GLuint get_source( struct i915_fragment_program *p,
GLenum src, GLuint unit )
{
switch (src) {
case GL_TEXTURE:
if (p->src_texture == UREG_BAD) {
/* TODO: Use D0_CHANNEL_XY where possible.
*/
GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
GLuint sampler = i915_emit_decl(p, REG_TYPE_S, unit, dim);
GLuint texcoord = i915_emit_decl(p, REG_TYPE_T, unit, D0_CHANNEL_ALL);
GLuint tmp = i915_get_temp( p );
GLuint op = T0_TEXLD;
if (p->VB->TexCoordPtr[unit]->size == 4)
op = T0_TEXLDP;
p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL,
sampler, texcoord, op );
}
return p->src_texture;
/* Crossbar: */
case GL_TEXTURE0:
case GL_TEXTURE1:
case GL_TEXTURE2:
case GL_TEXTURE3:
case GL_TEXTURE4:
case GL_TEXTURE5:
case GL_TEXTURE6:
case GL_TEXTURE7: {
return UREG_BAD;
}
case GL_CONSTANT:
return i915_emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
case GL_PRIMARY_COLOR:
return i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
case GL_PREVIOUS:
default:
i915_emit_decl(p,
GET_UREG_TYPE(p->src_previous),
GET_UREG_NR(p->src_previous), D0_CHANNEL_ALL);
return p->src_previous;
}
}
static GLuint emit_combine_source( struct i915_fragment_program *p,
GLuint mask,
GLuint unit,
GLenum source,
GLenum operand )
{
GLuint arg, src;
src = get_source(p, source, unit);
switch (operand) {
case GL_ONE_MINUS_SRC_COLOR:
/* Get unused tmp,
* Emit tmp = 1.0 + arg.-x-y-z-w
*/
arg = i915_get_temp( p );
return i915_emit_arith( p, A0_ADD, arg, mask, 0,
swizzle(src, ONE, ONE, ONE, ONE ),
negate(src, 1,1,1,1), 0);
case GL_SRC_ALPHA:
if (mask == A0_DEST_CHANNEL_W)
return src;
else
return swizzle( src, W, W, W, W );
case GL_ONE_MINUS_SRC_ALPHA:
/* Get unused tmp,
* Emit tmp = 1.0 + arg.-w-w-w-w
*/
arg = i915_get_temp( p );
return i915_emit_arith( p, A0_ADD, arg, mask, 0,
swizzle(src, ONE, ONE, ONE, ONE ),
negate( swizzle(src,W,W,W,W), 1,1,1,1), 0);
case GL_SRC_COLOR:
default:
return src;
}
}
static int nr_args( GLenum mode )
{
switch (mode) {
case GL_REPLACE: return 1;
case GL_MODULATE: return 2;
case GL_ADD: return 2;
case GL_ADD_SIGNED: return 2;
case GL_INTERPOLATE: return 3;
case GL_SUBTRACT: return 2;
case GL_DOT3_RGB_EXT: return 2;
case GL_DOT3_RGBA_EXT: return 2;
case GL_DOT3_RGB: return 2;
case GL_DOT3_RGBA: return 2;
default: return 0;
}
}
static GLboolean args_match( struct gl_texture_unit *texUnit )
{
int i, nr = nr_args(texUnit->Combine.ModeRGB);
for (i = 0 ; i < nr ; i++) {
if (texUnit->Combine.SourceA[i] != texUnit->Combine.SourceRGB[i])
return GL_FALSE;
switch(texUnit->Combine.OperandA[i]) {
case GL_SRC_ALPHA:
switch(texUnit->Combine.OperandRGB[i]) {
case GL_SRC_COLOR:
case GL_SRC_ALPHA:
break;
default:
return GL_FALSE;
}
break;
case GL_ONE_MINUS_SRC_ALPHA:
switch(texUnit->Combine.OperandRGB[i]) {
case GL_ONE_MINUS_SRC_COLOR:
case GL_ONE_MINUS_SRC_ALPHA:
break;
default:
return GL_FALSE;
}
break;
default:
return GL_FALSE; /* impossible */
}
}
return GL_TRUE;
}
static GLuint emit_combine( struct i915_fragment_program *p,
GLuint dest,
GLuint mask,
GLuint saturate,
GLuint unit,
GLenum mode,
const GLenum *source,
const GLenum *operand)
{
int tmp, src[3], nr = nr_args(mode);
int i;
for (i = 0; i < nr; i++)
src[i] = emit_combine_source( p, mask, unit, source[i], operand[i] );
switch (mode) {
case GL_REPLACE:
if (mask == A0_DEST_CHANNEL_ALL && !saturate)
return src[0];
else
return i915_emit_arith( p, A0_MOV, dest, mask, saturate, src[0], 0, 0 );
case GL_MODULATE:
return i915_emit_arith( p, A0_MUL, dest, mask, saturate,
src[0], src[1], 0 );
case GL_ADD:
return i915_emit_arith( p, A0_ADD, dest, mask, saturate,
src[0], src[1], 0 );
case GL_ADD_SIGNED:
/* tmp = arg0 + arg1
* result = tmp + -.5
*/
tmp = i915_emit_const1f(p, .5);
tmp = negate(swizzle(tmp,X,X,X,X),1,1,1,1);
i915_emit_arith( p, A0_ADD, dest, mask, 0, src[0], src[1], 0 );
i915_emit_arith( p, A0_ADD, dest, mask, saturate, dest, tmp, 0 );
return dest;
case GL_INTERPOLATE: /* TWO INSTRUCTIONS */
/* Arg0 * (Arg2) + Arg1 * (1-Arg2)
*
* Arg0*Arg2 + Arg1 - Arg1Arg2
*
* tmp = Arg0*Arg2 + Arg1,
* result = (-Arg1)Arg2 + tmp
*/
tmp = i915_get_temp( p );
i915_emit_arith( p, A0_MAD, tmp, mask, 0, src[0], src[2], src[1] );
i915_emit_arith( p, A0_MAD, dest, mask, saturate,
negate(src[1], 1,1,1,1), src[2], tmp );
return dest;
case GL_SUBTRACT:
/* negate src[1] */
return i915_emit_arith( p, A0_ADD, dest, mask, saturate, src[0],
negate(src[1],1,1,1,1), 0 );
case GL_DOT3_RGBA:
case GL_DOT3_RGBA_EXT:
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGB: {
GLuint tmp0 = i915_get_temp( p );
GLuint tmp1 = i915_get_temp( p );
GLuint neg1 = negate(swizzle(i915_emit_const1f(p, 1),X,X,X,X), 1,1,1,1);
GLuint two = swizzle(i915_emit_const1f(p, 2),X,X,X,X);
i915_emit_arith( p, A0_MAD, tmp0, A0_DEST_CHANNEL_ALL, 0,
two, src[0], neg1);
if (src[0] == src[1])
tmp1 = tmp0;
else
i915_emit_arith( p, A0_MAD, tmp1, A0_DEST_CHANNEL_ALL, 0,
two, src[1], neg1);
i915_emit_arith( p, A0_DP3, dest, mask, saturate, tmp0, tmp1, 0);
return dest;
}
default:
return src[0];
}
}
static GLuint get_dest( struct i915_fragment_program *p, int unit )
{
if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
return i915_get_temp( p );
else if (unit != p->last_tex_stage)
return i915_get_temp( p );
else
return UREG(REG_TYPE_OC, 0);
}
static GLuint emit_texenv( struct i915_fragment_program *p, int unit )
{
struct gl_texture_unit *texUnit = &p->ctx->Texture.Unit[unit];
GLenum envMode = texUnit->EnvMode;
struct gl_texture_object *tObj = texUnit->_Current;
GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
GLuint saturate = unit < p->last_tex_stage ? A0_DEST_SATURATE : 0;
switch(envMode) {
case GL_BLEND: {
const int cf = get_source(p, GL_PREVIOUS, unit);
const int cc = get_source(p, GL_CONSTANT, unit);
const int cs = get_source(p, GL_TEXTURE, unit);
const int out = get_dest(p, unit);
if (format == GL_INTENSITY) {
/* cv = cf(1 - cs) + cc.cs
* cv = cf - cf.cs + cc.cs
*/
/* u[2] = MAD( -cf * cs + cf )
* cv = MAD( cc * cs + u[2] )
*/
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
negate(cf,1,1,1,1), cs, cf );
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
cc, cs, out );
return out;
} else {
/* cv = cf(1 - cs) + cc.cs
* cv = cf - cf.cs + cc.cs
* av = af.as
*/
/* u[2] = MAD( cf.-x-y-zw * cs.xyzw + cf.xyz0 )
* oC = MAD( cc.xyz0 * cs.xyz0 + u[2].xyzw )
*/
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
negate(cf,1,1,1,0),
cs,
swizzle(cf,X,Y,Z,ZERO) );
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
swizzle(cc,X,Y,Z,ZERO),
swizzle(cs,X,Y,Z,ZERO),
out );
return out;
}
}
case GL_DECAL: {
if (format == GL_RGB ||
format == GL_RGBA) {
int cf = get_source( p, GL_PREVIOUS, unit );
int cs = get_source( p, GL_TEXTURE, unit );
int out = get_dest(p, unit);
/* cv = cf(1-as) + cs.as
* cv = cf.(-as) + cf + cs.as
* av = af
*/
/* u[2] = mad( cf.xyzw * cs.-w-w-w1 + cf.xyz0 )
* oc = mad( cs.xyz0 * cs.www0 + u[2].xyzw )
*/
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
cf,
negate(swizzle(cs,W,W,W,ONE),1,1,1,0),
swizzle(cf,X,Y,Z,ZERO) );
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
swizzle(cs,X,Y,Z,ZERO),
swizzle(cs,W,W,W,ZERO),
out );
return out;
}
else {
return get_source( p, GL_PREVIOUS, unit );
}
}
case GL_REPLACE: {
const int cs = get_source( p, GL_TEXTURE, unit ); /* saturated */
switch (format) {
case GL_ALPHA: {
const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_XYZ, 0, cf, 0, 0 );
return cs;
}
case GL_RGB:
case GL_LUMINANCE: {
const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_W, 0, cf, 0, 0 );
return cs;
}
default:
return cs;
}
}
case GL_MODULATE: {
const int cf = get_source( p, GL_PREVIOUS, unit );
const int cs = get_source( p, GL_TEXTURE, unit );
const int out = get_dest(p, unit);
switch (format) {
case GL_ALPHA:
i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
swizzle(cs, ONE, ONE, ONE, W), cf, 0 );
break;
default:
i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
cs, cf, 0 );
break;
}
return out;
}
case GL_ADD: {
int cf = get_source( p, GL_PREVIOUS, unit );
int cs = get_source( p, GL_TEXTURE, unit );
const int out = get_dest( p, unit );
if (format == GL_INTENSITY) {
/* output-color.rgba = add( incoming, u[1] )
*/
i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, saturate,
cs, cf, 0 );
return out;
}
else {
/* cv.xyz = cf.xyz + cs.xyz
* cv.w = cf.w * cs.w
*
* cv.xyzw = MAD( cf.111w * cs.xyzw + cf.xyz0 )
*/
i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
swizzle(cf,ONE,ONE,ONE,W),
cs,
swizzle(cf,X,Y,Z,ZERO) );
return out;
}
break;
}
case GL_COMBINE: {
GLuint rgb_shift, alpha_shift, out, shift;
GLuint dest = get_dest(p, unit);
/* The EXT version of the DOT3 extension does not support the
* scale factor, but the ARB version (and the version in OpenGL
* 1.3) does.
*/
switch (texUnit->Combine.ModeRGB) {
case GL_DOT3_RGB_EXT:
alpha_shift = texUnit->Combine.ScaleShiftA;
rgb_shift = 0;
break;
case GL_DOT3_RGBA_EXT:
alpha_shift = 0;
rgb_shift = 0;
break;
default:
rgb_shift = texUnit->Combine.ScaleShiftRGB;
alpha_shift = texUnit->Combine.ScaleShiftA;
break;
}
/* Emit the RGB and A combine ops
*/
if (texUnit->Combine.ModeRGB == texUnit->Combine.ModeA &&
args_match( texUnit )) {
out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
unit,
texUnit->Combine.ModeRGB,
texUnit->Combine.SourceRGB,
texUnit->Combine.OperandRGB );
}
else if (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT ||
texUnit->Combine.ModeRGB == GL_DOT3_RGBA) {
out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
unit,
texUnit->Combine.ModeRGB,
texUnit->Combine.SourceRGB,
texUnit->Combine.OperandRGB );
}
else {
/* Need to do something to stop from re-emitting identical
* argument calculations here:
*/
out = emit_combine( p, dest, A0_DEST_CHANNEL_XYZ, saturate,
unit,
texUnit->Combine.ModeRGB,
texUnit->Combine.SourceRGB,
texUnit->Combine.OperandRGB );
out = emit_combine( p, dest, A0_DEST_CHANNEL_W, saturate,
unit,
texUnit->Combine.ModeA,
texUnit->Combine.SourceA,
texUnit->Combine.OperandA );
}
/* Deal with the final shift:
*/
if (alpha_shift || rgb_shift) {
if (rgb_shift == alpha_shift) {
shift = i915_emit_const1f(p, 1<<rgb_shift);
shift = swizzle(shift,X,X,X,X);
}
else {
shift = i915_emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
shift = swizzle(shift,X,X,X,Y);
}
return i915_emit_arith( p, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
saturate, out, shift, 0 );
}
return out;
}
default:
return get_source(p, GL_PREVIOUS, 0);
}
}
static void emit_program_fini( struct i915_fragment_program *p )
{
int cf = get_source( p, GL_PREVIOUS, 0 );
int out = UREG( REG_TYPE_OC, 0 );
if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
/* Emit specular add.
*/
GLuint s = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_ALL);
i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, 0, cf,
swizzle(s, X,Y,Z,ZERO), 0 );
}
else if (cf != out) {
/* Will wind up in here if no texture enabled or a couple of
* other scenarios (GL_REPLACE for instance).
*/
i915_emit_arith( p, A0_MOV, out, A0_DEST_CHANNEL_ALL, 0, cf, 0, 0 );
}
}
static void i915EmitTextureProgram( i915ContextPtr i915 )
{
GLcontext *ctx = &i915->intel.ctx;
struct i915_fragment_program *p = &i915->tex_program;
GLuint unit;
if (0) fprintf(stderr, "%s\n", __FUNCTION__);
i915_init_program( i915, p );
if (ctx->Texture._EnabledUnits) {
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
p->last_tex_stage = unit;
}
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++)
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
p->src_previous = emit_texenv( p, unit );
p->src_texture = UREG_BAD;
p->temp_flag = 0xffff000;
p->temp_flag |= 1 << GET_UREG_NR(p->src_previous);
}
}
emit_program_fini( p );
i915_fini_program( p );
i915_upload_program( i915, p );
p->translated = 1;
}
void i915ValidateTextureProgram( i915ContextPtr i915 )
{
intelContextPtr intel = &i915->intel;
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
DECLARE_RENDERINPUTS(index_bitset);
int i, offset;
GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
GLuint s2 = S2_TEXCOORD_NONE;
RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
intel->vertex_attr_count = 0;
intel->coloroffset = 0;
intel->specoffset = 0;
offset = 0;
if (i915->current_program) {
i915->current_program->on_hardware = 0;
i915->current_program->params_uptodate = 0;
}
if (i915->vertex_fog == I915_FOG_PIXEL) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
RENDERINPUTS_CLEAR( index_bitset, _TNL_ATTRIB_FOG );
}
else if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
}
else {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12 );
}
/* How undefined is undefined? */
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4 );
}
intel->coloroffset = offset / 4;
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 );
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
intel->specoffset = offset / 4;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 );
} else
EMIT_PAD( 3 );
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 );
else
EMIT_PAD( 1 );
}
if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
for (i = 0; i < 8; i++) {
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
int sz = VB->TexCoordPtr[i]->size;
s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0, sz * 4 );
}
}
}
/* Only need to change the vertex emit code if there has been a
* statechange to a new hardware vertex format:
*/
if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
I915_STATECHANGE( i915, I915_UPLOAD_CTX );
i915->tex_program.translated = 0;
/* Must do this *after* statechange, so as not to affect
* buffered vertices reliant on the old state:
*/
intel->vertex_size = _tnl_install_attrs( ctx,
intel->vertex_attrs,
intel->vertex_attr_count,
intel->ViewportMatrix.m, 0 );
intel->vertex_size >>= 2;
i915->state.Ctx[I915_CTXREG_LIS2] = s2;
i915->state.Ctx[I915_CTXREG_LIS4] = s4;
assert(intel->vtbl.check_vertex_size( intel, intel->vertex_size ));
}
if (!i915->tex_program.translated ||
i915->last_ReallyEnabled != ctx->Texture._EnabledUnits) {
i915EmitTextureProgram( i915 );
i915->last_ReallyEnabled = ctx->Texture._EnabledUnits;
}
}

View File

@ -1,975 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
#include "texstore.h"
#include "mm.h"
#include "intel_screen.h"
#include "intel_ioctl.h"
#include "intel_tex.h"
#include "i915_context.h"
#include "i915_reg.h"
static GLint initial_offsets[6][2] = { {0,0},
{0,2},
{1,0},
{1,2},
{1,1},
{1,3} };
static GLint step_offsets[6][2] = { {0,2},
{0,2},
{-1,2},
{-1,2},
{-1,1},
{-1,1} };
#define I915_TEX_UNIT_ENABLED(unit) (1<<unit)
static GLuint i915_compressed_alignment(GLint internal_fmt)
{
GLuint alignment = 4;
switch (internal_fmt) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
alignment = 8;
break;
default:
break;
}
return alignment;
}
static int align(int value, GLuint alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
static GLuint minify(GLuint d)
{
return MAX2(1, d >> 1);
}
static void i915LayoutTextureImages( i915ContextPtr i915,
struct gl_texture_object *tObj )
{
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
GLint firstLevel, lastLevel, numLevels;
GLint i, total_height, pitch;
/* Compute which mipmap levels we really want to send to the hardware.
*/
driCalculateTextureFirstLastLevel( (driTextureObject *) t );
/* Figure out the amount of memory required to hold all the mipmap
* levels. Choose the smallest pitch to accomodate the largest
* mipmap:
*/
firstLevel = t->intel.base.firstLevel;
lastLevel = t->intel.base.lastLevel;
numLevels = lastLevel - firstLevel + 1;
/* All images must be loaded at this pitch. Count the number of
* lines required:
*/
switch (tObj->Target) {
case GL_TEXTURE_CUBE_MAP: {
const GLuint dim = tObj->Image[0][firstLevel]->Width;
GLuint face;
pitch = dim * t->intel.texelBytes;
pitch *= 2; /* double pitch for cube layouts */
pitch = (pitch + 3) & ~3;
total_height = dim * 4;
for ( face = 0 ; face < 6 ; face++) {
GLuint x = initial_offsets[face][0] * dim;
GLuint y = initial_offsets[face][1] * dim;
GLuint d = dim;
t->intel.base.dirty_images[face] = ~0;
assert(tObj->Image[face][firstLevel]->Width == dim);
assert(tObj->Image[face][firstLevel]->Height == dim);
for (i = 0; i < numLevels; i++) {
t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
if (!t->intel.image[face][i].image) {
fprintf(stderr, "no image %d %d\n", face, i);
break; /* can't happen */
}
t->intel.image[face][i].offset =
y * pitch + x * t->intel.texelBytes;
t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
break;
}
case GL_TEXTURE_3D: {
GLuint virtual_height;
GLuint tmp_numLevels = numLevels;
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
pitch = (pitch + 3) & ~3;
t->intel.base.dirty_images[0] = ~0;
/* Calculate the size of a single slice. Hardware demands a
* minimum of 8 mipmaps, some of which might ultimately not be
* used:
*/
if (tmp_numLevels < 9)
tmp_numLevels = 9;
virtual_height = tObj->Image[0][firstLevel]->Height;
for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
if (t->intel.image[0][i].image) {
t->intel.image[0][i].offset = total_height * pitch;
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
}
total_height += MAX2(2, virtual_height);
virtual_height >>= 1;
}
t->intel.depth_pitch = total_height * pitch;
/* Multiply slice size by texture depth for total size. It's
* remarkable how wasteful of memory all the i8x0 texture
* layouts are.
*/
total_height *= t->intel.image[0][0].image->Depth;
break;
}
default:
if (baseImage->IsCompressed) {
GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat);
pitch = align(tObj->Image[0][firstLevel]->Width, alignment) * t->intel.texelBytes;
} else {
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
pitch = (pitch + 3) & ~3;
}
t->intel.base.dirty_images[0] = ~0;
for ( total_height = i = 0 ; i < numLevels ; i++ ) {
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
if (!t->intel.image[0][i].image)
break;
t->intel.image[0][i].offset = total_height * pitch;
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
if (t->intel.image[0][i].image->IsCompressed) {
total_height += (t->intel.image[0][i].image->Height + 3) / 4;
}
else
total_height += MAX2(2, t->intel.image[0][i].image->Height);
}
break;
}
t->intel.Pitch = pitch;
t->intel.base.totalSize = total_height*pitch;
t->intel.max_level = numLevels-1;
}
static void i945LayoutTextureImages( i915ContextPtr i915,
struct gl_texture_object *tObj )
{
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
GLint firstLevel, lastLevel, numLevels;
GLint i, total_height, pitch, sz, max_offset = 0, offset;
/* Compute which mipmap levels we really want to send to the hardware.
*/
driCalculateTextureFirstLastLevel( (driTextureObject *) t );
/* Figure out the amount of memory required to hold all the mipmap
* levels. Choose the smallest pitch to accomodate the largest
* mipmap:
*/
firstLevel = t->intel.base.firstLevel;
lastLevel = t->intel.base.lastLevel;
numLevels = lastLevel - firstLevel + 1;
/* All images must be loaded at this pitch. Count the number of
* lines required:
*/
switch (tObj->Target) {
case GL_TEXTURE_CUBE_MAP: {
const GLuint dim = tObj->Image[0][firstLevel]->Width;
GLuint face;
/* Depending on the size of the largest images, pitch can be
* determined either by the old-style packing of cubemap faces,
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32) {
pitch = dim * t->intel.texelBytes;
pitch *= 2; /* double pitch for cube layouts */
pitch = (pitch + 3) & ~3;
}
else {
pitch = 14 * 8 * t->intel.texelBytes; /* determined by row of
* little maps at
* bottom */
}
total_height = dim * 4 + 4;
for ( face = 0 ; face < 6 ; face++) {
GLuint x = initial_offsets[face][0] * dim;
GLuint y = initial_offsets[face][1] * dim;
GLuint d = dim;
if (dim == 4 && face >= 4) {
y = total_height - 4;
x = (face - 4) * 8;
}
else if (dim < 4) {
y = total_height - 4;
x = face * 8;
}
t->intel.base.dirty_images[face] = ~0;
assert(tObj->Image[face][firstLevel]->Width == dim);
assert(tObj->Image[face][firstLevel]->Height == dim);
for (i = 0; i < numLevels; i++) {
t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
assert(t->intel.image[face][i].image);
t->intel.image[face][i].offset =
y * pitch + x * t->intel.texelBytes;
t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;
d >>= 1;
switch (d) {
case 4:
switch (face) {
case FACE_POS_X:
case FACE_NEG_X:
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
break;
case FACE_POS_Y:
case FACE_NEG_Y:
y += 12;
x -= 8;
break;
case FACE_POS_Z:
case FACE_NEG_Z:
y = total_height - 4;
x = (face - 4) * 8;
break;
}
case 2:
y = total_height - 4;
x = 16 + face * 8;
break;
case 1:
x += 48;
break;
default:
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
break;
}
}
}
max_offset = total_height * pitch;
break;
}
case GL_TEXTURE_3D: {
GLuint depth_packing = 0, depth_pack_pitch;
GLuint tmp_numLevels = numLevels;
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
pitch = (pitch + 3) & ~3;
depth_pack_pitch = pitch;
t->intel.base.dirty_images[0] = ~0;
for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
if (!t->intel.image[0][i].image)
break;
t->intel.image[0][i].offset = total_height * pitch;
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
total_height += MAX2(2, t->intel.image[0][i].image->Height) *
MAX2((t->intel.image[0][i].image->Depth >> depth_packing), 1);
/* When alignment dominates, can't increase depth packing?
* Or does pitch grow??? What are the alignment constraints,
* anyway?
*/
if (depth_pack_pitch > 4) {
depth_packing++;
depth_pack_pitch <<= 2;
}
}
max_offset = total_height * pitch;
break;
}
default:
if (baseImage->IsCompressed) {
GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat);
pitch = align(tObj->Image[0][firstLevel]->Width, alignment);
if (numLevels > 2) {
GLint width0 = align(minify(tObj->Image[0][firstLevel]->Width), alignment) +
+ align(minify(minify(tObj->Image[0][firstLevel]->Width)), alignment);
if (width0 > pitch)
pitch = width0;
}
pitch = pitch * t->intel.texelBytes;
} else {
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
pitch = (pitch + 3) & ~3;
}
t->intel.base.dirty_images[0] = ~0;
max_offset = 0;
for ( offset = i = 0 ; i < numLevels ; i++ ) {
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
if (!t->intel.image[0][i].image)
break;
t->intel.image[0][i].offset = offset;
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
if (t->intel.image[0][i].image->IsCompressed)
sz = MAX2(1, t->intel.image[0][i].image->Height/4) * pitch;
else
sz = MAX2(2, t->intel.image[0][i].image->Height) * pitch;
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
max_offset = MAX2(max_offset, offset + sz);
/* LPT change: step right after second mipmap.
*/
if (i == 1)
offset += pitch / 2;
else
offset += sz;
}
break;
}
t->intel.Pitch = pitch;
t->intel.base.totalSize = max_offset;
t->intel.max_level = numLevels-1;
}
static void i915SetTexImages( i915ContextPtr i915,
struct gl_texture_object *tObj )
{
GLuint textureFormat;
i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
GLint ss2 = 0;
switch( baseImage->TexFormat->MesaFormat ) {
case MESA_FORMAT_L8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_L8;
break;
case MESA_FORMAT_I8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_I8;
break;
case MESA_FORMAT_A8:
t->intel.texelBytes = 1;
textureFormat = MAPSURF_8BIT | MT_8BIT_A8;
break;
case MESA_FORMAT_AL88:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_AY88;
break;
case MESA_FORMAT_RGB565:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
break;
case MESA_FORMAT_ARGB1555:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
break;
case MESA_FORMAT_ARGB4444:
t->intel.texelBytes = 2;
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444;
break;
case MESA_FORMAT_ARGB8888:
t->intel.texelBytes = 4;
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
break;
case MESA_FORMAT_YCBCR_REV:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL);
ss2 |= SS2_COLORSPACE_CONVERSION;
break;
case MESA_FORMAT_YCBCR:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY);
ss2 |= SS2_COLORSPACE_CONVERSION;
break;
case MESA_FORMAT_RGB_FXT1:
case MESA_FORMAT_RGBA_FXT1:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
break;
case MESA_FORMAT_Z16:
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_16BIT | MT_16BIT_L16);
break;
case MESA_FORMAT_RGBA_DXT1:
case MESA_FORMAT_RGB_DXT1:
/*
* DXTn pitches are Width/4 * blocksize in bytes
* for DXT1: blocksize=8 so Width/4*8 = Width * 2
* for DXT3/5: blocksize=16 so Width/4*16 = Width * 4
*/
t->intel.texelBytes = 2;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
break;
case MESA_FORMAT_RGBA_DXT3:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
break;
case MESA_FORMAT_RGBA_DXT5:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
break;
#if 0
case MESA_FORMAT_Z24_S8:
t->intel.texelBytes = 4;
textureFormat = (MAPSURF_32BIT | MT_32BIT_xL824);
break;
#endif
default:
fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__,
baseImage->TexFormat->MesaFormat);
abort();
}
switch (i915->intel.intelScreen->deviceID) {
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
case PCI_CHIP_I945_GME:
case PCI_CHIP_G33_G:
case PCI_CHIP_Q33_G:
case PCI_CHIP_Q35_G:
i945LayoutTextureImages( i915, tObj );
break;
default:
i915LayoutTextureImages( i915, tObj );
break;
}
t->Setup[I915_TEXREG_MS3] =
(((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
((tObj->Image[0][t->intel.base.firstLevel]->Width - 1) << MS3_WIDTH_SHIFT) |
textureFormat |
MS3_USE_FENCE_REGS);
t->Setup[I915_TEXREG_MS4] =
((((t->intel.Pitch / 4) - 1) << MS4_PITCH_SHIFT) |
MS4_CUBE_FACE_ENA_MASK |
(((t->intel.max_level * 4)) << MS4_MAX_LOD_SHIFT) |
((tObj->Image[0][t->intel.base.firstLevel]->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
t->Setup[I915_TEXREG_SS2] &= ~(SS2_COLORSPACE_CONVERSION);
t->Setup[I915_TEXREG_SS2] |= ss2;
t->intel.dirty = I915_UPLOAD_TEX_ALL;
}
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
* Intel drivers for "other operating systems" implement GL_CLAMP as
* GL_CLAMP_TO_EDGE, so the same is done here.
*/
static GLuint translate_wrap_mode( GLenum wrap )
{
switch( wrap ) {
case GL_REPEAT: return TEXCOORDMODE_WRAP;
case GL_CLAMP: return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */
case GL_CLAMP_TO_EDGE: return TEXCOORDMODE_CLAMP_EDGE;
case GL_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER;
case GL_MIRRORED_REPEAT: return TEXCOORDMODE_MIRROR;
default: return TEXCOORDMODE_WRAP;
}
}
/**
*/
static void i915ImportTexObjState( struct gl_texture_object *texObj )
{
i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData;
int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0;
if(INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
switch (texObj->MinFilter) {
case GL_NEAREST:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_NONE;
break;
case GL_LINEAR:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_NONE;
break;
case GL_NEAREST_MIPMAP_NEAREST:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_NEAREST;
break;
case GL_LINEAR_MIPMAP_NEAREST:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
minFilt = FILTER_NEAREST;
mipFilt = MIPFILTER_LINEAR;
break;
case GL_LINEAR_MIPMAP_LINEAR:
minFilt = FILTER_LINEAR;
mipFilt = MIPFILTER_LINEAR;
break;
default:
break;
}
if ( texObj->MaxAnisotropy > 1.0 ) {
minFilt = FILTER_ANISOTROPIC;
magFilt = FILTER_ANISOTROPIC;
}
else {
switch (texObj->MagFilter) {
case GL_NEAREST:
magFilt = FILTER_NEAREST;
break;
case GL_LINEAR:
magFilt = FILTER_LINEAR;
break;
default:
break;
}
}
if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
texObj->Target != GL_TEXTURE_3D) {
shadow = SS2_SHADOW_ENABLE;
shadow |= intel_translate_compare_func( texObj->CompareFunc );
minFilt = FILTER_4X4_FLAT;
magFilt = FILTER_4X4_FLAT;
}
t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK |
SS2_MIP_FILTER_MASK |
SS2_MAG_FILTER_MASK |
SS2_SHADOW_ENABLE |
SS2_SHADOW_FUNC_MASK);
t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
(mipFilt << SS2_MIP_FILTER_SHIFT) |
(magFilt << SS2_MAG_FILTER_SHIFT) |
shadow);
{
GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK |
SS3_TCY_ADDR_MODE_MASK |
SS3_TCZ_ADDR_MODE_MASK);
GLenum ws = texObj->WrapS;
GLenum wt = texObj->WrapT;
GLenum wr = texObj->WrapR;
t->refs_border_color = 0;
if (texObj->Target == GL_TEXTURE_3D &&
(texObj->MinFilter != GL_NEAREST ||
texObj->MagFilter != GL_NEAREST)) {
/* Try to mimic GL_CLAMP functionality a little better -
* switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
* in use. Only do this for 3D textures at the moment --
* doing it universally would fix the conform texbc.c
* failure, though.
*/
if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER;
if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER;
if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER;
/* 3D textures don't seem to respect the border color.
* Fallback if there's ever a danger that they might refer to
* it.
*/
if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
}
ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT;
ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT;
ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT;
if (ss3 != t->Setup[I915_TEXREG_SS3]) {
t->intel.dirty = I915_UPLOAD_TEX_ALL;
t->Setup[I915_TEXREG_SS3] = ss3;
}
}
{
const GLubyte *color = texObj->_BorderChan;
t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1],
color[2],color[3]);
}
}
static void i915_import_tex_unit( i915ContextPtr i915,
i915TextureObjectPtr t,
GLuint unit )
{
GLuint state[I915_TEX_SETUP_SIZE];
if(INTEL_DEBUG&DEBUG_TEXTURE)
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
if (i915->intel.CurrentTexObj[unit])
i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
t->intel.base.bound |= (1 << unit);
if (t->intel.dirty & I915_UPLOAD_TEX(unit)) {
i915ImportTexObjState( t->intel.base.tObj );
t->intel.dirty &= ~I915_UPLOAD_TEX(unit);
}
state[I915_TEXREG_MS2] = t->intel.TextureOffset;
state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3];
state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4];
state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] &
SS2_LOD_BIAS_MASK);
state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK);
state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] &
SS3_NORMALIZED_COORDS);
state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] &
~(SS3_NORMALIZED_COORDS|
SS3_TEXTUREMAP_INDEX_MASK));
state[I915_TEXREG_SS3] |= (unit<<SS3_TEXTUREMAP_INDEX_SHIFT);
state[I915_TEXREG_SS4] = t->Setup[I915_TEXREG_SS4];
if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
memcpy(i915->state.Tex[unit], state, sizeof(state));
}
}
static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, unit);
if (!(i915->state.active & I915_UPLOAD_TEX(unit))) {
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
}
/* Fallback if there's a texture border */
if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
return GL_FALSE;
}
/* Update state if this is a different texture object to last
* time.
*/
if (i915->intel.CurrentTexObj[unit] != &t->intel ||
(t->intel.dirty & I915_UPLOAD_TEX(unit))) {
i915_import_tex_unit( i915, t, unit);
i915->tex_program.translated = 0;
}
return GL_TRUE;
}
static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
ss3 &= ~SS3_NORMALIZED_COORDS;
if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
}
/* Upload teximages (not pipelined)
*/
if (t->intel.base.dirty_images[0]) {
i915SetTexImages( i915, tObj );
if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
return GL_FALSE;
}
}
return GL_TRUE;
}
static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
ss3 |= SS3_NORMALIZED_COORDS;
if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
}
/* Upload teximages (not pipelined)
*/
if (t->intel.base.dirty_images[0]) {
i915SetTexImages( i915, tObj );
if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
return GL_FALSE;
}
}
return GL_TRUE;
}
static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *tObj = texUnit->_Current;
i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
GLuint face;
ss3 |= SS3_NORMALIZED_COORDS;
if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
}
/* Upload teximages (not pipelined)
*/
if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] ||
t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] ||
t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) {
i915SetTexImages( i915, tObj );
}
/* upload (per face) */
for (face = 0; face < 6; face++) {
if (t->intel.base.dirty_images[face]) {
if (!intelUploadTexImages( &i915->intel, &t->intel, face )) {
return GL_FALSE;
}
}
}
return GL_TRUE;
}
static GLboolean enable_tex_3d( GLcontext *ctx, GLuint unit )
{
struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
/* 3D textures on I915 seem to get bogus border colors, hence this
* fallback:
*/
if (t->refs_border_color)
return GL_FALSE;
return GL_TRUE;
}
static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
{
i915ContextPtr i915 = I915_CONTEXT(ctx);
if (i915->state.active & I915_UPLOAD_TEX(unit)) {
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_FALSE);
}
/* The old texture is no longer bound to this texture unit.
* Mark it as such.
*/
if ( i915->intel.CurrentTexObj[unit] != NULL ) {
i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
i915->intel.CurrentTexObj[unit] = NULL;
}
return GL_TRUE;
}
static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit )
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
if (texUnit->_ReallyEnabled &&
INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
return GL_FALSE;
switch (texUnit->_ReallyEnabled) {
case TEXTURE_1D_BIT:
case TEXTURE_2D_BIT:
return (enable_tex_2d( ctx, unit ) &&
enable_tex_common( ctx, unit ));
case TEXTURE_RECT_BIT:
return (enable_tex_rect( ctx, unit ) &&
enable_tex_common( ctx, unit ));
case TEXTURE_CUBE_BIT:
return (enable_tex_cube( ctx, unit ) &&
enable_tex_common( ctx, unit ));
case TEXTURE_3D_BIT:
return (enable_tex_2d( ctx, unit ) &&
enable_tex_common( ctx, unit ) &&
enable_tex_3d( ctx, unit));
case 0:
return disable_tex( ctx, unit );
default:
return GL_FALSE;
}
}
void i915UpdateTextureState( intelContextPtr intel )
{
GLcontext *ctx = &intel->ctx;
GLboolean ok = GL_TRUE;
GLuint i;
for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) {
ok = i915UpdateTexUnit( ctx, i );
}
FALLBACK( intel, I915_FALLBACK_TEXTURE, !ok );
}

View File

@ -1,469 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "macros.h"
#include "colormac.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
#include "intel_batchbuffer.h"
#include "i915_reg.h"
#include "i915_context.h"
static void
i915_render_prevalidate(struct intel_context *intel)
{
GLcontext *ctx = &intel->ctx;
i915ContextPtr i915 = I915_CONTEXT(intel);
if (ctx->FragmentProgram._Active)
i915ValidateFragmentProgram( i915 );
else {
assert(!ctx->FragmentProgram._MaintainTexEnvProgram);
i915ValidateTextureProgram( i915 );
}
}
static void i915_render_start( intelContextPtr intel )
{
}
static void i915_reduced_primitive_state( intelContextPtr intel,
GLenum rprim )
{
i915ContextPtr i915 = I915_CONTEXT(intel);
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
st1 &= ~ST1_ENABLE;
switch (rprim) {
case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */
case GL_TRIANGLES:
if (intel->ctx.Polygon.StippleFlag &&
intel->hw_stipple)
st1 |= ST1_ENABLE;
break;
case GL_LINES:
case GL_POINTS:
default:
break;
}
i915->intel.reduced_primitive = rprim;
if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
i915->state.Stipple[I915_STPREG_ST1] = st1;
}
}
/* Pull apart the vertex format registers and figure out how large a
* vertex is supposed to be.
*/
static GLboolean i915_check_vertex_size( intelContextPtr intel,
GLuint expected )
{
i915ContextPtr i915 = I915_CONTEXT(intel);
int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
int i, sz = 0;
switch (lis4 & S4_VFMT_XYZW_MASK) {
case S4_VFMT_XY: sz = 2; break;
case S4_VFMT_XYZ: sz = 3; break;
case S4_VFMT_XYW: sz = 3; break;
case S4_VFMT_XYZW: sz = 4; break;
default:
fprintf(stderr, "no xyzw specified\n");
return 0;
}
if (lis4 & S4_VFMT_SPEC_FOG) sz++;
if (lis4 & S4_VFMT_COLOR) sz++;
if (lis4 & S4_VFMT_DEPTH_OFFSET) sz++;
if (lis4 & S4_VFMT_POINT_WIDTH) sz++;
if (lis4 & S4_VFMT_FOG_PARAM) sz++;
for (i = 0 ; i < 8 ; i++) {
switch (lis2 & S2_TEXCOORD_FMT0_MASK) {
case TEXCOORDFMT_2D: sz += 2; break;
case TEXCOORDFMT_3D: sz += 3; break;
case TEXCOORDFMT_4D: sz += 4; break;
case TEXCOORDFMT_1D: sz += 1; break;
case TEXCOORDFMT_2D_16: sz += 1; break;
case TEXCOORDFMT_4D_16: sz += 2; break;
case TEXCOORDFMT_NOT_PRESENT: break;
default:
fprintf(stderr, "bad texcoord fmt %d\n", i);
return GL_FALSE;
}
lis2 >>= S2_TEXCOORD_FMT1_SHIFT;
}
if (sz != expected)
fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected);
return sz == expected;
}
static void i915_emit_invarient_state( intelContextPtr intel )
{
BATCH_LOCALS;
BEGIN_BATCH( 20 );
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE |
AA_LINE_REGION_WIDTH_1_0);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
OUT_BATCH(0);
/* Don't support texture crossbar yet */
OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
CSB_TCB(0, 0) |
CSB_TCB(1, 1) |
CSB_TCB(2, 2) |
CSB_TCB(3, 3) |
CSB_TCB(4, 4) |
CSB_TCB(5, 5) |
CSB_TCB(6, 6) |
CSB_TCB(7, 7));
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |
ENABLE_LINE_STRIP_PROVOKE_VRTX |
ENABLE_TRI_FAN_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) |
TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_TEXKILL_3D_4D |
TEXKILL_4D);
/* Need to initialize this to zero.
*/
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(3) |
(0));
OUT_BATCH(0);
/* XXX: Use this */
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD);
OUT_BATCH(0);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */
OUT_BATCH(0);
/* Don't support twosided stencil yet */
OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS |
BFO_ENABLE_STENCIL_TWO_SIDE |
0 );
ADVANCE_BATCH();
}
#define emit( intel, state, size ) \
do { \
int k; \
BEGIN_BATCH( (size) / sizeof(GLuint)); \
for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \
OUT_BATCH((state)[k]); \
ADVANCE_BATCH(); \
} while (0);
static GLuint get_dirty( struct i915_hw_state *state )
{
GLuint dirty;
/* Workaround the multitex hang - if one texture unit state is
* modified, emit all texture units.
*/
dirty = state->active & ~state->emitted;
if (dirty & I915_UPLOAD_TEX_ALL)
state->emitted &= ~I915_UPLOAD_TEX_ALL;
dirty = state->active & ~state->emitted;
return dirty;
}
static GLuint get_state_size( struct i915_hw_state *state )
{
GLuint dirty = get_dirty(state);
GLuint i;
GLuint sz = 0;
if (dirty & I915_UPLOAD_INVARIENT)
sz += 20 * sizeof(int);
if (dirty & I915_UPLOAD_CTX)
sz += sizeof(state->Ctx);
if (dirty & I915_UPLOAD_BUFFERS)
sz += sizeof(state->Buffer);
if (dirty & I915_UPLOAD_STIPPLE)
sz += sizeof(state->Stipple);
if (dirty & I915_UPLOAD_FOG)
sz += sizeof(state->Fog);
if (dirty & I915_UPLOAD_TEX_ALL) {
int nr = 0;
for (i = 0; i < I915_TEX_UNITS; i++)
if (dirty & I915_UPLOAD_TEX(i))
nr++;
sz += (2+nr*3) * sizeof(GLuint) * 2;
}
if (dirty & I915_UPLOAD_CONSTANTS)
sz += state->ConstantSize * sizeof(GLuint);
if (dirty & I915_UPLOAD_PROGRAM)
sz += state->ProgramSize * sizeof(GLuint);
return sz;
}
/* Push the state into the sarea and/or texture memory.
*/
static void i915_emit_state( intelContextPtr intel )
{
i915ContextPtr i915 = I915_CONTEXT(intel);
struct i915_hw_state *state = i915->current;
int i;
GLuint dirty = get_dirty(state);
GLuint counter = intel->batch.counter;
BATCH_LOCALS;
if (intel->batch.space < get_state_size(state)) {
intelFlushBatch(intel, GL_TRUE);
dirty = get_dirty(state);
counter = intel->batch.counter;
}
if (VERBOSE)
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
if (dirty & I915_UPLOAD_INVARIENT) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
i915_emit_invarient_state( intel );
}
if (dirty & I915_UPLOAD_CTX) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
emit( i915, state->Ctx, sizeof(state->Ctx) );
}
if (dirty & I915_UPLOAD_BUFFERS) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
emit( i915, state->Buffer, sizeof(state->Buffer) );
}
if (dirty & I915_UPLOAD_STIPPLE) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
emit( i915, state->Stipple, sizeof(state->Stipple) );
}
if (dirty & I915_UPLOAD_FOG) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n");
emit( i915, state->Fog, sizeof(state->Fog) );
}
/* Combine all the dirty texture state into a single command to
* avoid lockups on I915 hardware.
*/
if (dirty & I915_UPLOAD_TEX_ALL) {
int nr = 0;
for (i = 0; i < I915_TEX_UNITS; i++)
if (dirty & I915_UPLOAD_TEX(i))
nr++;
BEGIN_BATCH(2+nr*3);
OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr));
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
for (i = 0 ; i < I915_TEX_UNITS ; i++)
if (dirty & I915_UPLOAD_TEX(i)) {
OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]);
OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
}
ADVANCE_BATCH();
BEGIN_BATCH(2+nr*3);
OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr));
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
for (i = 0 ; i < I915_TEX_UNITS ; i++)
if (dirty & I915_UPLOAD_TEX(i)) {
OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]);
OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]);
OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]);
}
ADVANCE_BATCH();
}
if (dirty & I915_UPLOAD_CONSTANTS) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) );
}
if (dirty & I915_UPLOAD_PROGRAM) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize);
emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) );
if (VERBOSE)
i915_disassemble_program( state->Program, state->ProgramSize );
}
state->emitted |= dirty;
intel->batch.last_emit_state = counter;
assert(counter == intel->batch.counter);
}
static void i915_destroy_context( intelContextPtr intel )
{
_tnl_free_vertices(&intel->ctx);
}
/**
* Set the color buffer drawing region.
*/
static void
i915_set_color_region( intelContextPtr intel, const intelRegion *region)
{
i915ContextPtr i915 = I915_CONTEXT(intel);
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_CBUFADDR2] = region->offset;
}
/**
* specify the z-buffer/stencil region
*/
static void
i915_set_z_region( intelContextPtr intel, const intelRegion *region)
{
i915ContextPtr i915 = I915_CONTEXT(intel);
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = region->offset;
}
/**
* Set both the color and Z/stencil drawing regions.
* Similar to two previous functions, but don't use I915_STATECHANGE()
*/
static void
i915_update_color_z_regions(intelContextPtr intel,
const intelRegion *colorRegion,
const intelRegion *depthRegion)
{
i915ContextPtr i915 = I915_CONTEXT(intel);
i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_CBUFADDR2] = colorRegion->offset;
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(depthRegion->pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = depthRegion->offset;
}
static void i915_lost_hardware( intelContextPtr intel )
{
I915_CONTEXT(intel)->state.emitted = 0;
}
static void i915_emit_flush( intelContextPtr intel )
{
BATCH_LOCALS;
BEGIN_BATCH(2);
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE );
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
void i915InitVtbl( i915ContextPtr i915 )
{
i915->intel.vtbl.alloc_tex_obj = i915AllocTexObj;
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
i915->intel.vtbl.clear_with_tris = i915ClearWithTris;
i915->intel.vtbl.rotate_window = i915RotateWindow;
i915->intel.vtbl.destroy = i915_destroy_context;
i915->intel.vtbl.emit_state = i915_emit_state;
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state;
i915->intel.vtbl.render_start = i915_render_start;
i915->intel.vtbl.render_prevalidate = i915_render_prevalidate;
i915->intel.vtbl.set_color_region = i915_set_color_region;
i915->intel.vtbl.set_z_region = i915_set_z_region;
i915->intel.vtbl.update_color_z_regions = i915_update_color_z_regions;
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
i915->intel.vtbl.emit_flush = i915_emit_flush;
}

View File

@ -1,829 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <stdio.h>
#include <errno.h>
#include "mtypes.h"
#include "context.h"
#include "enums.h"
#include "vblank.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
/* ================================================================
* Performance monitoring functions
*/
static void intel_fill_box( intelContextPtr intel,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLubyte r, GLubyte g, GLubyte b )
{
x += intel->drawX;
y += intel->drawY;
if (x >= 0 && y >= 0 &&
x+w < intel->intelScreen->width &&
y+h < intel->intelScreen->height)
intelEmitFillBlitLocked( intel,
intel->intelScreen->cpp,
intel->intelScreen->back.pitch,
intel->intelScreen->back.offset,
x, y, w, h,
INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
r,g,b,0xff));
}
static void intel_draw_performance_boxes( intelContextPtr intel )
{
/* Purple box for page flipping
*/
if ( intel->perf_boxes & I830_BOX_FLIP )
intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 );
/* Red box if we have to wait for idle at any point
*/
if ( intel->perf_boxes & I830_BOX_WAIT )
intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 );
/* Blue box: lost context?
*/
if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT )
intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 );
/* Yellow box for texture swaps
*/
if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD )
intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 );
/* Green box if hardware never idles (as far as we can tell)
*/
if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) )
intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 );
/* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
*/
#if 0
if (intel->dma_used) {
int bar = intel->dma_used / 10240;
if (bar > 100) bar = 100;
if (bar < 1) bar = 1;
intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 );
intel->dma_used = 0;
}
#endif
intel->perf_boxes = 0;
}
static int bad_prim_vertex_nr( int primitive, int nr )
{
switch (primitive & PRIM3D_MASK) {
case PRIM3D_POINTLIST:
return nr < 1;
case PRIM3D_LINELIST:
return (nr & 1) || nr == 0;
case PRIM3D_LINESTRIP:
return nr < 2;
case PRIM3D_TRILIST:
case PRIM3D_RECTLIST:
return nr % 3 || nr == 0;
case PRIM3D_POLY:
case PRIM3D_TRIFAN:
case PRIM3D_TRISTRIP:
case PRIM3D_TRISTRIP_RVRSE:
return nr < 3;
default:
return 1;
}
}
static void intel_flush_inline_primitive( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
GLuint used = intel->batch.ptr - intel->prim.start_ptr;
GLuint vertcount;
assert(intel->prim.primitive != ~0);
if (1) {
/* Check vertex size against the vertex we're specifying to
* hardware. If it's wrong, ditch the primitive.
*/
if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size ))
goto do_discard;
vertcount = (used - 4)/ (intel->vertex_size * 4);
if (!vertcount)
goto do_discard;
if (vertcount * intel->vertex_size * 4 != used - 4) {
fprintf(stderr, "vertex size confusion %d %d\n", used,
intel->vertex_size * vertcount * 4);
goto do_discard;
}
if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,
vertcount);
goto do_discard;
}
}
if (used < 8)
goto do_discard;
*(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
intel->prim.primitive |
(used/4-2));
goto finished;
do_discard:
intel->batch.ptr -= used;
intel->batch.space += used;
assert(intel->batch.space >= 0);
finished:
intel->prim.primitive = ~0;
intel->prim.start_ptr = 0;
intel->prim.flush = 0;
}
/* Emit a primitive referencing vertices in a vertex buffer.
*/
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
{
BATCH_LOCALS;
if (0)
fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
/* Finish any in-progress primitive:
*/
INTEL_FIREVERTICES( intel );
/* Emit outstanding state:
*/
intel->vtbl.emit_state( intel );
/* Make sure there is some space in this buffer:
*/
if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) {
intelFlushBatch(intel, GL_TRUE);
intel->vtbl.emit_state( intel );
}
#if 1
if (((unsigned long)intel->batch.ptr) & 0x4) {
BEGIN_BATCH(1);
OUT_BATCH(0);
ADVANCE_BATCH();
}
#endif
/* Emit a slot which will be filled with the inline primitive
* command later.
*/
BEGIN_BATCH(2);
OUT_BATCH( 0 );
intel->prim.start_ptr = batch_ptr;
intel->prim.primitive = prim;
intel->prim.flush = intel_flush_inline_primitive;
intel->batch.contains_geometry = 1;
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
void intelRestartInlinePrimitive( intelContextPtr intel )
{
GLuint prim = intel->prim.primitive;
intel_flush_inline_primitive( &intel->ctx );
if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */
intelStartInlinePrimitive( intel, prim );
}
void intelWrapInlinePrimitive( intelContextPtr intel )
{
GLuint prim = intel->prim.primitive;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
intel_flush_inline_primitive( &intel->ctx );
intelFlushBatch(intel, GL_TRUE);
intelStartInlinePrimitive( intel, prim );
}
/* Emit a primitive with space for inline vertices.
*/
GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
int primitive,
int dwords,
int vertex_size )
{
GLuint *tmp = 0;
BATCH_LOCALS;
if (0)
fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords);
/* Emit outstanding state:
*/
intel->vtbl.emit_state( intel );
if ((1+dwords)*4 >= intel->batch.space) {
intelFlushBatch(intel, GL_TRUE);
intel->vtbl.emit_state( intel );
}
if (1) {
int used = dwords * 4;
int vertcount;
/* Check vertex size against the vertex we're specifying to
* hardware. If it's wrong, ditch the primitive.
*/
if (!intel->vtbl.check_vertex_size( intel, vertex_size ))
goto do_discard;
vertcount = dwords / vertex_size;
if (dwords % vertex_size) {
fprintf(stderr, "did not request a whole number of vertices\n");
goto do_discard;
}
if (bad_prim_vertex_nr( primitive, vertcount )) {
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount);
goto do_discard;
}
if (used < 8)
goto do_discard;
}
/* Emit 3D_PRIMITIVE commands:
*/
BEGIN_BATCH(1 + dwords);
OUT_BATCH( _3DPRIMITIVE |
primitive |
(dwords-1) );
tmp = (GLuint *)batch_ptr;
batch_ptr += dwords * 4;
ADVANCE_BATCH();
intel->batch.contains_geometry = 1;
do_discard:
return tmp;
}
static void intelWaitForFrameCompletion( intelContextPtr intel )
{
drm_i915_sarea_t *sarea = (drm_i915_sarea_t *)intel->sarea;
if (intel->do_irqs) {
if (intelGetLastFrame(intel) < sarea->last_dispatch) {
if (!intel->irqsEmitted) {
while (intelGetLastFrame (intel) < sarea->last_dispatch)
;
}
else {
intelWaitIrq( intel, intel->alloc.irq_emitted );
}
intel->irqsEmitted = 10;
}
if (intel->irqsEmitted) {
LOCK_HARDWARE( intel );
intelEmitIrqLocked( intel );
intel->irqsEmitted--;
UNLOCK_HARDWARE( intel );
}
}
else {
while (intelGetLastFrame (intel) < sarea->last_dispatch) {
if (intel->do_usleeps)
DO_USLEEP( 1 );
}
}
}
/*
* Copy the back buffer to the front buffer.
*/
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
intelContextPtr intel;
const intelScreenPrivate *intelScreen;
GLboolean missed_target;
int64_t ust;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
intelScreen = intel->intelScreen;
if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 &&
!(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
intelScreen->current_rotation == 0) {
unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags);
unsigned int target;
drm_i915_vblank_swap_t swap;
swap.drawable = dPriv->hHWDrawable;
swap.seqtype = DRM_VBLANK_ABSOLUTE;
target = swap.sequence = intel->vbl_seq + interval;
if (intel->vblank_flags & VBLANK_FLAG_SYNC) {
swap.seqtype |= DRM_VBLANK_NEXTONMISS;
} else if (interval == 0) {
goto noschedule;
}
if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) {
swap.seqtype |= DRM_VBLANK_SECONDARY;
}
if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
sizeof(swap))) {
intel->swap_scheduled = 1;
intel->vbl_seq = swap.sequence;
swap.sequence -= target;
missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
}
} else {
intel->swap_scheduled = 0;
}
noschedule:
if (!intel->swap_scheduled) {
intelWaitForFrameCompletion( intel );
LOCK_HARDWARE( intel );
if (!rect)
{
UNLOCK_HARDWARE( intel );
driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
LOCK_HARDWARE( intel );
}
{
const intelScreenPrivate *intelScreen = intel->intelScreen;
const __DRIdrawablePrivate *dPriv = intel->driDrawable;
const int nbox = dPriv->numClipRects;
const drm_clip_rect_t *pbox = dPriv->pClipRects;
drm_clip_rect_t box;
const int cpp = intelScreen->cpp;
const int pitch = intelScreen->front.pitch; /* in bytes */
int i;
GLuint CMD, BR13;
BATCH_LOCALS;
switch(cpp) {
case 2:
BR13 = (pitch) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = (pitch) | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
BR13 = (pitch) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
}
if (0)
intel_draw_performance_boxes( intel );
for (i = 0 ; i < nbox; i++, pbox++)
{
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->width ||
pbox->y2 > intelScreen->height) {
_mesa_warning(&intel->ctx, "Bad cliprect in intelCopyBuffer()");
continue;
}
box = *pbox;
if (rect)
{
if (rect->x1 > box.x1)
box.x1 = rect->x1;
if (rect->y1 > box.y1)
box.y1 = rect->y1;
if (rect->x2 < box.x2)
box.x2 = rect->x2;
if (rect->y2 < box.y2)
box.y2 = rect->y2;
if (box.x1 > box.x2 || box.y1 > box.y2)
continue;
}
BEGIN_BATCH( 8);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (box.y1 << 16) | box.x1 );
OUT_BATCH( (box.y2 << 16) | box.x2 );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->front.offset );
else
OUT_BATCH( intelScreen->back.offset );
OUT_BATCH( (box.y1 << 16) | box.x1 );
OUT_BATCH( BR13 & 0xffff );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->back.offset );
else
OUT_BATCH( intelScreen->front.offset );
ADVANCE_BATCH();
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
UNLOCK_HARDWARE( intel );
}
if (!rect)
{
intel->swap_count++;
(*dri_interface->getUST)(&ust);
if (missed_target) {
intel->swap_missed_count++;
intel->swap_missed_ust = ust - intel->swap_ust;
}
intel->swap_ust = ust;
}
}
void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch, /* in bytes */
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color )
{
GLuint BR13, CMD;
BATCH_LOCALS;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
break;
default:
return;
}
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (y << 16) | x );
OUT_BATCH( ((y+h) << 16) | (x+w) );
OUT_BATCH( dst_offset );
OUT_BATCH( color );
ADVANCE_BATCH();
}
/* Copy BitBlt
*/
void intelEmitCopyBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_offset,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h )
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
BATCH_LOCALS;
src_pitch *= cpp;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
case 3:
BR13 = dst_pitch | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
return;
}
if (dst_y2 < dst_y ||
dst_x2 < dst_x) {
return;
}
BEGIN_BATCH( 12);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (dst_y << 16) | dst_x );
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
OUT_BATCH( dst_offset );
OUT_BATCH( (src_y << 16) | src_x );
OUT_BATCH( src_pitch );
OUT_BATCH( src_offset );
ADVANCE_BATCH();
}
void intelClearWithBlit(GLcontext *ctx, GLbitfield buffers, GLboolean allFoo,
GLint cx1Foo, GLint cy1Foo, GLint cwFoo, GLint chFoo)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cx, cy, cw, ch;
GLboolean all;
GLint pitch;
GLint cpp = intelScreen->cpp;
GLint i;
GLuint BR13, CMD, D_CMD;
BATCH_LOCALS;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
/* get clear bounds after locking */
cx = intel->ctx.DrawBuffer->_Xmin;
cy = intel->ctx.DrawBuffer->_Ymin;
cw = intel->ctx.DrawBuffer->_Xmax - cx;
ch = intel->ctx.DrawBuffer->_Ymax - cy;
all = (cw == intel->ctx.DrawBuffer->Width &&
ch == intel->ctx.DrawBuffer->Height);
pitch = intelScreen->front.pitch;
clear_color = intel->ClearColor;
clear_depth = 0;
if (buffers & BUFFER_BIT_DEPTH) {
clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
}
if (buffers & BUFFER_BIT_STENCIL) {
clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
}
switch(cpp) {
case 2:
BR13 = (0xF0 << 16) | (pitch) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = (0xF0 << 16) | (pitch) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD |
XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
D_CMD = XY_COLOR_BLT_CMD;
if (buffers & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
if (buffers & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
break;
default:
BR13 = (0xF0 << 16) | (pitch) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
}
{
/* flip top to bottom */
cy = intel->driDrawable->h - cy - ch;
cx = cx + intel->drawX;
cy += intel->drawY;
/* adjust for page flipping */
if ( intel->sarea->pf_current_page == 1 ) {
GLuint tmp = buffers;
buffers &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
if ( tmp & BUFFER_BIT_FRONT_LEFT ) buffers |= BUFFER_BIT_BACK_LEFT;
if ( tmp & BUFFER_BIT_BACK_LEFT ) buffers |= BUFFER_BIT_FRONT_LEFT;
}
for (i = 0 ; i < intel->numClipRects ; i++)
{
drm_clip_rect_t *box = &intel->pClipRects[i];
drm_clip_rect_t b;
if (!all) {
GLint x = box->x1;
GLint y = box->y1;
GLint w = box->x2 - x;
GLint h = box->y2 - y;
if (x < cx) w -= cx - x, x = cx;
if (y < cy) h -= cy - y, y = cy;
if (x + w > cx + cw) w = cx + cw - x;
if (y + h > cy + ch) h = cy + ch - y;
if (w <= 0) continue;
if (h <= 0) continue;
b.x1 = x;
b.y1 = y;
b.x2 = x + w;
b.y2 = y + h;
} else {
b = *box;
}
if (b.x1 > b.x2 ||
b.y1 > b.y2 ||
b.x2 > intelScreen->width ||
b.y2 > intelScreen->height)
continue;
if ( buffers & BUFFER_BIT_FRONT_LEFT ) {
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->front.offset );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
if ( buffers & BUFFER_BIT_BACK_LEFT ) {
BEGIN_BATCH( 6);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->back.offset );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
if ( buffers & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
BEGIN_BATCH( 6);
OUT_BATCH( D_CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_BATCH( intelScreen->depth.offset );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
UNLOCK_HARDWARE( intel );
}
void intelDestroyBatchBuffer( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
if (intel->alloc.offset) {
intelFreeAGP( intel, intel->alloc.ptr );
intel->alloc.ptr = NULL;
intel->alloc.offset = 0;
}
else if (intel->alloc.ptr) {
free(intel->alloc.ptr);
intel->alloc.ptr = NULL;
}
memset(&intel->batch, 0, sizeof(intel->batch));
}
void intelInitBatchBuffer( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
/* This path isn't really safe with rotate:
*/
if (getenv("INTEL_BATCH") && intel->intelScreen->allow_batchbuffer) {
switch (intel->intelScreen->deviceID) {
case PCI_CHIP_I865_G:
/* HW bug? Seems to crash if batchbuffer crosses 4k boundary.
*/
intel->alloc.size = 8 * 1024;
break;
default:
/* This is the smallest amount of memory the kernel deals with.
* We'd ideally like to make this smaller.
*/
intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity;
break;
}
intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
if (intel->alloc.ptr)
intel->alloc.offset =
intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
else
intel->alloc.offset = 0; /* OK? */
}
/* The default is now to use a local buffer and pass that to the
* kernel. This is also a fallback if allocation fails on the
* above path:
*/
if (!intel->alloc.ptr) {
intel->alloc.size = 8 * 1024;
intel->alloc.ptr = malloc( intel->alloc.size );
intel->alloc.offset = 0;
}
assert(intel->alloc.ptr);
}

View File

@ -1,126 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H
#include "intel_context.h"
#include "intel_ioctl.h"
#define BATCH_LOCALS GLubyte *batch_ptr;
/* #define VERBOSE 0 */
#ifndef VERBOSE
extern int VERBOSE;
#endif
#define BEGIN_BATCH(n) \
do { \
if (VERBOSE) fprintf(stderr, \
"BEGIN_BATCH(%ld) in %s, %d dwords free\n", \
((unsigned long)n), __FUNCTION__, \
intel->batch.space/4); \
if (intel->batch.space < (n)*4) \
intelFlushBatch(intel, GL_TRUE); \
if (intel->batch.space == intel->batch.size) intel->batch.func = __FUNCTION__; \
batch_ptr = intel->batch.ptr; \
} while (0)
#define OUT_BATCH(n) \
do { \
*(GLuint *)batch_ptr = (n); \
if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \
batch_ptr += 4; \
} while (0)
#define ADVANCE_BATCH() \
do { \
if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \
intel->batch.space -= (batch_ptr - intel->batch.ptr); \
intel->batch.ptr = batch_ptr; \
assert(intel->batch.space >= 0); \
} while(0)
extern void intelInitBatchBuffer( GLcontext *ctx );
extern void intelDestroyBatchBuffer( GLcontext *ctx );
extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim );
extern void intelWrapInlinePrimitive( intelContextPtr intel );
extern void intelRestartInlinePrimitive( intelContextPtr intel );
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
int primitive, int dwords,
int vertex_size);
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv,
const drm_clip_rect_t *rect);
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch);
extern void intelEmitCopyBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort src_pitch,
GLuint src_offset,
GLshort dst_pitch,
GLuint dst_offset,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
GLshort w, GLshort h );
extern void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
GLshort dst_pitch,
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color );
static __inline GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
GLuint dwords )
{
GLuint sz = dwords * sizeof(GLuint);
GLuint *ptr;
if (intel->batch.space < sz) {
intelWrapInlinePrimitive( intel );
/* assert(intel->batch.space >= sz); */
}
/* assert(intel->prim.primitive != ~0); */
ptr = (GLuint *)intel->batch.ptr;
intel->batch.ptr += sz;
intel->batch.space -= sz;
return ptr;
}
#endif

View File

@ -1,776 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "matrix.h"
#include "simple_list.h"
#include "extensions.h"
#include "framebuffer.h"
#include "imports.h"
#include "points.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
#include "drivers/common/driverfuncs.h"
#include "intel_screen.h"
#include "i830_dri.h"
#include "i830_common.h"
#include "intel_tex.h"
#include "intel_span.h"
#include "intel_tris.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
#ifndef INTEL_DEBUG
int INTEL_DEBUG = (0);
#endif
#define need_GL_ARB_multisample
#define need_GL_ARB_point_parameters
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_fog_coord
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
#include "extension_helper.h"
#ifndef VERBOSE
int VERBOSE = 0;
#endif
#if DEBUG_LOCKING
char *prevLockFile;
int prevLockLine;
#endif
/***************************************
* Mesa's Driver Functions
***************************************/
#define DRIVER_DATE "20061017"
const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
{
const char * chipset;
static char buffer[128];
switch (name) {
case GL_VENDOR:
return (GLubyte *)"Tungsten Graphics, Inc";
break;
case GL_RENDERER:
switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) {
case PCI_CHIP_845_G:
chipset = "Intel(R) 845G"; break;
case PCI_CHIP_I830_M:
chipset = "Intel(R) 830M"; break;
case PCI_CHIP_I855_GM:
chipset = "Intel(R) 852GM/855GM"; break;
case PCI_CHIP_I865_G:
chipset = "Intel(R) 865G"; break;
case PCI_CHIP_I915_G:
chipset = "Intel(R) 915G"; break;
case PCI_CHIP_I915_GM:
chipset = "Intel(R) 915GM"; break;
case PCI_CHIP_I945_G:
chipset = "Intel(R) 945G"; break;
case PCI_CHIP_I945_GM:
chipset = "Intel(R) 945GM"; break;
case PCI_CHIP_I945_GME:
chipset = "Intel(R) 945GME"; break;
case PCI_CHIP_G33_G:
chipset = "Intel(R) G33"; break;
case PCI_CHIP_Q35_G:
chipset = "Intel(R) Q35"; break;
case PCI_CHIP_Q33_G:
chipset = "Intel(R) Q33"; break;
default:
chipset = "Unknown Intel Chipset"; break;
}
(void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
return (GLubyte *) buffer;
default:
return NULL;
}
}
/**
* Extension strings exported by the intel driver.
*
* \note
* It appears that ARB_texture_env_crossbar has "disappeared" compared to the
* old i830-specific driver.
*/
const struct dri_extension card_extensions[] =
{
{ "GL_ARB_multisample", GL_ARB_multisample_functions },
{ "GL_ARB_multitexture", NULL },
{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
{ "GL_ARB_texture_cube_map", NULL },
{ "GL_ARB_texture_env_add", NULL },
{ "GL_ARB_texture_env_combine", NULL },
{ "GL_ARB_texture_env_dot3", NULL },
{ "GL_ARB_texture_mirrored_repeat", NULL },
{ "GL_ARB_texture_rectangle", NULL },
{ "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
{ "GL_ARB_window_pos", GL_ARB_window_pos_functions },
{ "GL_EXT_blend_color", GL_EXT_blend_color_functions },
{ "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions },
{ "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
{ "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
{ "GL_EXT_blend_subtract", NULL },
{ "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions },
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
{ "GL_EXT_texture_edge_clamp", NULL },
{ "GL_EXT_texture_env_combine", NULL },
{ "GL_EXT_texture_env_dot3", NULL },
{ "GL_EXT_texture_filter_anisotropic", NULL },
{ "GL_EXT_texture_lod_bias", NULL },
{ "GL_3DFX_texture_compression_FXT1", NULL },
{ "GL_APPLE_client_storage", NULL },
{ "GL_MESA_pack_invert", NULL },
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
{ "GL_NV_vertex_program1_1", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
{ NULL, NULL }
};
extern const struct tnl_pipeline_stage _intel_render_stage;
static const struct tnl_pipeline_stage *intel_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_vertex_cull_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
&_tnl_point_attenuation_stage,
&_tnl_vertex_program_stage,
#if 1
&_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
#endif
&_tnl_render_stage,
0,
};
static const struct dri_debug_control debug_control[] =
{
{ "fall", DEBUG_FALLBACKS },
{ "tex", DEBUG_TEXTURE },
{ "ioctl", DEBUG_IOCTL },
{ "prim", DEBUG_PRIMS },
{ "vert", DEBUG_VERTS },
{ "state", DEBUG_STATE },
{ "verb", DEBUG_VERBOSE },
{ "dri", DEBUG_DRI },
{ "dma", DEBUG_DMA },
{ "san", DEBUG_SANITY },
{ "sync", DEBUG_SYNC },
{ "sleep", DEBUG_SLEEP },
{ "pix", DEBUG_PIXEL },
{ NULL, 0 }
};
static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
_vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
}
void intelInitDriverFunctions( struct dd_function_table *functions )
{
_mesa_init_driver_functions( functions );
functions->Clear = intelClear;
functions->Flush = intelglFlush;
functions->Finish = intelFinish;
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
intelInitTextureFuncs( functions );
intelInitPixelFuncs( functions );
intelInitStateFuncs( functions );
}
static void intel_emit_invarient_state( GLcontext *ctx )
{
}
GLboolean intelInitContext( intelContextPtr intel,
const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate,
struct dd_function_table *functions )
{
GLcontext *ctx = &intel->ctx;
GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
drmI830Sarea *saPriv = (drmI830Sarea *)
(((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
int fthrottle_mode;
if (!_mesa_initialize_context(&intel->ctx,
mesaVis, shareCtx,
functions,
(void*) intel))
return GL_FALSE;
driContextPriv->driverPrivate = intel;
intel->intelScreen = intelScreen;
intel->driScreen = sPriv;
intel->sarea = saPriv;
(void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
make_empty_list( & intel->swapped );
driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
intel->driScreen->myNum, "i915");
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 3.0;
ctx->Const.MaxLineWidthAA = 3.0;
ctx->Const.LineWidthGranularity = 1.0;
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
ctx->Const.MaxPointSize = 255.0;
ctx->Const.MaxPointSizeAA = 3.0;
ctx->Const.PointSizeGranularity = 1.0;
/* reinitialize the context point state.
* It depend on constants in __GLcontextRec::Const
*/
_mesa_init_point(ctx);
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
_vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
/* Install the customized pipeline: */
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, intel_pipeline );
/* Configure swrast to match hardware characteristics: */
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
/* Dri stuff */
intel->hHWContext = driContextPriv->hHWContext;
intel->driFd = sPriv->fd;
intel->driHwLock = (drmLock *) &sPriv->pSAREA->lock;
intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
intel->hw_stipple = 1;
switch(mesaVis->depthBits) {
case 0: /* what to do in this case? */
case 16:
intel->depth_scale = 1.0/0xffff;
intel->polygon_offset_scale = 1.0/0xffff;
intel->depth_clear_mask = ~0;
intel->ClearDepth = 0xffff;
break;
case 24:
intel->depth_scale = 1.0/0xffffff;
intel->polygon_offset_scale = 2.0/0xffffff; /* req'd to pass glean */
intel->depth_clear_mask = 0x00ffffff;
intel->stencil_clear_mask = 0xff000000;
intel->ClearDepth = 0x00ffffff;
break;
default:
assert(0);
break;
}
/* Initialize swrast, tnl driver tables: */
intelInitSpanFuncs( ctx );
intelInitTriFuncs( ctx );
intel->RenderIndex = ~0;
fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
intel->iw.irq_seq = -1;
intel->irqsEmitted = 0;
intel->do_irqs = (intel->intelScreen->irq_active &&
fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
intel->vblank_flags = (intel->intelScreen->irq_active != 0)
? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
(*dri_interface->getUST)(&intel->swap_ust);
_math_matrix_ctr (&intel->ViewportMatrix);
driInitExtensions( ctx, card_extensions, GL_TRUE );
if (intel->ctx.Mesa_DXTn) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
}
else if (driQueryOptionb (&intel->optionCache, "force_s3tc_enable")) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
}
/* driInitTextureObjects( ctx, & intel->swapped, */
/* DRI_TEXMGR_DO_TEXTURE_1D | */
/* DRI_TEXMGR_DO_TEXTURE_2D | */
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
intelInitBatchBuffer(&intel->ctx);
intel->prim.flush = intel_emit_invarient_state;
intel->prim.primitive = ~0;
#if DO_DEBUG
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
#endif
#ifndef VERBOSE
if (getenv("INTEL_VERBOSE"))
VERBOSE=1;
#endif
if (getenv("INTEL_NO_RAST") ||
getenv("INTEL_NO_RAST")) {
fprintf(stderr, "disabling 3D rasterization\n");
FALLBACK(intel, INTEL_FALLBACK_USER, 1);
}
return GL_TRUE;
}
void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
{
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
assert(intel); /* should never be null */
if (intel) {
GLboolean release_texture_heaps;
INTEL_FIREVERTICES( intel );
intel->vtbl.destroy( intel );
release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
_swsetup_DestroyContext (&intel->ctx);
_tnl_DestroyContext (&intel->ctx);
_vbo_DestroyContext (&intel->ctx);
_swrast_DestroyContext (&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
intelDestroyBatchBuffer(&intel->ctx);
if ( release_texture_heaps ) {
/* This share group is about to go away, free our private
* texture object data.
*/
int i;
for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
driDestroyTextureHeap( intel->texture_heaps[ i ] );
intel->texture_heaps[ i ] = NULL;
}
assert( is_empty_list( & intel->swapped ) );
}
/* free the Mesa context */
_mesa_destroy_context(&intel->ctx);
}
}
void intelSetFrontClipRects( intelContextPtr intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
}
void intelSetBackClipRects( intelContextPtr intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
} else {
intel->numClipRects = dPriv->numBackClipRects;
intel->pClipRects = dPriv->pBackClipRects;
intel->drawX = dPriv->backX;
intel->drawY = dPriv->backY;
if (dPriv->numBackClipRects == 1 &&
dPriv->x == dPriv->backX &&
dPriv->y == dPriv->backY) {
/* Repeat the calculation of the back cliprect dimensions here
* as early versions of dri.a in the Xserver are incorrect. Try
* very hard not to restrict future versions of dri.a which
* might eg. allocate truly private back buffers.
*/
int x1, y1;
int x2, y2;
x1 = dPriv->x;
y1 = dPriv->y;
x2 = dPriv->x + dPriv->w;
y2 = dPriv->y + dPriv->h;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
if (x1 == dPriv->pBackClipRects[0].x1 &&
y1 == dPriv->pBackClipRects[0].y1) {
dPriv->pBackClipRects[0].x2 = x2;
dPriv->pBackClipRects[0].y2 = y2;
}
}
}
}
void intelWindowMoved( intelContextPtr intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate;
if (!intel->ctx.DrawBuffer) {
intelSetFrontClipRects( intel );
}
else {
driUpdateFramebufferSize(&intel->ctx, dPriv);
switch (drawFb->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects( intel );
break;
case BUFFER_BIT_BACK_LEFT:
intelSetBackClipRects( intel );
break;
default:
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
intelSetFrontClipRects( intel );
}
}
if (drawFb->Width != dPriv->w || drawFb->Height != dPriv->h) {
/* update Mesa's notion of framebuffer/window size */
_mesa_resize_framebuffer(&intel->ctx, drawFb, dPriv->w, dPriv->h);
drawFb->Initialized = GL_TRUE; /* XXX remove someday */
}
/* Set state we know depends on drawable parameters:
*/
{
GLcontext *ctx = &intel->ctx;
if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
.y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x,
.x2 = sarea->planeA_x + sarea->planeA_w,
.y1 = sarea->planeA_y,
.y2 = sarea->planeA_y + sarea->planeA_h };
drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x,
.x2 = sarea->planeB_x + sarea->planeB_w,
.y1 = sarea->planeB_y,
.y2 = sarea->planeB_y + sarea->planeB_h };
GLint areaA = driIntersectArea( drw_rect, planeA_rect );
GLint areaB = driIntersectArea( drw_rect, planeB_rect );
GLuint flags = intel->vblank_flags;
if (areaB > areaA || (areaA == areaB && areaB > 0)) {
flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
} else {
flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY;
}
if (flags != intel->vblank_flags) {
intel->vblank_flags = flags;
driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq);
}
} else {
intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
}
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
ctx->Driver.DepthRange( ctx,
ctx->Viewport.Near,
ctx->Viewport.Far );
}
}
GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
if (driContextPriv) {
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
if ( intel->driDrawable != driDrawPriv ) {
/* Shouldn't the readbuffer be stored also? */
driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
&intel->vbl_seq );
intel->driDrawable = driDrawPriv;
intelWindowMoved( intel );
}
_mesa_make_current(&intel->ctx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] );
} else {
_mesa_make_current(NULL, NULL, NULL);
}
return GL_TRUE;
}
/**
* Use the information in the sarea to update the screen parameters
* related to screen rotation.
*/
static void
intelUpdateScreenRotation(intelContextPtr intel,
__DRIscreenPrivate *sPriv,
drmI830Sarea *sarea)
{
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
intelRegion *colorBuf;
intelUnmapScreenRegions(intelScreen);
intelUpdateScreenFromSAREA(intelScreen, sarea);
/* update the current hw offsets for the color and depth buffers */
if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
colorBuf = &intelScreen->back;
else
colorBuf = &intelScreen->front;
intel->vtbl.update_color_z_regions(intel, colorBuf, &intelScreen->depth);
if (!intelMapScreenRegions(sPriv)) {
fprintf(stderr, "ERROR Remapping screen regions!!!\n");
}
}
void intelGetLock( intelContextPtr intel, GLuint flags )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
__DRIscreenPrivate *sPriv = intel->driScreen;
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
drmI830Sarea * sarea = intel->sarea;
unsigned i;
drmGetLock(intel->driFd, intel->hHWContext, flags);
/* If the window moved, may need to set a new cliprect now.
*
* NOTE: This releases and regains the hw lock, so all state
* checking must be done *after* this call:
*/
if (dPriv)
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
intelWindowMoved( intel );
intel->lastStamp = dPriv->lastStamp;
}
/* If we lost context, need to dump all registers to hardware.
* Note that we don't care about 2d contexts, even if they perform
* accelerated commands, so the DRI locking in the X server is even
* more broken than usual.
*/
if (sarea->width != intelScreen->width ||
sarea->height != intelScreen->height ||
sarea->rotation != intelScreen->current_rotation) {
intelUpdateScreenRotation(intel, sPriv, sarea);
/* This will drop the outstanding batchbuffer on the floor */
intel->batch.ptr -= (intel->batch.size - intel->batch.space);
intel->batch.space = intel->batch.size;
/* lose all primitives */
intel->prim.primitive = ~0;
intel->prim.start_ptr = 0;
intel->prim.flush = 0;
intel->vtbl.lost_hardware( intel );
intel->lastStamp = 0; /* force window update */
/* Release batch buffer
*/
intelDestroyBatchBuffer(&intel->ctx);
intelInitBatchBuffer(&intel->ctx);
intel->prim.flush = intel_emit_invarient_state;
/* Still need to reset the global LRU?
*/
intel_driReinitTextureHeap( intel->texture_heaps[0], intel->intelScreen->tex.size );
}
/* Shared texture managment - if another client has played with
* texture space, figure out which if any of our textures have been
* ejected, and update our global LRU.
*/
for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
}
}
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
intelContextPtr intel;
GLcontext *ctx;
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
intelScreenPrivate *screen = intel->intelScreen;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv, NULL );
}
if (screen->current_rotation != 0) {
intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
}
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
intelContextPtr intel;
GLcontext *ctx;
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
intelCopyBuffer( dPriv, &rect );
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}

View File

@ -1,564 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTELCONTEXT_INC
#define INTELCONTEXT_INC
#include "mtypes.h"
#include "drm.h"
#include "mm.h"
#include "texmem.h"
#include "vblank.h"
#include "intel_screen.h"
#include "i915_drm.h"
#include "i830_common.h"
#include "tnl/t_vertex.h"
#define TAG(x) intel##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
#define DV_PF_555 (1<<8)
#define DV_PF_565 (2<<8)
#define DV_PF_8888 (3<<8)
#define INTEL_CONTEXT(ctx) ((intelContextPtr)(ctx))
typedef struct intel_context intelContext;
typedef struct intel_context *intelContextPtr;
typedef struct intel_texture_object *intelTextureObjectPtr;
typedef void (*intel_tri_func)(intelContextPtr, intelVertex *, intelVertex *,
intelVertex *);
typedef void (*intel_line_func)(intelContextPtr, intelVertex *, intelVertex *);
typedef void (*intel_point_func)(intelContextPtr, intelVertex *);
#define INTEL_FALLBACK_DRAW_BUFFER 0x1
#define INTEL_FALLBACK_READ_BUFFER 0x2
#define INTEL_FALLBACK_USER 0x4
#define INTEL_FALLBACK_NO_BATCHBUFFER 0x8
#define INTEL_FALLBACK_NO_TEXMEM 0x10
#define INTEL_FALLBACK_RENDERMODE 0x20
extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode );
#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
#define INTEL_TEX_MAXLEVELS 10
struct intel_texture_object
{
driTextureObject base; /* the parent class */
GLuint texelBytes;
GLuint age;
GLuint Pitch;
GLuint Height;
GLuint TextureOffset;
GLubyte *BufAddr;
GLuint min_level;
GLuint max_level;
GLuint depth_pitch;
struct {
const struct gl_texture_image *image;
GLuint offset; /* into BufAddr */
GLuint height;
GLuint internalFormat;
} image[6][INTEL_TEX_MAXLEVELS];
GLuint dirty;
GLuint firstLevel,lastLevel;
};
struct intel_context
{
GLcontext ctx; /* the parent class */
struct {
void (*destroy)( intelContextPtr intel );
void (*emit_state)( intelContextPtr intel );
void (*lost_hardware)( intelContextPtr intel );
void (*update_texture_state)( intelContextPtr intel );
void (*render_start)( intelContextPtr intel );
void (*render_prevalidate) (struct intel_context * intel);
void (*set_color_region)( intelContextPtr intel, const intelRegion *reg );
void (*set_z_region)( intelContextPtr intel, const intelRegion *reg );
void (*update_color_z_regions)(intelContextPtr intel,
const intelRegion *colorRegion,
const intelRegion *depthRegion);
void (*emit_flush)( intelContextPtr intel );
void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim );
GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected );
void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch);
void (*rotate_window)( intelContextPtr intel,
__DRIdrawablePrivate *dPriv, GLuint srcBuf);
intelTextureObjectPtr (*alloc_tex_obj)( struct gl_texture_object *tObj );
} vtbl;
GLint refcount;
GLuint Fallback;
GLuint NewGLState;
struct {
GLuint start_offset;
GLint size;
GLint space;
GLubyte *ptr;
GLuint counter;
GLuint last_emit_state;
GLboolean contains_geometry;
const char *func;
GLuint last_swap;
} batch;
struct {
void *ptr;
GLint size;
GLuint offset;
GLuint active_buf;
GLuint irq_emitted;
} alloc;
struct {
GLuint primitive;
GLubyte *start_ptr;
void (*flush)( GLcontext * );
} prim;
GLboolean locked;
GLubyte clear_red;
GLubyte clear_green;
GLubyte clear_blue;
GLubyte clear_alpha;
GLuint ClearColor;
GLuint ClearDepth;
GLuint coloroffset;
GLuint specoffset;
/* Support for duplicating XYZW as WPOS parameter (crutch for I915).
*/
GLuint wpos_offset;
GLuint wpos_size;
struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
GLuint vertex_attr_count;
GLfloat depth_scale;
GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */
GLuint depth_clear_mask;
GLuint stencil_clear_mask;
GLboolean hw_stencil;
GLboolean hw_stipple;
/* Texture object bookkeeping
*/
GLuint nr_heaps;
driTexHeap * texture_heaps[1];
driTextureObject swapped;
GLuint lastStamp;
struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS];
/* State for intelvb.c and inteltris.c.
*/
GLuint RenderIndex;
GLmatrix ViewportMatrix;
GLenum render_primitive;
GLenum reduced_primitive;
GLuint vertex_size;
unsigned char *verts; /* points to tnl->clipspace.vertex_buf */
/* Fallback rasterization functions
*/
intel_point_func draw_point;
intel_line_func draw_line;
intel_tri_func draw_tri;
/* Drawing buffer state
*/
intelRegion *drawRegion; /* current drawing buffer */
intelRegion *readRegion; /* current reading buffer */
int drawX; /* origin of drawable in draw buffer */
int drawY;
GLuint numClipRects; /* cliprects for that buffer */
drm_clip_rect_t *pClipRects;
int dirtyAge;
int perf_boxes;
GLuint do_usleeps;
int do_irqs;
GLuint irqsEmitted;
drm_i915_irq_wait_t iw;
GLboolean scissor;
drm_clip_rect_t draw_rect;
drm_clip_rect_t scissor_rect;
drm_context_t hHWContext;
drmLock *driHwLock;
int driFd;
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
intelScreenPrivate *intelScreen;
drmI830Sarea *sarea;
/**
* Configuration cache
*/
driOptionCache optionCache;
/* VBI
*/
GLuint vbl_seq;
GLuint vblank_flags;
int64_t swap_ust;
int64_t swap_missed_ust;
GLuint swap_count;
GLuint swap_missed_count;
GLuint swap_scheduled;
};
#define DEBUG_LOCKING 1
#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)
/* Slightly less broken way of detecting recursive locking in a
* threaded environment. The right way to do this would be to make
* prevLockFile, prevLockLine thread-local.
*
* This technique instead checks to see if the same context is
* requesting the lock twice -- this will not catch application
* breakages where the same context is active in two different threads
* at once, but it will catch driver breakages (recursive locking) in
* threaded apps.
*/
#define DEBUG_CHECK_LOCK() \
do { \
if ( *((volatile int *)intel->driHwLock) == \
(DRM_LOCK_HELD | intel->hHWContext) ) { \
fprintf( stderr, \
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
abort(); \
} \
} while (0)
#else
#define DEBUG_LOCK()
#define DEBUG_RESET()
#define DEBUG_CHECK_LOCK()
#endif
/* Lock the hardware and validate our state.
*/
#define LOCK_HARDWARE( intel ) \
do { \
char __ret=0; \
DEBUG_CHECK_LOCK(); \
assert(!(intel)->locked); \
if ((intel)->swap_scheduled) { \
drmVBlank vbl; \
vbl.request.type = DRM_VBLANK_ABSOLUTE; \
if ((intel)->vblank_flags & \
VBLANK_FLAG_SECONDARY) { \
vbl.request.type |= DRM_VBLANK_SECONDARY; \
} \
vbl.request.sequence = (intel)->vbl_seq; \
drmWaitVBlank((intel)->driFd, &vbl); \
(intel)->swap_scheduled = 0; \
} \
DRM_CAS((intel)->driHwLock, (intel)->hHWContext, \
(DRM_LOCK_HELD|(intel)->hHWContext), __ret); \
if (__ret) \
intelGetLock( (intel), 0 ); \
DEBUG_LOCK(); \
(intel)->locked = 1; \
}while (0)
/* Unlock the hardware using the global current context
*/
#define UNLOCK_HARDWARE(intel) \
do { \
intel->locked = 0; \
if (0) { \
intel->perf_boxes |= intel->sarea->perf_boxes; \
intel->sarea->perf_boxes = 0; \
} \
DRM_UNLOCK((intel)->driFd, (intel)->driHwLock, (intel)->hHWContext); \
DEBUG_RESET(); \
} while (0)
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
(intel)->prim.flush(&(intel)->ctx); \
} while (0)
/* ================================================================
* Color packing:
*/
#define INTEL_PACKCOLOR4444(r,g,b,a) \
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
#define INTEL_PACKCOLOR1555(r,g,b,a) \
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
((a) ? 0x8000 : 0))
#define INTEL_PACKCOLOR565(r,g,b) \
((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#define INTEL_PACKCOLOR8888(r,g,b,a) \
((a<<24) | (r<<16) | (g<<8) | b)
#define INTEL_PACKCOLOR(format, r, g, b, a) \
(format == DV_PF_555 ? INTEL_PACKCOLOR1555(r,g,b,a) : \
(format == DV_PF_565 ? INTEL_PACKCOLOR565(r,g,b) : \
(format == DV_PF_8888 ? INTEL_PACKCOLOR8888(r,g,b,a) : \
0)))
/* ================================================================
* From linux kernel i386 header files, copes with odd sizes better
* than COPY_DWORDS would:
*/
#if defined(i386) || defined(__i386__)
static __inline__ void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
#else
#define __memcpy(a,b,c) memcpy(a,b,c)
#endif
/* ================================================================
* Debugging:
*/
#define DO_DEBUG 1
#if DO_DEBUG
extern int INTEL_DEBUG;
#else
#define INTEL_DEBUG 0
#endif
#define DEBUG_TEXTURE 0x1
#define DEBUG_STATE 0x2
#define DEBUG_IOCTL 0x4
#define DEBUG_PRIMS 0x8
#define DEBUG_VERTS 0x10
#define DEBUG_FALLBACKS 0x20
#define DEBUG_VERBOSE 0x40
#define DEBUG_DRI 0x80
#define DEBUG_DMA 0x100
#define DEBUG_SANITY 0x200
#define DEBUG_SYNC 0x400
#define DEBUG_SLEEP 0x800
#define DEBUG_PIXEL 0x1000
#define PCI_CHIP_845_G 0x2562
#define PCI_CHIP_I830_M 0x3577
#define PCI_CHIP_I855_GM 0x3582
#define PCI_CHIP_I865_G 0x2572
#define PCI_CHIP_I915_G 0x2582
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
#define PCI_CHIP_I945_GME 0x27AE
#define PCI_CHIP_G33_G 0x29C2
#define PCI_CHIP_Q35_G 0x29B2
#define PCI_CHIP_Q33_G 0x29D2
/* ================================================================
* intel_context.c:
*/
extern void intelInitDriverFunctions( struct dd_function_table *functions );
extern GLboolean intelInitContext( intelContextPtr intel,
const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate,
struct dd_function_table *functions );
extern void intelGetLock(intelContextPtr intel, GLuint flags);
extern void intelSetBackClipRects(intelContextPtr intel);
extern void intelSetFrontClipRects(intelContextPtr intel);
extern void intelWindowMoved( intelContextPtr intel );
extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name );
/* ================================================================
* intel_state.c:
*/
extern void intelInitStateFuncs( struct dd_function_table *functions );
#define COMPAREFUNC_ALWAYS 0
#define COMPAREFUNC_NEVER 0x1
#define COMPAREFUNC_LESS 0x2
#define COMPAREFUNC_EQUAL 0x3
#define COMPAREFUNC_LEQUAL 0x4
#define COMPAREFUNC_GREATER 0x5
#define COMPAREFUNC_NOTEQUAL 0x6
#define COMPAREFUNC_GEQUAL 0x7
#define STENCILOP_KEEP 0
#define STENCILOP_ZERO 0x1
#define STENCILOP_REPLACE 0x2
#define STENCILOP_INCRSAT 0x3
#define STENCILOP_DECRSAT 0x4
#define STENCILOP_INCR 0x5
#define STENCILOP_DECR 0x6
#define STENCILOP_INVERT 0x7
#define LOGICOP_CLEAR 0
#define LOGICOP_NOR 0x1
#define LOGICOP_AND_INV 0x2
#define LOGICOP_COPY_INV 0x3
#define LOGICOP_AND_RVRSE 0x4
#define LOGICOP_INV 0x5
#define LOGICOP_XOR 0x6
#define LOGICOP_NAND 0x7
#define LOGICOP_AND 0x8
#define LOGICOP_EQUIV 0x9
#define LOGICOP_NOOP 0xa
#define LOGICOP_OR_INV 0xb
#define LOGICOP_COPY 0xc
#define LOGICOP_OR_RVRSE 0xd
#define LOGICOP_OR 0xe
#define LOGICOP_SET 0xf
#define BLENDFACT_ZERO 0x01
#define BLENDFACT_ONE 0x02
#define BLENDFACT_SRC_COLR 0x03
#define BLENDFACT_INV_SRC_COLR 0x04
#define BLENDFACT_SRC_ALPHA 0x05
#define BLENDFACT_INV_SRC_ALPHA 0x06
#define BLENDFACT_DST_ALPHA 0x07
#define BLENDFACT_INV_DST_ALPHA 0x08
#define BLENDFACT_DST_COLR 0x09
#define BLENDFACT_INV_DST_COLR 0x0a
#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b
#define BLENDFACT_CONST_COLOR 0x0c
#define BLENDFACT_INV_CONST_COLOR 0x0d
#define BLENDFACT_CONST_ALPHA 0x0e
#define BLENDFACT_INV_CONST_ALPHA 0x0f
#define BLENDFACT_MASK 0x0f
extern int intel_translate_compare_func( GLenum func );
extern int intel_translate_stencil_op( GLenum op );
extern int intel_translate_blend_factor( GLenum factor );
extern int intel_translate_logic_op( GLenum opcode );
/* ================================================================
* intel_ioctl.c:
*/
extern void intel_dump_batchbuffer( long offset,
int *ptr,
int count );
/* ================================================================
* intel_pixel.c:
*/
extern void intelInitPixelFuncs( struct dd_function_table *functions );
#endif

View File

@ -1,668 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include "mtypes.h"
#include "context.h"
#include "swrast/swrast.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "drm.h"
u_int32_t intelGetLastFrame (intelContextPtr intel)
{
int ret;
u_int32_t frame;
drm_i915_getparam_t gp;
gp.param = I915_PARAM_LAST_DISPATCH;
gp.value = (int *)&frame;
ret = drmCommandWriteRead( intel->driFd, DRM_I915_GETPARAM,
&gp, sizeof(gp) );
return frame;
}
/**
* Emits a marker in the command stream, numbered from 0x00000001 to
* 0x7fffffff.
*/
int intelEmitIrqLocked( intelContextPtr intel )
{
drmI830IrqEmit ie;
int ret, seq;
assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) ==
(DRM_LOCK_HELD|intel->hHWContext));
/* Valgrind can't tell that the kernel will have copyout()ed onto this
* value, so initialize it now to prevent false positives.
*/
seq = 0;
ie.irq_seq = &seq;
ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT,
&ie, sizeof(ie) );
if ( ret ) {
fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
exit(1);
}
if (0)
fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq );
return seq;
}
/** Blocks on a marker returned by intelEitIrqLocked(). */
void intelWaitIrq( intelContextPtr intel, int seq )
{
int ret;
if (0)
fprintf(stderr, "%s %d\n", __FUNCTION__, seq );
intel->iw.irq_seq = seq;
do {
ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, sizeof(intel->iw) );
} while (ret == -EAGAIN || ret == -EINTR);
if ( ret ) {
fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
if (0)
intel_dump_batchbuffer( intel->alloc.offset,
intel->alloc.ptr,
intel->alloc.size );
exit(1);
}
}
static void age_intel( intelContextPtr intel, int age )
{
GLuint i;
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
if (intel->CurrentTexObj[i])
intel->CurrentTexObj[i]->age = age;
}
void intel_dump_batchbuffer( long offset,
int *ptr,
int count )
{
int i;
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count);
for (i = 0; i < count/4; i += 4)
fprintf(stderr, "\t0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
(unsigned int)offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
fprintf(stderr, "END BATCH\n\n\n");
}
void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock )
{
GLuint last_irq = intel->alloc.irq_emitted;
GLuint half = intel->alloc.size / 2;
GLuint buf = (intel->alloc.active_buf ^= 1);
intel->alloc.irq_emitted = intelEmitIrqLocked( intel );
if (last_irq) {
if (allow_unlock) UNLOCK_HARDWARE( intel );
intelWaitIrq( intel, last_irq );
if (allow_unlock) LOCK_HARDWARE( intel );
}
if (0)
fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf);
intel->batch.start_offset = intel->alloc.offset + buf * half;
intel->batch.ptr = (unsigned char *)intel->alloc.ptr + buf * half;
intel->batch.size = half - 8;
intel->batch.space = half - 8;
assert(intel->batch.space >= 0);
}
#define MI_BATCH_BUFFER_END (0xA<<23)
void intelFlushBatchLocked( intelContextPtr intel,
GLboolean ignore_cliprects,
GLboolean refill,
GLboolean allow_unlock)
{
drmI830BatchBuffer batch;
assert(intel->locked);
if (0)
fprintf(stderr, "%s used %d of %d offset %x..%x refill %d (started in %s)\n",
__FUNCTION__,
(intel->batch.size - intel->batch.space),
intel->batch.size,
intel->batch.start_offset,
intel->batch.start_offset +
(intel->batch.size - intel->batch.space),
refill,
intel->batch.func);
/* Throw away non-effective packets. Won't work once we have
* hardware contexts which would preserve statechanges beyond a
* single buffer.
*/
if (intel->numClipRects == 0 && !ignore_cliprects) {
/* Without this yeild, an application with no cliprects can hog
* the hardware. Without unlocking, the effect is much worse -
* effectively a lock-out of other contexts.
*/
if (allow_unlock) {
UNLOCK_HARDWARE( intel );
sched_yield();
LOCK_HARDWARE( intel );
}
/* Note that any state thought to have been emitted actually
* hasn't:
*/
intel->batch.ptr -= (intel->batch.size - intel->batch.space);
intel->batch.space = intel->batch.size;
intel->vtbl.lost_hardware( intel );
}
if (intel->batch.space != intel->batch.size) {
if (intel->sarea->ctxOwner != intel->hHWContext) {
intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
intel->sarea->ctxOwner = intel->hHWContext;
}
batch.start = intel->batch.start_offset;
batch.used = intel->batch.size - intel->batch.space;
batch.cliprects = intel->pClipRects;
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
batch.DR1 = 0;
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
(((GLuint)intel->drawY) << 16));
if (intel->alloc.offset) {
if ((batch.used & 0x4) == 0) {
((int *)intel->batch.ptr)[0] = 0;
((int *)intel->batch.ptr)[1] = MI_BATCH_BUFFER_END;
batch.used += 0x8;
intel->batch.ptr += 0x8;
}
else {
((int *)intel->batch.ptr)[0] = MI_BATCH_BUFFER_END;
batch.used += 0x4;
intel->batch.ptr += 0x4;
}
}
if (0)
intel_dump_batchbuffer( batch.start,
(int *)(intel->batch.ptr - batch.used),
batch.used );
intel->batch.start_offset += batch.used;
intel->batch.size -= batch.used;
if (intel->batch.size < 8) {
refill = GL_TRUE;
intel->batch.space = intel->batch.size = 0;
}
else {
intel->batch.size -= 8;
intel->batch.space = intel->batch.size;
}
assert(intel->batch.space >= 0);
assert(batch.start >= intel->alloc.offset);
assert(batch.start < intel->alloc.offset + intel->alloc.size);
assert(batch.start + batch.used > intel->alloc.offset);
assert(batch.start + batch.used <=
intel->alloc.offset + intel->alloc.size);
if (intel->alloc.offset) {
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
sizeof(batch))) {
fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
UNLOCK_HARDWARE(intel);
exit(1);
}
} else {
drmI830CmdBuffer cmd;
cmd.buf = (char *)intel->alloc.ptr + batch.start;
cmd.sz = batch.used;
cmd.DR1 = batch.DR1;
cmd.DR4 = batch.DR4;
cmd.num_cliprects = batch.num_cliprects;
cmd.cliprects = batch.cliprects;
if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd,
sizeof(cmd))) {
fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n", -errno);
UNLOCK_HARDWARE(intel);
exit(1);
}
}
age_intel(intel, intel->sarea->last_enqueue);
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
if (intel->batch.contains_geometry)
assert(intel->batch.last_emit_state == intel->batch.counter);
intel->batch.counter++;
intel->batch.contains_geometry = 0;
intel->batch.func = 0;
intel->vtbl.lost_hardware( intel );
}
if (refill)
intelRefillBatchLocked( intel, allow_unlock );
}
void intelFlushBatch( intelContextPtr intel, GLboolean refill )
{
if (intel->locked) {
intelFlushBatchLocked( intel, GL_FALSE, refill, GL_FALSE );
}
else {
LOCK_HARDWARE(intel);
intelFlushBatchLocked( intel, GL_FALSE, refill, GL_TRUE );
UNLOCK_HARDWARE(intel);
}
}
void intelWaitForIdle( intelContextPtr intel )
{
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
intel->vtbl.emit_flush( intel );
intelFlushBatch( intel, GL_TRUE );
/* Use an irq to wait for dma idle -- Need to track lost contexts
* to shortcircuit consecutive calls to this function:
*/
intelWaitIrq( intel, intel->alloc.irq_emitted );
intel->alloc.irq_emitted = 0;
}
/**
* Check if we need to rotate/warp the front color buffer to the
* rotated screen. We generally need to do this when we get a glFlush
* or glFinish after drawing to the front color buffer.
*/
static void
intelCheckFrontRotate(GLcontext *ctx)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
intelScreenPrivate *screen = intel->intelScreen;
if (screen->current_rotation != 0) {
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
}
}
}
/**
* NOT directly called via glFlush.
*/
void intelFlush( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
if (intel->Fallback)
_swrast_flush( ctx );
INTEL_FIREVERTICES( intel );
if (intel->batch.size != intel->batch.space)
intelFlushBatch( intel, GL_FALSE );
}
/**
* Called via glFlush.
*/
void intelglFlush( GLcontext *ctx )
{
intelFlush(ctx);
intelCheckFrontRotate(ctx);
}
void intelFinish( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelFlush( ctx );
intelWaitForIdle( intel );
intelCheckFrontRotate(ctx);
}
void intelClear(GLcontext *ctx, GLbitfield mask)
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Take care of cliprects, which are handled differently for
* clears, etc.
*/
intelFlush( &intel->ctx );
if (mask & BUFFER_BIT_FRONT_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_FRONT_LEFT;
}
else {
tri_mask |= BUFFER_BIT_FRONT_LEFT;
}
}
if (mask & BUFFER_BIT_BACK_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_BACK_LEFT;
}
else {
tri_mask |= BUFFER_BIT_BACK_LEFT;
}
}
if (mask & BUFFER_BIT_DEPTH) {
blit_mask |= BUFFER_BIT_DEPTH;
}
if (mask & BUFFER_BIT_STENCIL) {
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
blit_mask |= BUFFER_BIT_STENCIL;
}
}
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
if (blit_mask)
intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0);
if (tri_mask)
intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0);
if (swrast_mask)
_swrast_Clear( ctx, swrast_mask );
}
void
intelRotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuffer)
{
if (intel->vtbl.rotate_window) {
intel->vtbl.rotate_window(intel, dPriv, srcBuffer);
}
}
void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
{
int region_offset;
drmI830MemAlloc alloc;
int ret;
if (0)
fprintf(stderr, "%s: %d bytes\n", __FUNCTION__, size);
alloc.region = I830_MEM_REGION_AGP;
alloc.alignment = 0;
alloc.size = size;
alloc.region_offset = &region_offset;
LOCK_HARDWARE(intel);
/* Make sure the global heap is initialized
*/
if (intel->texture_heaps[0])
driAgeTextures( intel->texture_heaps[0] );
ret = drmCommandWriteRead( intel->driFd,
DRM_I830_ALLOC,
&alloc, sizeof(alloc));
if (ret) {
fprintf(stderr, "%s: DRM_I830_ALLOC ret %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE(intel);
return NULL;
}
if (0)
fprintf(stderr, "%s: allocated %d bytes\n", __FUNCTION__, size);
/* Need to propogate this information (agp memory in use) to our
* local texture lru. The kernel has already updated the global
* lru. An alternative would have been to allocate memory the
* usual way and then notify the kernel to pin the allocation.
*/
if (intel->texture_heaps[0])
driAgeTextures( intel->texture_heaps[0] );
UNLOCK_HARDWARE(intel);
return (void *)((char *)intel->intelScreen->tex.map + region_offset);
}
void intelFreeAGP( intelContextPtr intel, void *pointer )
{
int region_offset;
drmI830MemFree memfree;
int ret;
region_offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
if (region_offset < 0 ||
region_offset > intel->intelScreen->tex.size) {
fprintf(stderr, "offset %d outside range 0..%d\n", region_offset,
intel->intelScreen->tex.size);
return;
}
memfree.region = I830_MEM_REGION_AGP;
memfree.region_offset = region_offset;
ret = drmCommandWrite( intel->driFd,
DRM_I830_FREE,
&memfree, sizeof(memfree));
if (ret)
fprintf(stderr, "%s: DRM_I830_FREE ret %d\n", __FUNCTION__, ret);
}
/* This version of AllocateMemoryMESA allocates only agp memory, and
* only does so after the point at which the driver has been
* initialized.
*
* Theoretically a valid context isn't required. However, in this
* implementation, it is, as I'm using the hardware lock to protect
* the kernel data structures, and the current context to get the
* device fd.
*/
void *intelAllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn,
GLsizei size, GLfloat readfreq,
GLfloat writefreq, GLfloat priority)
{
GET_CURRENT_CONTEXT(ctx);
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,
writefreq, priority);
if (getenv("INTEL_NO_ALLOC"))
return NULL;
if (!ctx || INTEL_CONTEXT(ctx) == 0)
return NULL;
return intelAllocateAGP( INTEL_CONTEXT(ctx), size );
}
/* Called via glXFreeMemoryMESA() */
void intelFreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
{
GET_CURRENT_CONTEXT(ctx);
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);
if (!ctx || INTEL_CONTEXT(ctx) == 0) {
fprintf(stderr, "%s: no context\n", __FUNCTION__);
return;
}
intelFreeAGP( INTEL_CONTEXT(ctx), pointer );
}
/* Called via glXGetMemoryOffsetMESA()
*
* Returns offset of pointer from the start of agp aperture.
*/
GLuint intelGetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn,
const GLvoid *pointer)
{
GET_CURRENT_CONTEXT(ctx);
intelContextPtr intel;
if (!ctx || !(intel = INTEL_CONTEXT(ctx)) ) {
fprintf(stderr, "%s: no context\n", __FUNCTION__);
return ~0;
}
if (!intelIsAgpMemory( intel, pointer, 0 ))
return ~0;
return intelAgpOffsetFromVirtual( intel, pointer );
}
GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer,
GLint size )
{
int offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
int valid = (size >= 0 &&
offset >= 0 &&
offset + size < intel->intelScreen->tex.size);
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "intelIsAgpMemory( %p ) : %d\n", pointer, valid );
return valid;
}
GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *pointer )
{
int offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
if (offset < 0 || offset > intel->intelScreen->tex.size)
return ~0;
else
return intel->intelScreen->tex.offset + offset;
}
/* Flip the front & back buffes
*/
void intelPageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
intelContextPtr intel;
int tmp, ret;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (dPriv->pClipRects) {
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
intel->sarea->nbox = 1;
}
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
if (ret) {
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE( intel );
exit(1);
}
tmp = intel->sarea->last_enqueue;
intelRefillBatchLocked( intel );
UNLOCK_HARDWARE( intel );
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
#endif
}

View File

@ -1,72 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_IOCTL_H
#define INTEL_IOCTL_H
#include "intel_context.h"
extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock );
extern void intelClear(GLcontext *ctx, GLbitfield mask);
extern void intelPageFlip( const __DRIdrawablePrivate *dpriv );
extern void intelRotateWindow(intelContextPtr intel,
__DRIdrawablePrivate *dPriv, GLuint srcBuffer);
extern void intelWaitForIdle( intelContextPtr intel );
extern void intelFlushBatch( intelContextPtr intel, GLboolean refill );
extern void intelFlushBatchLocked( intelContextPtr intel,
GLboolean ignore_cliprects,
GLboolean refill,
GLboolean allow_unlock);
extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock );
extern void intelFinish( GLcontext *ctx );
extern void intelFlush( GLcontext *ctx );
extern void intelglFlush( GLcontext *ctx );
extern void *intelAllocateAGP( intelContextPtr intel, GLsizei size );
extern void intelFreeAGP( intelContextPtr intel, void *pointer );
extern void *intelAllocateMemoryMESA( __DRInativeDisplay *dpy, int scrn,
GLsizei size, GLfloat readfreq,
GLfloat writefreq, GLfloat priority );
extern void intelFreeMemoryMESA( __DRInativeDisplay *dpy, int scrn,
GLvoid *pointer );
extern GLuint intelGetMemoryOffsetMESA( __DRInativeDisplay *dpy, int scrn, const GLvoid *pointer );
extern GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer,
GLint size );
extern GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *p );
extern void intelWaitIrq( intelContextPtr intel, int seq );
extern u_int32_t intelGetLastFrame (intelContextPtr intel);
extern int intelEmitIrqLocked( intelContextPtr intel );
#endif

View File

@ -1,524 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "enums.h"
#include "mtypes.h"
#include "macros.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
static GLboolean
check_color( const GLcontext *ctx, GLenum type, GLenum format,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz, GLint pitch )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLuint cpp = intel->intelScreen->cpp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( (pitch & 63) ||
ctx->_ImageTransferState ||
packing->SwapBytes ||
packing->LsbFirst) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
return GL_FALSE;
}
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&
cpp == 4 &&
format == GL_BGRA ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
return GL_TRUE;
}
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: failed\n", __FUNCTION__);
return GL_FALSE;
}
static GLboolean
check_color_per_fragment_ops( const GLcontext *ctx )
{
int result;
result = (!( ctx->Color.AlphaEnabled ||
ctx->Depth.Test ||
ctx->Fog.Enabled ||
ctx->Scissor.Enabled ||
ctx->Stencil.Enabled ||
!ctx->Color.ColorMask[0] ||
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
ctx->Color.ColorLogicOpEnabled ||
ctx->Texture._EnabledUnits
) &&
ctx->Current.RasterPosValid);
return result;
}
/**
* Clip the given rectangle against the buffer's bounds (including scissor).
* \param size returns the
* \return GL_TRUE if any pixels remain, GL_FALSE if totally clipped.
*
* XXX Replace this with _mesa_clip_drawpixels() and _mesa_clip_readpixels()
* from Mesa 6.4. We shouldn't apply scissor for ReadPixels.
*/
static GLboolean
clip_pixelrect( const GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height)
{
/* left clipping */
if (*x < buffer->_Xmin) {
*width -= (buffer->_Xmin - *x);
*x = buffer->_Xmin;
}
/* right clipping */
if (*x + *width > buffer->_Xmax)
*width -= (*x + *width - buffer->_Xmax - 1);
if (*width <= 0)
return GL_FALSE;
/* bottom clipping */
if (*y < buffer->_Ymin) {
*height -= (buffer->_Ymin - *y);
*y = buffer->_Ymin;
}
/* top clipping */
if (*y + *height > buffer->_Ymax)
*height -= (*y + *height - buffer->_Ymax - 1);
if (*height <= 0)
return GL_FALSE;
return GL_TRUE;
}
/**
* Compute intersection of a clipping rectangle and pixel rectangle,
* returning results in x/y/w/hOut vars.
* \return GL_TRUE if there's intersection, GL_FALSE if disjoint.
*/
static INLINE GLboolean
intersect_region(const drm_clip_rect_t *box,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint *xOut, GLint *yOut, GLint *wOut, GLint *hOut)
{
GLint bx = box->x1;
GLint by = box->y1;
GLint bw = box->x2 - bx;
GLint bh = box->y2 - by;
if (bx < x) bw -= x - bx, bx = x;
if (by < y) bh -= y - by, by = y;
if (bx + bw > x + width) bw = x + width - bx;
if (by + bh > y + height) bh = y + height - by;
*xOut = bx;
*yOut = by;
*wOut = bw;
*hOut = bh;
if (bw <= 0) return GL_FALSE;
if (bh <= 0) return GL_FALSE;
return GL_TRUE;
}
static GLboolean
intelTryReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLint size = 0; /* not really used */
GLint pitch = pack->RowLength ? pack->RowLength : width;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Only accelerate reading to agp buffers.
*/
if ( !intelIsAgpMemory(intel, pixels,
pitch * height * intel->intelScreen->cpp ) ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
return GL_FALSE;
}
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
* blitter:
*/
if (!pack->Invert) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
return GL_FALSE;
}
if (!check_color(ctx, type, format, pack, pixels, size, pitch))
return GL_FALSE;
switch ( intel->intelScreen->cpp ) {
case 4:
break;
default:
return GL_FALSE;
}
/* Although the blits go on the command buffer, need to do this and
* fire with lock held to guarentee cliprects and drawing offset are
* correct.
*
* This is an unusual situation however, as the code which flushes
* a full command buffer expects to be called unlocked. As a
* workaround, immediately flush the buffer on aquiring the lock.
*/
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
int src_offset = intel->readRegion->offset;
int src_pitch = intel->intelScreen->front.pitch;
int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
assert(dst_offset != ~0); /* should have been caught above */
if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s totally clipped -- nothing to do\n",
__FUNCTION__);
return GL_TRUE;
}
/* convert to screen coords (y=0=top) */
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
src_pitch, pitch);
/* We don't really have to do window clipping for readpixels.
* The OpenGL spec says that pixels read from outside the
* visible window region (pixel ownership) have undefined value.
*/
for (i = 0 ; i < nbox ; i++)
{
GLint bx, by, bw, bh;
if (intersect_region(box+i, x, y, width, height,
&bx, &by, &bw, &bh)) {
intelEmitCopyBlitLocked( intel,
intel->intelScreen->cpp,
src_pitch, src_offset,
pitch, dst_offset,
bx, by,
bx - x, by - y,
bw, bh );
}
}
}
UNLOCK_HARDWARE( intel );
intelFinish( &intel->ctx );
return GL_TRUE;
}
static void
intelReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack,
pixels))
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
pixels);
}
static void do_draw_pix( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint pitch,
const void *pixels,
GLuint dest )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t *box = dPriv->pClipRects;
int nbox = dPriv->numClipRects;
int i;
int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
int src_pitch = pitch;
assert(src_offset != ~0); /* should be caught earlier */
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (ctx->DrawBuffer)
{
y -= height; /* cope with pixel zoom */
if (!clip_pixelrect(ctx, ctx->DrawBuffer,
&x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
return;
}
y = dPriv->h - y - height; /* convert from gl to hardware coords */
x += dPriv->x;
y += dPriv->y;
for (i = 0 ; i < nbox ; i++ )
{
GLint bx, by, bw, bh;
if (intersect_region(box + i, x, y, width, height,
&bx, &by, &bw, &bh)) {
intelEmitCopyBlitLocked( intel,
intel->intelScreen->cpp,
src_pitch, src_offset,
intel->intelScreen->front.pitch,
intel->drawRegion->offset,
bx - x, by - y,
bx, by,
bw, bh );
}
}
}
UNLOCK_HARDWARE( intel );
intelFinish( &intel->ctx );
}
static GLboolean
intelTryDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
GLuint dest;
GLuint cpp = intel->intelScreen->cpp;
GLint size = width * pitch * cpp;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
switch (format) {
case GL_RGB:
case GL_RGBA:
case GL_BGRA:
dest = intel->drawRegion->offset;
/* Planemask doesn't have full support in blits.
*/
if (!ctx->Color.ColorMask[RCOMP] ||
!ctx->Color.ColorMask[GCOMP] ||
!ctx->Color.ColorMask[BCOMP] ||
!ctx->Color.ColorMask[ACOMP]) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: planemask\n", __FUNCTION__);
return GL_FALSE;
}
/* Can't do conversions on agp reads/draws.
*/
if ( !intelIsAgpMemory( intel, pixels, size ) ) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
return GL_FALSE;
}
if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
return GL_FALSE;
}
if (!check_color_per_fragment_ops(ctx)) {
return GL_FALSE;
}
if (ctx->Pixel.ZoomX != 1.0F ||
ctx->Pixel.ZoomY != -1.0F)
return GL_FALSE;
break;
default:
return GL_FALSE;
}
if ( intelIsAgpMemory(intel, pixels, size) )
{
do_draw_pix( ctx, x, y, width, height, pitch, pixels, dest );
return GL_TRUE;
}
else if (0)
{
/* Pixels is in regular memory -- get dma buffers and perform
* upload through them. No point doing this for regular uploads
* but once we remove some of the restrictions above (colormask,
* pixelformat conversion, zoom?, etc), this could be a win.
*/
}
else
return GL_FALSE;
return GL_FALSE;
}
static void
intelDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (intelTryDrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels ))
return;
if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
/*
* We don't want the i915 texenv program to be applied to DrawPixels.
* This is really just a performance optimization (mesa will other-
* wise happily run the fragment program on each pixel in the image).
*/
struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
/* can't just set current frag prog to 0 here as on buffer resize
we'll get new state checks which will segfault. Remains a hack. */
ctx->FragmentProgram._Current = NULL;
ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE;
ctx->FragmentProgram._Active = GL_FALSE;
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
ctx->FragmentProgram._Current = fpSave;
ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
ctx->FragmentProgram._Active = GL_TRUE;
}
else {
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
}
}
/**
* Implement glCopyPixels for the front color buffer (or back buffer Pixmap)
* for the color buffer. Don't support zooming, pixel transfer, etc.
* We do support copying from one window to another, ala glXMakeCurrentRead.
*/
static void
intelCopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GLint destx, GLint desty, GLenum type )
{
#if 0
const XMesaContext xmesa = XMESA_CONTEXT(ctx);
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
XMesaDisplay *dpy = xmesa->xm_visual->display;
const XMesaDrawable drawBuffer = xmesa->xm_draw_buffer->buffer;
const XMesaDrawable readBuffer = xmesa->xm_read_buffer->buffer;
const XMesaGC gc = xmesa->xm_draw_buffer->gc;
ASSERT(dpy);
ASSERT(gc);
if (drawBuffer && /* buffer != 0 means it's a Window or Pixmap */
readBuffer &&
type == GL_COLOR &&
(swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */
ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */
ctx->Pixel.ZoomX == 1.0 && /* no zooming */
ctx->Pixel.ZoomY == 1.0) {
/* Note: we don't do any special clipping work here. We could,
* but X will do it for us.
*/
srcy = FLIP(xmesa->xm_read_buffer, srcy) - height + 1;
desty = FLIP(xmesa->xm_draw_buffer, desty) - height + 1;
XCopyArea(dpy, readBuffer, drawBuffer, gc,
srcx, srcy, width, height, destx, desty);
}
#else
_swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type );
#endif
}
void intelInitPixelFuncs( struct dd_function_table *functions )
{
functions->CopyPixels = intelCopyPixels;
if (!getenv("INTEL_NO_BLITS")) {
functions->ReadPixels = intelReadPixels;
functions->DrawPixels = intelDrawPixels;
}
}

View File

@ -1,84 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_REG_H_
#define _INTEL_REG_H_
#define CMD_3D (0x3<<29)
#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24))
#define PRIM_INDIRECT (1<<23)
#define PRIM_INLINE (0<<23)
#define PRIM_INDIRECT_SEQUENTIAL (0<<17)
#define PRIM_INDIRECT_ELTS (1<<17)
#define PRIM3D_TRILIST (0x0<<18)
#define PRIM3D_TRISTRIP (0x1<<18)
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
#define PRIM3D_TRIFAN (0x3<<18)
#define PRIM3D_POLY (0x4<<18)
#define PRIM3D_LINELIST (0x5<<18)
#define PRIM3D_LINESTRIP (0x6<<18)
#define PRIM3D_RECTLIST (0x7<<18)
#define PRIM3D_POINTLIST (0x8<<18)
#define PRIM3D_DIB (0x9<<18)
#define PRIM3D_MASK (0x1f<<18)
#define I915PACKCOLOR4444(r,g,b,a) \
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
#define I915PACKCOLOR1555(r,g,b,a) \
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
((a) ? 0x8000 : 0))
#define I915PACKCOLOR565(r,g,b) \
((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#define I915PACKCOLOR8888(r,g,b,a) \
((a<<24) | (r<<16) | (g<<8) | b)
#define BR00_BITBLT_CLIENT 0x40000000
#define BR00_OP_COLOR_BLT 0x10000000
#define BR00_OP_SRC_COPY_BLT 0x10C00000
#define BR13_SOLID_PATTERN 0x80000000
#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
#define XY_COLOR_BLT_WRITE_RGB (1<<20)
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
#endif

View File

@ -1,242 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Render unclipped vertex buffers by emitting vertices directly to
* dma buffers. Use strip/fan hardware acceleration where possible.
*
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
#include "mtypes.h"
#include "enums.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_tris.h"
#include "intel_batchbuffer.h"
#include "intel_reg.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 0 /* Has it, but can't use because subpixel has to
* be adjusted for points on the INTEL/I845G
*/
#define HAVE_LINES 1
#define HAVE_LINE_STRIPS 1
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */
#define HAVE_TRI_FANS 1
#define HAVE_POLYGONS 1
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
#define HAVE_ELTS 0
static GLuint hw_prim[GL_POLYGON+1] = {
0,
PRIM3D_LINELIST,
PRIM3D_LINESTRIP,
PRIM3D_LINESTRIP,
PRIM3D_TRILIST,
PRIM3D_TRISTRIP,
PRIM3D_TRIFAN,
0,
0,
PRIM3D_POLY
};
static const GLenum reduced_prim[GL_POLYGON+1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
static const int scale_prim[GL_POLYGON+1] = {
0, /* fallback case */
1,
2,
2,
1,
3,
3,
0, /* fallback case */
0, /* fallback case */
3
};
static void intelDmaPrimitive( intelContextPtr intel, GLenum prim )
{
if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
INTEL_FIREVERTICES(intel);
intel->vtbl.reduced_primitive_state( intel, reduced_prim[prim] );
intelStartInlinePrimitive( intel, hw_prim[prim] );
}
#define LOCAL_VARS intelContextPtr intel = INTEL_CONTEXT(ctx)
#define INIT( prim ) \
do { \
intelDmaPrimitive( intel, prim ); \
} while (0)
#define FLUSH() INTEL_FIREVERTICES( intel )
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
(((intel->alloc.size / 2) - 1500) / (intel->vertex_size*4))
#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS()
#define ALLOC_VERTS( nr ) \
intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size )
#define EMIT_VERTS( ctx, j, nr, buf ) \
_tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
#define TAG(x) intel_##x
#include "tnl_dd/t_dd_dmatmp.h"
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
/* Heuristic to choose between the two render paths:
*/
static GLboolean choose_render( intelContextPtr intel,
struct vertex_buffer *VB )
{
int vertsz = intel->vertex_size;
int cost_render = 0;
int cost_fallback = 0;
int nr_prims = 0;
int nr_rprims = 0;
int nr_rverts = 0;
int rprim = intel->reduced_primitive;
int i = 0;
for (i = 0 ; i < VB->PrimitiveCount ; i++) {
GLuint prim = VB->Primitive[i].mode;
GLuint length = VB->Primitive[i].count;
if (!length)
continue;
nr_prims++;
nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK];
if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) {
nr_rprims++;
rprim = reduced_prim[prim & PRIM_MODE_MASK];
}
}
/* One point for each generated primitive:
*/
cost_render = nr_prims;
cost_fallback = nr_rprims;
/* One point for every 1024 dwords (4k) of dma:
*/
cost_render += (vertsz * i) / 1024;
cost_fallback += (vertsz * nr_rverts) / 1024;
if (0)
fprintf(stderr, "cost render: %d fallback: %d\n",
cost_render, cost_fallback);
if (cost_render > cost_fallback)
return GL_FALSE;
return GL_TRUE;
}
static GLboolean intel_run_render( GLcontext *ctx,
struct tnl_pipeline_stage *stage )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
intel->vtbl.render_prevalidate( intel );
/* Don't handle clipping or indexed vertices.
*/
if (intel->RenderIndex != 0 ||
!intel_validate_render( ctx, VB ) ||
!choose_render( intel, VB )) {
return GL_TRUE;
}
tnl->clipspace.new_inputs |= VERT_BIT_POS;
tnl->Driver.Render.Start( ctx );
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
GLuint prim = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
if (!length)
continue;
intel_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length,
prim );
}
tnl->Driver.Render.Finish( ctx );
return GL_FALSE; /* finished the pipe */
}
const struct tnl_pipeline_stage _intel_render_stage =
{
"intel render",
NULL,
NULL,
NULL,
NULL,
intel_run_render /* run */
};

View File

@ -1,221 +0,0 @@
/**
* Routines for simple 2D->2D transformations for rotated, flipped screens.
*
* XXX This code is not intel-specific. Move it into a common/utility
* someday.
*/
#include "intel_rotate.h"
#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) )
#define ABS(A) ( ((A) < 0) ? -(A) : (A) )
void
matrix23Set(struct matrix23 *m,
int m00, int m01, int m02,
int m10, int m11, int m12)
{
m->m00 = m00; m->m01 = m01; m->m02 = m02;
m->m10 = m10; m->m11 = m11; m->m12 = m12;
}
/*
* Transform (x,y) coordinate by the given matrix.
*/
void
matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y)
{
const float x0 = *x;
const float y0 = *y;
*x = m->m00 * x0 + m->m01 * y0 + m->m02;
*y = m->m10 * x0 + m->m11 * y0 + m->m12;
}
void
matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y)
{
const int x0 = *x;
const int y0 = *y;
*x = m->m00 * x0 + m->m01 * y0 + m->m02;
*y = m->m10 * x0 + m->m11 * y0 + m->m12;
}
/*
* Transform a width and height by the given matrix.
* XXX this could be optimized quite a bit.
*/
void
matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist)
{
int x0 = 0, y0 = 0;
int x1 = *xDist, y1 = 0;
int x2 = 0, y2 = *yDist;
matrix23TransformCoordi(m, &x0, &y0);
matrix23TransformCoordi(m, &x1, &y1);
matrix23TransformCoordi(m, &x2, &y2);
*xDist = (x1 - x0) + (x2 - x0);
*yDist = (y1 - y0) + (y2 - y0);
if (*xDist < 0)
*xDist = -*xDist;
if (*yDist < 0)
*yDist = -*yDist;
}
/**
* Transform the rect defined by (x, y, w, h) by m.
*/
void
matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, int *h)
{
int x0 = *x, y0 = *y;
int x1 = *x + *w, y1 = *y;
int x2 = *x + *w, y2 = *y + *h;
int x3 = *x, y3 = *y + *h;
matrix23TransformCoordi(m, &x0, &y0);
matrix23TransformCoordi(m, &x1, &y1);
matrix23TransformCoordi(m, &x2, &y2);
matrix23TransformCoordi(m, &x3, &y3);
*w = ABS(x1 - x0) + ABS(x2 - x1);
/**w = ABS(*w);*/
*h = ABS(y1 - y0) + ABS(y2 - y1);
/**h = ABS(*h);*/
*x = MIN2(x0, x1);
*x = MIN2(*x, x2);
*y = MIN2(y0, y1);
*y = MIN2(*y, y2);
}
/*
* Make rotation matrix for width X height screen.
*/
void
matrix23Rotate(struct matrix23 *m, int width, int height, int angle)
{
switch (angle) {
case 0:
matrix23Set(m, 1, 0, 0, 0, 1, 0);
break;
case 90:
matrix23Set(m, 0, 1, 0, -1, 0, width);
break;
case 180:
matrix23Set(m, -1, 0, width, 0, -1, height);
break;
case 270:
matrix23Set(m, 0, -1, height, 1, 0, 0);
break;
default:
/*abort()*/;
}
}
/*
* Make flip/reflection matrix for width X height screen.
*/
void
matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip)
{
if (xflip) {
m->m00 = -1; m->m01 = 0; m->m02 = width - 1;
}
else {
m->m00 = 1; m->m01 = 0; m->m02 = 0;
}
if (yflip) {
m->m10 = 0; m->m11 = -1; m->m12 = height - 1;
}
else {
m->m10 = 0; m->m11 = 1; m->m12 = 0;
}
}
/*
* result = a * b
*/
void
matrix23Multiply(struct matrix23 *result,
const struct matrix23 *a, const struct matrix23 *b)
{
result->m00 = a->m00 * b->m00 + a->m01 * b->m10;
result->m01 = a->m00 * b->m01 + a->m01 * b->m11;
result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02;
result->m10 = a->m10 * b->m00 + a->m11 * b->m10;
result->m11 = a->m10 * b->m01 + a->m11 * b->m11;
result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12;
}
#if 000
#include <stdio.h>
int
main(int argc, char *argv[])
{
int width = 500, height = 400;
int rot;
int fx = 0, fy = 0; /* flip x and/or y ? */
int coords[4][2];
/* four corner coords to test with */
coords[0][0] = 0; coords[0][1] = 0;
coords[1][0] = width-1; coords[1][1] = 0;
coords[2][0] = width-1; coords[2][1] = height-1;
coords[3][0] = 0; coords[3][1] = height-1;
for (rot = 0; rot < 360; rot += 90) {
struct matrix23 rotate, flip, m;
int i;
printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy);
/* make transformation matrix 'm' */
matrix23Rotate(&rotate, width, height, rot);
matrix23Flip(&flip, width, height, fx, fy);
matrix23Multiply(&m, &rotate, &flip);
/* xform four coords */
for (i = 0; i < 4; i++) {
int x = coords[i][0];
int y = coords[i][1];
matrix23TransformCoordi(&m, &x, &y);
printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y);
}
/* xform width, height */
{
int x = width;
int y = height;
matrix23TransformDistance(&m, &x, &y);
printf(" %d x %d -> %d x %d\n", width, height, x, y);
}
/* xform rect */
{
int x = 50, y = 10, w = 200, h = 100;
matrix23TransformRect(&m, &x, &y, &w, &h);
printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100,
x, y, w, h);
}
}
return 0;
}
#endif

View File

@ -1,41 +0,0 @@
#ifndef INTEL_ROTATE_H
#define INTEL_ROTATE_H 1
struct matrix23
{
int m00, m01, m02;
int m10, m11, m12;
};
extern void
matrix23Set(struct matrix23 *m,
int m00, int m01, int m02,
int m10, int m11, int m12);
extern void
matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y);
extern void
matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y);
extern void
matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist);
extern void
matrix23TransformRect(const struct matrix23 *m,
int *x, int *y, int *w, int *h);
extern void
matrix23Rotate(struct matrix23 *m, int width, int height, int angle);
extern void
matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip);
extern void
matrix23Multiply(struct matrix23 *result,
const struct matrix23 *a, const struct matrix23 *b);
#endif /* INTEL_ROTATE_H */

View File

@ -1,690 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "framebuffer.h"
#include "matrix.h"
#include "renderbuffer.h"
#include "simple_list.h"
#include "utils.h"
#include "vblank.h"
#include "xmlpool.h"
#include "intel_screen.h"
#include "intel_tex.h"
#include "intel_span.h"
#include "intel_tris.h"
#include "intel_ioctl.h"
#include "i830_dri.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END
DRI_CONF_END;
const GLuint __driNConfigOptions = 4;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /*USE_NEW_INTERFACE*/
extern const struct dri_extension card_extensions[];
/**
* Map all the memory regions described by the screen.
* \return GL_TRUE if success, GL_FALSE if error.
*/
GLboolean
intelMapScreenRegions(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
if (intelScreen->front.handle) {
if (drmMap(sPriv->fd,
intelScreen->front.handle,
intelScreen->front.size,
(drmAddress *)&intelScreen->front.map) != 0) {
_mesa_problem(NULL, "drmMap(frontbuffer) failed!");
return GL_FALSE;
}
}
else {
_mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!");
}
if (drmMap(sPriv->fd,
intelScreen->back.handle,
intelScreen->back.size,
(drmAddress *)&intelScreen->back.map) != 0) {
intelUnmapScreenRegions(intelScreen);
return GL_FALSE;
}
if (drmMap(sPriv->fd,
intelScreen->depth.handle,
intelScreen->depth.size,
(drmAddress *)&intelScreen->depth.map) != 0) {
intelUnmapScreenRegions(intelScreen);
return GL_FALSE;
}
if (drmMap(sPriv->fd,
intelScreen->tex.handle,
intelScreen->tex.size,
(drmAddress *)&intelScreen->tex.map) != 0) {
intelUnmapScreenRegions(intelScreen);
return GL_FALSE;
}
if (0)
printf("Mappings: front: %p back: %p depth: %p tex: %p\n",
intelScreen->front.map,
intelScreen->back.map,
intelScreen->depth.map,
intelScreen->tex.map);
return GL_TRUE;
}
void
intelUnmapScreenRegions(intelScreenPrivate *intelScreen)
{
#define REALLY_UNMAP 1
if (intelScreen->front.map) {
#if REALLY_UNMAP
if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0)
printf("drmUnmap front failed!\n");
#endif
intelScreen->front.map = NULL;
}
if (intelScreen->back.map) {
#if REALLY_UNMAP
if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0)
printf("drmUnmap back failed!\n");
#endif
intelScreen->back.map = NULL;
}
if (intelScreen->depth.map) {
#if REALLY_UNMAP
drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
intelScreen->depth.map = NULL;
#endif
}
if (intelScreen->tex.map) {
#if REALLY_UNMAP
drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
intelScreen->tex.map = NULL;
#endif
}
}
static void
intelPrintDRIInfo(intelScreenPrivate *intelScreen,
__DRIscreenPrivate *sPriv,
I830DRIPtr gDRIPriv)
{
fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
intelScreen->front.size, intelScreen->front.offset,
intelScreen->front.pitch);
fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n",
intelScreen->back.size, intelScreen->back.offset,
intelScreen->back.pitch);
fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n",
intelScreen->depth.size, intelScreen->depth.offset,
intelScreen->depth.pitch);
fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n",
intelScreen->rotated.size, intelScreen->rotated.offset,
intelScreen->rotated.pitch);
fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n",
intelScreen->tex.size, intelScreen->tex.offset);
fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
}
static void
intelPrintSAREA(const drmI830Sarea *sarea)
{
fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, sarea->height);
fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
fprintf(stderr,
"SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
sarea->front_offset, sarea->front_size,
(unsigned) sarea->front_handle);
fprintf(stderr,
"SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
sarea->back_offset, sarea->back_size,
(unsigned) sarea->back_handle);
fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
sarea->depth_offset, sarea->depth_size,
(unsigned) sarea->depth_handle);
fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
sarea->tex_offset, sarea->tex_size,
(unsigned) sarea->tex_handle);
fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation);
fprintf(stderr,
"SAREA: rotated offset: 0x%08x size: 0x%x\n",
sarea->rotated_offset, sarea->rotated_size);
fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch);
}
/**
* A number of the screen parameters are obtained/computed from
* information in the SAREA. This function updates those parameters.
*/
void
intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
drmI830Sarea *sarea)
{
intelScreen->width = sarea->width;
intelScreen->height = sarea->height;
intelScreen->front.offset = sarea->front_offset;
intelScreen->front.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->front.handle = sarea->front_handle;
intelScreen->front.size = sarea->front_size;
intelScreen->back.offset = sarea->back_offset;
intelScreen->back.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->back.handle = sarea->back_handle;
intelScreen->back.size = sarea->back_size;
intelScreen->depth.offset = sarea->depth_offset;
intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->depth.handle = sarea->depth_handle;
intelScreen->depth.size = sarea->depth_size;
intelScreen->tex.offset = sarea->tex_offset;
intelScreen->logTextureGranularity = sarea->log_tex_granularity;
intelScreen->tex.handle = sarea->tex_handle;
intelScreen->tex.size = sarea->tex_size;
intelScreen->rotated.offset = sarea->rotated_offset;
intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp;
intelScreen->rotated.size = sarea->rotated_size;
intelScreen->current_rotation = sarea->rotation;
matrix23Rotate(&intelScreen->rotMatrix,
sarea->width, sarea->height, sarea->rotation);
intelScreen->rotatedWidth = sarea->virtualX;
intelScreen->rotatedHeight = sarea->virtualY;
if (0)
intelPrintSAREA(sarea);
}
static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen;
I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv;
drmI830Sarea *sarea;
PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
(PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
void * const psc = sPriv->psc->screenConfigs;
if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
fprintf(stderr,"\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
return GL_FALSE;
}
/* Allocate the private area */
intelScreen = (intelScreenPrivate *)CALLOC(sizeof(intelScreenPrivate));
if (!intelScreen) {
fprintf(stderr,"\nERROR! Allocating private area failed\n");
return GL_FALSE;
}
/* parse information in __driConfigOptions */
driParseOptionInfo (&intelScreen->optionCache,
__driConfigOptions, __driNConfigOptions);
intelScreen->driScrnPriv = sPriv;
sPriv->private = (void *)intelScreen;
intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
sarea = (drmI830Sarea *)
(((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
intelScreen->deviceID = gDRIPriv->deviceID;
intelScreen->mem = gDRIPriv->mem;
intelScreen->cpp = gDRIPriv->cpp;
switch (gDRIPriv->bitsPerPixel) {
case 15: intelScreen->fbFormat = DV_PF_555; break;
case 16: intelScreen->fbFormat = DV_PF_565; break;
case 32: intelScreen->fbFormat = DV_PF_8888; break;
}
intelUpdateScreenFromSAREA(intelScreen, sarea);
if (0)
intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
if (!intelMapScreenRegions(sPriv)) {
fprintf(stderr,"\nERROR! mapping regions\n");
_mesa_free(intelScreen);
sPriv->private = NULL;
return GL_FALSE;
}
intelScreen->drmMinor = sPriv->drmMinor;
/* Determine if IRQs are active? */
{
int ret;
drmI830GetParam gp;
gp.param = I830_PARAM_IRQ_ACTIVE;
gp.value = &intelScreen->irq_active;
ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmI830GetParam: %d\n", ret);
return GL_FALSE;
}
}
/* Determine if batchbuffers are allowed */
{
int ret;
drmI830GetParam gp;
gp.param = I830_PARAM_ALLOW_BATCHBUFFER;
gp.value = &intelScreen->allow_batchbuffer;
ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret);
return GL_FALSE;
}
}
if (glx_enable_extension != NULL) {
(*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
(*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
(*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
(*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
(*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
(*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
(*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
}
sPriv->psc->allocateMemory = (void *) intelAllocateMemoryMESA;
sPriv->psc->freeMemory = (void *) intelFreeMemoryMESA;
sPriv->psc->memoryOffset = (void *) intelGetMemoryOffsetMESA;
return GL_TRUE;
}
static void intelDestroyScreen(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
intelUnmapScreenRegions(intelScreen);
driDestroyOptionInfo (&intelScreen->optionCache);
FREE(intelScreen);
sPriv->private = NULL;
}
static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private;
if (isPixmap) {
return GL_FALSE; /* not implemented */
} else {
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24);
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
{
driRenderbuffer *frontRb
= driNewRenderbuffer(GL_RGBA,
screen->front.map,
screen->cpp,
screen->front.offset, screen->front.pitch,
driDrawPriv);
intelSetSpanFunctions(frontRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
}
if (mesaVis->doubleBufferMode) {
driRenderbuffer *backRb
= driNewRenderbuffer(GL_RGBA,
screen->back.map,
screen->cpp,
screen->back.offset, screen->back.pitch,
driDrawPriv);
intelSetSpanFunctions(backRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
}
if (mesaVis->depthBits == 16) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT16,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
else if (mesaVis->depthBits == 24) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT24,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
if (mesaVis->stencilBits > 0 && !swStencil) {
driRenderbuffer *stencilRb
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(stencilRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
}
_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
GL_FALSE, /* depth */
swStencil,
mesaVis->accumRedBits > 0,
GL_FALSE, /* alpha */
GL_FALSE /* aux */);
driDrawPriv->driverPrivate = (void *) fb;
return (driDrawPriv->driverPrivate != NULL);
}
}
static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}
/**
* Get information about previous buffer swaps.
*/
static int
intelGetSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
{
intelContextPtr intel;
if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
|| (dPriv->driContextPriv->driverPrivate == NULL)
|| (sInfo == NULL) ) {
return -1;
}
intel = dPriv->driContextPriv->driverPrivate;
sInfo->swap_count = intel->swap_count;
sInfo->swap_ust = intel->swap_ust;
sInfo->swap_missed_count = intel->swap_missed_count;
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
? driCalculateSwapUsage( dPriv, 0, intel->swap_missed_ust )
: 0.0;
return 0;
}
/* There are probably better ways to do this, such as an
* init-designated function to register chipids and createcontext
* functions.
*/
extern GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
switch (intelScreen->deviceID) {
case PCI_CHIP_845_G:
case PCI_CHIP_I830_M:
case PCI_CHIP_I855_GM:
case PCI_CHIP_I865_G:
return i830CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
case PCI_CHIP_I945_GME:
case PCI_CHIP_G33_G:
case PCI_CHIP_Q35_G:
case PCI_CHIP_Q33_G:
return i915CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
default:
fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
return GL_FALSE;
}
}
static const struct __DriverAPIRec intelAPI = {
.InitDriver = intelInitDriver,
.DestroyScreen = intelDestroyScreen,
.CreateContext = intelCreateContext,
.DestroyContext = intelDestroyContext,
.CreateBuffer = intelCreateBuffer,
.DestroyBuffer = intelDestroyBuffer,
.SwapBuffers = intelSwapBuffers,
.MakeCurrent = intelMakeCurrent,
.UnbindContext = intelUnbindContext,
.GetSwapInfo = intelGetSwapInfo,
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
.CopySubBuffer = intelCopySubBuffer
};
static __GLcontextModes *
intelFillInModes( unsigned pixel_bits, unsigned depth_bits,
unsigned stencil_bits, GLboolean have_back_buffer )
{
__GLcontextModes * modes;
__GLcontextModes * m;
unsigned num_modes;
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
GLenum fb_format;
GLenum fb_type;
/* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
* support pageflipping at all.
*/
static const GLenum back_buffer_modes[] = {
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
};
u_int8_t depth_bits_array[3];
u_int8_t stencil_bits_array[3];
depth_bits_array[0] = 0;
depth_bits_array[1] = depth_bits;
depth_bits_array[2] = depth_bits;
/* Just like with the accumulation buffer, always provide some modes
* with a stencil buffer. It will be a sw fallback, but some apps won't
* care about that.
*/
stencil_bits_array[0] = 0;
stencil_bits_array[1] = 0;
stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
back_buffer_factor = (have_back_buffer) ? 3 : 1;
num_modes = depth_buffer_factor * back_buffer_factor * 4;
if ( pixel_bits == 16 ) {
fb_format = GL_RGB;
fb_type = GL_UNSIGNED_SHORT_5_6_5;
}
else {
fb_format = GL_BGRA;
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
m = modes;
if ( ! driFillInModes( & m, fb_format, fb_type,
depth_bits_array, stencil_bits_array, depth_buffer_factor,
back_buffer_modes, back_buffer_factor,
GLX_TRUE_COLOR ) ) {
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
__func__, __LINE__ );
return NULL;
}
if ( ! driFillInModes( & m, fb_format, fb_type,
depth_bits_array, stencil_bits_array, depth_buffer_factor,
back_buffer_modes, back_buffer_factor,
GLX_DIRECT_COLOR ) ) {
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
__func__, __LINE__ );
return NULL;
}
/* Mark the visual as slow if there are "fake" stencil bits.
*/
for ( m = modes ; m != NULL ; m = m->next ) {
if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
m->visualRating = GLX_SLOW_CONFIG;
}
}
return modes;
}
/**
* This is the bootstrap function for the driver. libGL supplies all of the
* requisite information about the system, and the driver initializes itself.
* This routine also fills in the linked list pointed to by \c driver_modes
* with the \c __GLcontextModes that the driver can support for windows or
* pbuffers.
*
* \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
* failure.
*/
PUBLIC
void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
const __GLcontextModes * modes,
const __DRIversion * ddx_version,
const __DRIversion * dri_version,
const __DRIversion * drm_version,
const __DRIframebuffer * frame_buffer,
drmAddress pSAREA, int fd,
int internal_api_version,
const __DRIinterfaceMethods * interface,
__GLcontextModes ** driver_modes )
{
__DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 5, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 4, 0 };
dri_interface = interface;
if ( ! driCheckDriDdxDrmVersions2( "i915",
dri_version, & dri_expected,
ddx_version, & ddx_expected,
drm_version, & drm_expected ) ) {
return NULL;
}
psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
ddx_version, dri_version, drm_version,
frame_buffer, pSAREA, fd,
internal_api_version, &intelAPI);
if ( psp != NULL ) {
I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
*driver_modes = intelFillInModes( dri_priv->cpp * 8,
(dri_priv->cpp == 2) ? 16 : 24,
(dri_priv->cpp == 2) ? 0 : 8,
1 );
/* Calling driInitExtensions here, with a NULL context pointer, does not actually
* enable the extensions. It just makes sure that all the dispatch offsets for all
* the extensions that *might* be enables are known. This is needed because the
* dispatch offsets need to be known when _mesa_context_create is called, but we can't
* enable the extensions until we have a context pointer.
*
* Hello chicken. Hello egg. How are you two today?
*/
driInitExtensions( NULL, card_extensions, GL_FALSE );
}
return (void *) psp;
}

View File

@ -1,112 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_INIT_H_
#define _INTEL_INIT_H_
#include <sys/time.h>
#include "xmlconfig.h"
#include "dri_util.h"
#include "intel_rotate.h"
#include "i830_common.h"
/* This roughly corresponds to a gl_renderbuffer (Mesa 6.4) */
typedef struct {
drm_handle_t handle;
drmSize size; /* region size in bytes */
char *map; /* memory map */
int offset; /* from start of video mem, in bytes */
int pitch; /* row stride, in bytes */
} intelRegion;
typedef struct
{
intelRegion front;
intelRegion back;
intelRegion rotated;
intelRegion depth;
intelRegion tex;
int deviceID;
int width;
int height;
int mem; /* unused */
int cpp; /* for front and back buffers */
int fbFormat;
int logTextureGranularity;
__DRIscreenPrivate *driScrnPriv;
unsigned int sarea_priv_offset;
int drmMinor;
int irq_active;
int allow_batchbuffer;
struct matrix23 rotMatrix;
int current_rotation; /* 0, 90, 180 or 270 */
int rotatedWidth, rotatedHeight;
/**
* Configuration cache with default values for all contexts
*/
driOptionCache optionCache;
} intelScreenPrivate;
extern GLboolean
intelMapScreenRegions(__DRIscreenPrivate *sPriv);
extern void
intelUnmapScreenRegions(intelScreenPrivate *intelScreen);
extern void
intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
drmI830Sarea *sarea);
extern void
intelDestroyContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelUnbindContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
extern void
intelSwapBuffers(__DRIdrawablePrivate *dPriv);
extern void
intelCopySubBuffer( __DRIdrawablePrivate *dPriv, int x, int y, int w, int h );
#endif

View File

@ -1,258 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "colormac.h"
#include "intel_screen.h"
#include "intel_span.h"
#include "intel_ioctl.h"
#include "swrast/swrast.h"
#define DBG 0
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *) drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch; \
GLushort p; \
(void) buf; (void) p
#define LOCAL_DEPTH_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *) drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
#define INIT_MONO_PIXEL(p,color)\
p = INTEL_PACKCOLOR565(color[0],color[1],color[2])
#define Y_FLIP(_y) (height - _y - 1)
#define HW_LOCK()
#define HW_UNLOCK()
/* 16 bit, 565 rgb color spanline and pixel functions
*/
#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 *)(buf + _x*2 + _y*pitch); \
rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
rgba[3] = 255; \
} while(0)
#define TAG(x) intel##x##_565
#include "spantmp.h"
/* 15 bit, 555 rgb color spanline and pixel functions
*/
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
((g & 0xf8) << 3) | \
((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 *)(buf + _x*2 + _y*pitch); \
rgba[0] = (p >> 7) & 0xf8; \
rgba[1] = (p >> 3) & 0xf8; \
rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 255; \
} while(0)
#define TAG(x) intel##x##_555
#include "spantmp.h"
/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
#define TAG(x) intel##x##_z16
#include "depthtmp.h"
#undef LOCAL_VARS
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *)drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch; \
GLuint p; \
(void) buf; (void) p
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p,color)\
p = INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3])
/* 32 bit, 8888 argb color spanline and pixel functions
*/
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
(g << 8) | \
(b << 0) | \
(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 *)(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) intel##x##_8888
#include "spantmp.h"
/* 24/8 bit interleaved depth/stencil functions
*/
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xff000000; \
tmp |= (d) & 0xffffff; \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
}
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff;
#define TAG(x) intel##x##_z24_s8
#include "depthtmp.h"
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xffffff; \
tmp |= ((d)<<24); \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
}
#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24;
#define TAG(x) intel##x##_z24_s8
#include "stenciltmp.h"
/* Move locking out to get reasonable span performance.
*/
void intelSpanRenderStart( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);
intelWaitForIdle(intel);
}
void intelSpanRenderFinish( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
_swrast_flush( ctx );
UNLOCK_HARDWARE( intel );
}
void intelInitSpanFuncs( GLcontext *ctx )
{
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SpanRenderStart = intelSpanRenderStart;
swdd->SpanRenderFinish = intelSpanRenderFinish;
}
/**
* Plug in the Get/Put routines for the given driRenderbuffer.
*/
void
intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
{
if (drb->Base.InternalFormat == GL_RGBA) {
if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
intelInitPointers_555(&drb->Base);
}
else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
intelInitPointers_565(&drb->Base);
}
else {
assert(vis->redBits == 8);
assert(vis->greenBits == 8);
assert(vis->blueBits == 8);
intelInitPointers_8888(&drb->Base);
}
}
else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
intelInitDepthPointers_z16(&drb->Base);
}
else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
intelInitDepthPointers_z24_s8(&drb->Base);
}
else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
intelInitStencilPointers_z24_s8(&drb->Base);
}
}

View File

@ -1,41 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_SPAN_H
#define _INTEL_SPAN_H
#include "drirenderbuffer.h"
extern void intelInitSpanFuncs( GLcontext *ctx );
extern void intelSpanRenderFinish( GLcontext *ctx );
extern void intelSpanRenderStart( GLcontext *ctx );
extern void
intelSetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis);
#endif

View File

@ -1,281 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "dd.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "swrast/swrast.h"
int intel_translate_compare_func( GLenum func )
{
switch(func) {
case GL_NEVER:
return COMPAREFUNC_NEVER;
case GL_LESS:
return COMPAREFUNC_LESS;
case GL_LEQUAL:
return COMPAREFUNC_LEQUAL;
case GL_GREATER:
return COMPAREFUNC_GREATER;
case GL_GEQUAL:
return COMPAREFUNC_GEQUAL;
case GL_NOTEQUAL:
return COMPAREFUNC_NOTEQUAL;
case GL_EQUAL:
return COMPAREFUNC_EQUAL;
case GL_ALWAYS:
return COMPAREFUNC_ALWAYS;
}
fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
return COMPAREFUNC_ALWAYS;
}
int intel_translate_stencil_op( GLenum op )
{
switch(op) {
case GL_KEEP:
return STENCILOP_KEEP;
case GL_ZERO:
return STENCILOP_ZERO;
case GL_REPLACE:
return STENCILOP_REPLACE;
case GL_INCR:
return STENCILOP_INCRSAT;
case GL_DECR:
return STENCILOP_DECRSAT;
case GL_INCR_WRAP:
return STENCILOP_INCR;
case GL_DECR_WRAP:
return STENCILOP_DECR;
case GL_INVERT:
return STENCILOP_INVERT;
default:
return STENCILOP_ZERO;
}
}
int intel_translate_blend_factor( GLenum factor )
{
switch(factor) {
case GL_ZERO:
return BLENDFACT_ZERO;
case GL_SRC_ALPHA:
return BLENDFACT_SRC_ALPHA;
case GL_ONE:
return BLENDFACT_ONE;
case GL_SRC_COLOR:
return BLENDFACT_SRC_COLR;
case GL_ONE_MINUS_SRC_COLOR:
return BLENDFACT_INV_SRC_COLR;
case GL_DST_COLOR:
return BLENDFACT_DST_COLR;
case GL_ONE_MINUS_DST_COLOR:
return BLENDFACT_INV_DST_COLR;
case GL_ONE_MINUS_SRC_ALPHA:
return BLENDFACT_INV_SRC_ALPHA;
case GL_DST_ALPHA:
return BLENDFACT_DST_ALPHA;
case GL_ONE_MINUS_DST_ALPHA:
return BLENDFACT_INV_DST_ALPHA;
case GL_SRC_ALPHA_SATURATE:
return BLENDFACT_SRC_ALPHA_SATURATE;
case GL_CONSTANT_COLOR:
return BLENDFACT_CONST_COLOR;
case GL_ONE_MINUS_CONSTANT_COLOR:
return BLENDFACT_INV_CONST_COLOR;
case GL_CONSTANT_ALPHA:
return BLENDFACT_CONST_ALPHA;
case GL_ONE_MINUS_CONSTANT_ALPHA:
return BLENDFACT_INV_CONST_ALPHA;
}
fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor);
return BLENDFACT_ZERO;
}
int intel_translate_logic_op( GLenum opcode )
{
switch(opcode) {
case GL_CLEAR:
return LOGICOP_CLEAR;
case GL_AND:
return LOGICOP_AND;
case GL_AND_REVERSE:
return LOGICOP_AND_RVRSE;
case GL_COPY:
return LOGICOP_COPY;
case GL_COPY_INVERTED:
return LOGICOP_COPY_INV;
case GL_AND_INVERTED:
return LOGICOP_AND_INV;
case GL_NOOP:
return LOGICOP_NOOP;
case GL_XOR:
return LOGICOP_XOR;
case GL_OR:
return LOGICOP_OR;
case GL_OR_INVERTED:
return LOGICOP_OR_INV;
case GL_NOR:
return LOGICOP_NOR;
case GL_EQUIV:
return LOGICOP_EQUIV;
case GL_INVERT:
return LOGICOP_INV;
case GL_OR_REVERSE:
return LOGICOP_OR_RVRSE;
case GL_NAND:
return LOGICOP_NAND;
case GL_SET:
return LOGICOP_SET;
default:
return LOGICOP_SET;
}
}
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
int front = 0;
if (!ctx->DrawBuffer)
return;
switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
case BUFFER_BIT_FRONT_LEFT:
front = 1;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BUFFER_BIT_BACK_LEFT:
front = 0;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
intelSetFrontClipRects( intel );
if (front) {
intel->drawRegion = &intel->intelScreen->front;
intel->readRegion = &intel->intelScreen->front;
} else {
intel->drawRegion = &intel->intelScreen->back;
intel->readRegion = &intel->intelScreen->back;
}
intel->vtbl.set_color_region( intel, intel->drawRegion );
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
{
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}
static void intelClearColor(GLcontext *ctx, const GLfloat color[4])
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelScreenPrivate *screen = intel->intelScreen;
CLAMPED_FLOAT_TO_UBYTE(intel->clear_red, color[0]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_green, color[1]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_blue, color[2]);
CLAMPED_FLOAT_TO_UBYTE(intel->clear_alpha, color[3]);
intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat,
intel->clear_red,
intel->clear_green,
intel->clear_blue,
intel->clear_alpha);
}
static void intelCalcViewport( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
const GLfloat *v = ctx->Viewport._WindowMap.m;
GLfloat *m = intel->ViewportMatrix.m;
GLint h = 0;
if (intel->driDrawable)
h = intel->driDrawable->h + SUBPIXEL_Y;
/* See also intel_translate_vertex. SUBPIXEL adjustments can be done
* via state vars, too.
*/
m[MAT_SX] = v[MAT_SX];
m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
m[MAT_SY] = - v[MAT_SY];
m[MAT_TY] = - v[MAT_TY] + h;
m[MAT_SZ] = v[MAT_SZ] * intel->depth_scale;
m[MAT_TZ] = v[MAT_TZ] * intel->depth_scale;
}
static void intelViewport( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height )
{
intelCalcViewport( ctx );
}
static void intelDepthRange( GLcontext *ctx,
GLclampd nearval, GLclampd farval )
{
intelCalcViewport( ctx );
}
/* Fallback to swrast for select and feedback.
*/
static void intelRenderMode( GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
}
void intelInitStateFuncs( struct dd_function_table *functions )
{
functions->DrawBuffer = intelDrawBuffer;
functions->ReadBuffer = intelReadBuffer;
functions->RenderMode = intelRenderMode;
functions->Viewport = intelViewport;
functions->DepthRange = intelDepthRange;
functions->ClearColor = intelClearColor;
}

View File

@ -1,879 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "macros.h"
#include "simple_list.h"
#include "enums.h"
#include "image.h"
#include "texstore.h"
#include "texformat.h"
#include "teximage.h"
#include "texmem.h"
#include "texobj.h"
#include "swrast/swrast.h"
#include "mm.h"
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_tex.h"
#include "intel_ioctl.h"
static GLboolean
intelValidateClientStorage( intelContextPtr intel, GLenum target,
GLint internalFormat,
GLint srcWidth, GLint srcHeight,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
GLcontext *ctx = &intel->ctx;
int texelBytes;
if (0)
fprintf(stderr, "intformat %s format %s type %s\n",
_mesa_lookup_enum_by_nr( internalFormat ),
_mesa_lookup_enum_by_nr( format ),
_mesa_lookup_enum_by_nr( type ));
if (!ctx->Unpack.ClientStorage)
return 0;
if (ctx->_ImageTransferState ||
texImage->IsCompressed ||
texObj->GenerateMipmap)
return 0;
/* This list is incomplete
*/
switch ( internalFormat ) {
case GL_RGBA:
if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
texImage->TexFormat = &_mesa_texformat_argb8888;
texelBytes = 4;
}
else
return 0;
break;
case GL_RGB:
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
texImage->TexFormat = &_mesa_texformat_rgb565;
texelBytes = 2;
}
else
return 0;
break;
case GL_YCBCR_MESA:
if ( format == GL_YCBCR_MESA &&
type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
texelBytes = 2;
}
else if ( format == GL_YCBCR_MESA &&
(type == GL_UNSIGNED_SHORT_8_8_APPLE ||
type == GL_UNSIGNED_BYTE)) {
texImage->TexFormat = &_mesa_texformat_ycbcr;
texelBytes = 2;
}
else
return 0;
break;
default:
return 0;
}
/* Could deal with these packing issues, but currently don't:
*/
if (packing->SkipPixels ||
packing->SkipRows ||
packing->SwapBytes ||
packing->LsbFirst) {
return 0;
}
{
GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
format, type);
if (0)
fprintf(stderr, "%s: srcRowStride %d/%x\n",
__FUNCTION__, srcRowStride, srcRowStride);
/* Could check this later in upload, pitch restrictions could be
* relaxed, but would need to store the image pitch somewhere,
* as packing details might change before image is uploaded:
*/
if (!intelIsAgpMemory( intel, pixels, srcHeight * srcRowStride ) ||
(srcRowStride & 63))
return 0;
/* Have validated that _mesa_transfer_teximage would be a straight
* memcpy at this point. NOTE: future calls to TexSubImage will
* overwrite the client data. This is explicitly mentioned in the
* extension spec.
*/
texImage->Data = (void *)pixels;
texImage->IsClientData = GL_TRUE;
texImage->RowStride = srcRowStride / texelBytes;
return 1;
}
}
static void intelTexImage1D( 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 )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert(t);
intelFlush( ctx );
driSwapOutTextureObject( t );
texImage->IsClientData = GL_FALSE;
_mesa_store_teximage1d( ctx, target, level, internalFormat,
width, border, format, type,
pixels, packing, texObj, texImage );
t->dirty_images[0] |= (1 << level);
}
static void intelTexSubImage1D( 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 )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert(t);
intelFlush( ctx );
driSwapOutTextureObject( t );
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
format, type, pixels, packing, texObj,
texImage);
}
/* Handles 2D, CUBE, RECT:
*/
static void intelTexImage2D( 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 )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
GLuint face;
/* which cube face or ordinary 2D image */
switch (target) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
ASSERT(face < 6);
break;
default:
face = 0;
}
assert(t);
intelFlush( ctx );
driSwapOutTextureObject( t );
texImage->IsClientData = GL_FALSE;
if (intelValidateClientStorage( INTEL_CONTEXT(ctx), target,
internalFormat,
width, height,
format, type, pixels,
packing, texObj, texImage)) {
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
}
else {
_mesa_store_teximage2d( ctx, target, level, internalFormat,
width, height, border, format, type,
pixels, packing, texObj, texImage );
t->dirty_images[face] |= (1 << level);
}
}
static void intelTexSubImage2D( 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 )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
GLuint face;
/* which cube face or ordinary 2D image */
switch (target) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
ASSERT(face < 6);
break;
default:
face = 0;
}
if (texImage->IsClientData &&
(char *)pixels == (char *)texImage->Data +
((xoffset + yoffset * texImage->RowStride) *
texImage->TexFormat->TexelBytes)) {
/* Notification only - no upload required */
}
else {
assert( t ); /* this _should_ be true */
intelFlush( ctx );
driSwapOutTextureObject( t );
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
texImage);
t->dirty_images[face] |= (1 << level);
}
}
static void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint border,
GLsizei imageSize, const GLvoid *data,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
GLuint face;
/* which cube face or ordinary 2D image */
switch (target) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
ASSERT(face < 6);
break;
default:
face = 0;
}
assert(t);
intelFlush( ctx );
driSwapOutTextureObject( t );
texImage->IsClientData = GL_FALSE;
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
_mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
height, border, imageSize, data, texObj, texImage);
t->dirty_images[face] |= (1 << level);
}
static void intelCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format,
GLsizei imageSize, const GLvoid *data,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
GLuint face;
/* which cube face or ordinary 2D image */
switch (target) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
ASSERT(face < 6);
break;
default:
face = 0;
}
assert( t ); /* this _should_ be true */
intelFlush( ctx );
driSwapOutTextureObject( t );
_mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, imageSize, data, texObj, texImage);
t->dirty_images[face] |= (1 << level);
}
static void intelTexImage3D( GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
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 )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert(t);
driSwapOutTextureObject( t );
texImage->IsClientData = GL_FALSE;
_mesa_store_teximage3d(ctx, target, level, internalFormat,
width, height, depth, border,
format, type, pixels,
&ctx->Unpack, texObj, texImage);
t->dirty_images[0] |= (1 << level);
}
static void
intelTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert( t ); /* this _should_ be true */
driSwapOutTextureObject( t );
_mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
width, height, depth,
format, type, pixels, packing, texObj, texImage);
t->dirty_images[0] |= (1 << level);
}
static void intelDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
driTextureObject * t = (driTextureObject *) tObj->DriverData;
if ( t != NULL ) {
intelFlush( ctx );
driDestroyTextureObject( t );
}
/* Free mipmap images and the texture object itself */
_mesa_delete_texture_object(ctx, tObj);
}
static const struct gl_texture_format *
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 &&
intel->intelScreen->tex.size > 4*1024*1024);
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_argb8888 : &_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_argb8888 : &_mesa_texformat_rgb565;
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
return do32bpt ? &_mesa_texformat_argb8888 : &_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_argb8888 : &_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_a8;
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE4:
case GL_LUMINANCE8:
case GL_LUMINANCE12:
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
return &_mesa_texformat_l8;
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;
case GL_YCBCR_MESA:
if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
type == GL_UNSIGNED_BYTE)
return &_mesa_texformat_ycbcr;
else
return &_mesa_texformat_ycbcr_rev;
case GL_COMPRESSED_RGB_FXT1_3DFX:
return &_mesa_texformat_rgb_fxt1;
case GL_COMPRESSED_RGBA_FXT1_3DFX:
return &_mesa_texformat_rgba_fxt1;
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
return &_mesa_texformat_rgb_dxt1;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
return &_mesa_texformat_rgba_dxt1;
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
return &_mesa_texformat_rgba_dxt3;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return &_mesa_texformat_rgba_dxt5;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
return &_mesa_texformat_z16;
default:
fprintf(stderr, "unexpected texture format %s in %s\n",
_mesa_lookup_enum_by_nr(internalFormat),
__FUNCTION__);
return NULL;
}
return NULL; /* never get here */
}
void intelDestroyTexObj(intelContextPtr intel, intelTextureObjectPtr t)
{
unsigned i;
if ( intel == NULL )
return;
if ( t->age > intel->dirtyAge )
intel->dirtyAge = t->age;
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
if ( t == intel->CurrentTexObj[ i ] )
intel->CurrentTexObj[ i ] = NULL;
}
}
/* Upload an image from mesa's internal copy. Image may be 1D, 2D or
* 3D. Cubemaps are expanded elsewhere.
*/
static void intelUploadTexImage( intelContextPtr intel,
intelTextureObjectPtr t,
const struct gl_texture_image *image,
const GLuint offset )
{
if (!image || !image->Data)
return;
if (image->Depth == 1 && image->IsClientData) {
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "Blit uploading\n");
/* Do it with a blit.
*/
intelEmitCopyBlitLocked( intel,
image->TexFormat->TexelBytes,
image->RowStride, /* ? */
intelGetMemoryOffsetMESA( NULL, 0, image->Data ),
t->Pitch / image->TexFormat->TexelBytes,
intelGetMemoryOffsetMESA( NULL, 0, t->BufAddr + offset ),
0, 0,
0, 0,
image->Width,
image->Height);
}
else if (image->IsCompressed) {
GLuint row_len = 0;
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
GLubyte *src = (GLubyte *)image->Data;
GLuint j;
/* must always copy whole blocks (8/16 bytes) */
switch (image->InternalFormat) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
row_len = ((image->Width + 7) & ~7) * 2;
break;
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
row_len = ((image->Width + 3) & ~3) * 2;
break;
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
row_len = ((image->Width + 3) & ~3) * 4;
break;
default:
fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat);
break;
}
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr,
"Upload image %dx%dx%d offset %xm row_len %x "
"pitch %x depth_pitch %x\n",
image->Width, image->Height, image->Depth, offset,
row_len, t->Pitch, t->depth_pitch);
if (row_len) {
for (j = 0 ; j < (image->Height + 3)/4 ; j++, dst += (t->Pitch)) {
__memcpy(dst, src, row_len );
src += row_len;
}
}
}
/* Time for another vtbl entry:
*/
else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G ||
intel->intelScreen->deviceID == PCI_CHIP_I945_GM ||
intel->intelScreen->deviceID == PCI_CHIP_I945_GME ||
intel->intelScreen->deviceID == PCI_CHIP_G33_G ||
intel->intelScreen->deviceID == PCI_CHIP_Q33_G ||
intel->intelScreen->deviceID == PCI_CHIP_Q35_G) {
GLuint row_len = image->Width * image->TexFormat->TexelBytes;
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
GLubyte *src = (GLubyte *)image->Data;
GLuint d, j;
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr,
"Upload image %dx%dx%d offset %xm row_len %x "
"pitch %x depth_pitch %x\n",
image->Width, image->Height, image->Depth, offset,
row_len, t->Pitch, t->depth_pitch);
if (row_len == t->Pitch) {
memcpy( dst, src, row_len * image->Height * image->Depth );
}
else {
GLuint x = 0, y = 0;
for (d = 0 ; d < image->Depth ; d++) {
GLubyte *dst0 = dst + x + y * t->Pitch;
for (j = 0 ; j < image->Height ; j++) {
__memcpy(dst0, src, row_len );
src += row_len;
dst0 += t->Pitch;
}
x += MIN2(4, row_len); /* Guess: 4 byte minimum alignment */
if (x > t->Pitch) {
x = 0;
y += image->Height;
}
}
}
}
else {
GLuint row_len = image->Width * image->TexFormat->TexelBytes;
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
GLubyte *src = (GLubyte *)image->Data;
GLuint d, j;
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr,
"Upload image %dx%dx%d offset %xm row_len %x "
"pitch %x depth_pitch %x\n",
image->Width, image->Height, image->Depth, offset,
row_len, t->Pitch, t->depth_pitch);
if (row_len == t->Pitch) {
for (d = 0; d < image->Depth; d++) {
memcpy( dst, src, t->Pitch * image->Height );
dst += t->depth_pitch;
src += row_len * image->Height;
}
}
else {
for (d = 0 ; d < image->Depth ; d++) {
for (j = 0 ; j < image->Height ; j++) {
__memcpy(dst, src, row_len );
src += row_len;
dst += t->Pitch;
}
dst += t->depth_pitch - (t->Pitch * image->Height);
}
}
}
}
int intelUploadTexImages( intelContextPtr intel,
intelTextureObjectPtr t,
GLuint face)
{
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image;
int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes;
/* Can we texture out of the existing client data? */
if ( numLevels == 1 &&
firstImage->IsClientData &&
(pitch & 3) == 0) {
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "AGP texturing from client memory\n");
t->TextureOffset = intelAgpOffsetFromVirtual( intel, firstImage->Data );
t->BufAddr = 0;
t->dirty = ~0;
return GL_TRUE;
}
else {
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "Uploading client data to agp\n");
INTEL_FIREVERTICES( intel );
LOCK_HARDWARE( intel );
if ( t->base.memBlock == NULL ) {
int heap;
heap = driAllocateTexture( intel->texture_heaps, intel->nr_heaps,
(driTextureObject *) t );
if ( heap == -1 ) {
UNLOCK_HARDWARE( intel );
return GL_FALSE;
}
/* Set the base offset of the texture image */
t->BufAddr = (GLubyte *) (intel->intelScreen->tex.map +
t->base.memBlock->ofs);
t->TextureOffset = intel->intelScreen->tex.offset + t->base.memBlock->ofs;
t->dirty = ~0;
}
/* Let the world know we've used this memory recently.
*/
driUpdateTextureLRU( (driTextureObject *) t );
/* Upload any images that are new */
if (t->base.dirty_images[face]) {
int i;
intelWaitForIdle( intel );
for (i = 0 ; i < numLevels ; i++) {
int level = i + t->base.firstLevel;
if (t->base.dirty_images[face] & (1<<level)) {
const struct gl_texture_image *image = t->image[face][i].image;
GLuint offset = t->image[face][i].offset;
if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "upload level %d, offset %x\n",
level, offset);
intelUploadTexImage( intel, t, image, offset );
}
}
t->base.dirty_images[face] = 0;
intel->perf_boxes |= I830_BOX_TEXTURE_LOAD;
}
UNLOCK_HARDWARE( intel );
return GL_TRUE;
}
}
/**
* Allocate a new texture object.
* Called via ctx->Driver.NewTextureObject.
* Note: this function will be called during context creation to
* allocate the default texture objects.
* Note: we could use containment here to 'derive' the driver-specific
* texture object from the core mesa gl_texture_object. Not done at this time.
*/
static struct gl_texture_object *
intelNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
{
struct gl_texture_object *obj = _mesa_new_texture_object(ctx, name, target);
INTEL_CONTEXT(ctx)->vtbl.alloc_tex_obj( obj );
return obj;
}
void intelInitTextureFuncs( struct dd_function_table *functions )
{
functions->NewTextureObject = intelNewTextureObject;
functions->ChooseTextureFormat = intelChooseTextureFormat;
functions->TexImage1D = intelTexImage1D;
functions->TexImage2D = intelTexImage2D;
functions->TexImage3D = intelTexImage3D;
functions->TexSubImage1D = intelTexSubImage1D;
functions->TexSubImage2D = intelTexSubImage2D;
functions->TexSubImage3D = intelTexSubImage3D;
functions->CopyTexImage1D = _swrast_copy_teximage1d;
functions->CopyTexImage2D = _swrast_copy_teximage2d;
functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
functions->DeleteTexture = intelDeleteTexture;
functions->UpdateTexturePalette = NULL;
functions->IsTextureResident = driIsTextureResident;
functions->TestProxyTexImage = _mesa_test_proxy_teximage;
functions->DeleteTexture = intelDeleteTexture;
functions->CompressedTexImage2D = intelCompressedTexImage2D;
functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
}

View File

@ -1,45 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTELTEX_INC
#define INTELTEX_INC
#include "mtypes.h"
#include "intel_context.h"
#include "texmem.h"
void intelInitTextureFuncs( struct dd_function_table *functions );
void intelDestroyTexObj( intelContextPtr intel, intelTextureObjectPtr t );
int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t,
GLuint face );
GLboolean
intel_driReinitTextureHeap( driTexHeap *heap,
unsigned size );
#endif

View File

@ -1,72 +0,0 @@
#include "texmem.h"
#include "simple_list.h"
#include "imports.h"
#include "macros.h"
#include "intel_tex.h"
static GLuint
driLog2( GLuint n )
{
GLuint log2;
for ( log2 = 1 ; n > 1 ; log2++ ) {
n >>= 1;
}
return log2;
}
static void calculate_heap_size( driTexHeap * heap, unsigned size,
unsigned nr_regions, unsigned alignmentShift )
{
unsigned l;
l = driLog2( (size - 1) / nr_regions );
if ( l < alignmentShift )
{
l = alignmentShift;
}
heap->logGranularity = l;
heap->size = size & ~((1L << l) - 1);
}
GLboolean
intel_driReinitTextureHeap( driTexHeap *heap,
unsigned size )
{
driTextureObject *t, *tmp;
/* Kick out everything:
*/
foreach_s ( t, tmp, & heap->texture_objects ) {
if ( t->tObj != NULL ) {
driSwapOutTextureObject( t );
}
else {
driDestroyTextureObject( t );
}
}
/* Destroy the memory manager:
*/
mmDestroy( heap->memory_heap );
/* Recreate the memory manager:
*/
calculate_heap_size(heap, size, heap->nrRegions, heap->alignmentShift);
heap->memory_heap = mmInit( 0, heap->size );
if ( heap->memory_heap == NULL ) {
fprintf(stderr, "driReinitTextureHeap: couldn't recreate memory heap\n");
FREE( heap );
return GL_FALSE;
}
make_empty_list( & heap->texture_objects );
return GL_TRUE;
}

View File

@ -1,945 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "dd.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
#include "intel_screen.h"
#include "intel_tris.h"
#include "intel_batchbuffer.h"
#include "intel_reg.h"
#include "intel_span.h"
/* XXX we shouldn't include these headers in this file, but we need them
* for fallbackStrings, below.
*/
#include "i830_context.h"
#include "i915_context.h"
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
/***********************************************************************
* Emit primitives as inline vertices *
***********************************************************************/
#ifdef __i386__
#define COPY_DWORDS( j, vb, vertsize, v ) \
do { \
int __tmp; \
__asm__ __volatile__( "rep ; movsl" \
: "=%c" (j), "=D" (vb), "=S" (__tmp) \
: "0" (vertsize), \
"D" ((long)vb), \
"S" ((long)v) ); \
} while (0)
#else
#define COPY_DWORDS( j, vb, vertsize, v ) \
do { \
if (0) fprintf(stderr, "\n"); \
for ( j = 0 ; j < vertsize ; j++ ) { \
if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \
((GLuint *)v)[j], \
((GLfloat *)v)[j]); \
vb[j] = ((GLuint *)v)[j]; \
} \
vb += vertsize; \
} while (0)
#endif
static void __inline__ intel_draw_quad( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2,
intelVertexPtr v3 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize );
int j;
COPY_DWORDS( j, vb, vertsize, v0 );
COPY_DWORDS( j, vb, vertsize, v1 );
COPY_DWORDS( j, vb, vertsize, v3 );
COPY_DWORDS( j, vb, vertsize, v1 );
COPY_DWORDS( j, vb, vertsize, v2 );
COPY_DWORDS( j, vb, vertsize, v3 );
}
static void __inline__ intel_draw_triangle( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize );
int j;
COPY_DWORDS( j, vb, vertsize, v0 );
COPY_DWORDS( j, vb, vertsize, v1 );
COPY_DWORDS( j, vb, vertsize, v2 );
}
static __inline__ void intel_draw_line( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize );
int j;
COPY_DWORDS( j, vb, vertsize, v0 );
COPY_DWORDS( j, vb, vertsize, v1 );
}
static __inline__ void intel_draw_point( intelContextPtr intel,
intelVertexPtr v0 )
{
GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, vertsize );
int j;
/* Adjust for sub pixel position -- still required for conform. */
*(float *)&vb[0] = v0->v.x - 0.125;
*(float *)&vb[1] = v0->v.y - 0.125;
for (j = 2 ; j < vertsize ; j++)
vb[j] = v0->ui[j];
}
/***********************************************************************
* Fixup for ARB_point_parameters *
***********************************************************************/
static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
{
GLcontext *ctx = &intel->ctx;
GLfloat psz[4], col[4], restore_psz, restore_alpha;
_tnl_get_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz );
_tnl_get_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col );
restore_psz = psz[0];
restore_alpha = col[3];
if (psz[0] >= ctx->Point.Threshold) {
psz[0] = MIN2(psz[0], ctx->Point.MaxSize);
}
else {
GLfloat dsize = psz[0] / ctx->Point.Threshold;
psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
col[3] *= dsize * dsize;
}
if (psz[0] < 1.0)
psz[0] = 1.0;
if (restore_psz != psz[0] || restore_alpha != col[3]) {
_tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz);
_tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col);
intel_draw_point( intel, v0 );
psz[0] = restore_psz;
col[3] = restore_alpha;
_tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz);
_tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col);
}
else
intel_draw_point( intel, v0 );
}
/***********************************************************************
* Fixup for I915 WPOS texture coordinate *
***********************************************************************/
static void intel_wpos_triangle( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1,
intelVertexPtr v2 )
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
__memcpy( ((char *)v0) + offset, v0, size );
__memcpy( ((char *)v1) + offset, v1, size );
__memcpy( ((char *)v2) + offset, v2, size );
intel_draw_triangle( intel, v0, v1, v2 );
}
static void intel_wpos_line( intelContextPtr intel,
intelVertexPtr v0,
intelVertexPtr v1 )
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
__memcpy( ((char *)v0) + offset, v0, size );
__memcpy( ((char *)v1) + offset, v1, size );
intel_draw_line( intel, v0, v1 );
}
static void intel_wpos_point( intelContextPtr intel,
intelVertexPtr v0 )
{
GLuint offset = intel->wpos_offset;
GLuint size = intel->wpos_size;
__memcpy( ((char *)v0) + offset, v0, size );
intel_draw_point( intel, v0 );
}
/***********************************************************************
* Macros for t_dd_tritmp.h to draw basic primitives *
***********************************************************************/
#define TRI( a, b, c ) \
do { \
if (DO_FALLBACK) \
intel->draw_tri( intel, a, b, c ); \
else \
intel_draw_triangle( intel, a, b, c ); \
} while (0)
#define QUAD( a, b, c, d ) \
do { \
if (DO_FALLBACK) { \
intel->draw_tri( intel, a, b, d ); \
intel->draw_tri( intel, b, c, d ); \
} else \
intel_draw_quad( intel, a, b, c, d ); \
} while (0)
#define LINE( v0, v1 ) \
do { \
if (DO_FALLBACK) \
intel->draw_line( intel, v0, v1 ); \
else \
intel_draw_line( intel, v0, v1 ); \
} while (0)
#define POINT( v0 ) \
do { \
if (DO_FALLBACK) \
intel->draw_point( intel, v0 ); \
else \
intel_draw_point( intel, v0 ); \
} while (0)
/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/
#define INTEL_OFFSET_BIT 0x01
#define INTEL_TWOSIDE_BIT 0x02
#define INTEL_UNFILLED_BIT 0x04
#define INTEL_FALLBACK_BIT 0x08
#define INTEL_MAX_TRIFUNC 0x10
static struct {
tnl_points_func points;
tnl_line_func line;
tnl_triangle_func triangle;
tnl_quad_func quad;
} rast_tab[INTEL_MAX_TRIFUNC];
#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT)
#define DO_OFFSET (IND & INTEL_OFFSET_BIT)
#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT)
#define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT)
#define DO_FLAT 0
#define DO_TRI 1
#define DO_QUAD 1
#define DO_LINE 1
#define DO_POINTS 1
#define DO_FULL_QUAD 1
#define HAVE_RGBA 1
#define HAVE_SPEC 1
#define HAVE_BACK_COLORS 0
#define HAVE_HW_FLATSHADE 1
#define VERTEX intelVertex
#define TAB rast_tab
/* Only used to pull back colors into vertices (ie, we know color is
* floating point).
*/
#define INTEL_COLOR( dst, src ) \
do { \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
} while (0)
#define INTEL_SPEC( dst, src ) \
do { \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
} while (0)
#define DEPTH_SCALE intel->polygon_offset_scale
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define VERT_X(_v) _v->v.x
#define VERT_Y(_v) _v->v.y
#define VERT_Z(_v) _v->v.z
#define AREA_IS_CCW( a ) (a > 0)
#define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint)))
#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c )
#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c )
#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
#define LOCAL_VARS(n) \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
GLuint color[n], spec[n]; \
GLuint coloroffset = intel->coloroffset; \
GLboolean specoffset = intel->specoffset; \
(void) color; (void) spec; (void) coloroffset; (void) specoffset;
/***********************************************************************
* Helpers for rendering unfilled primitives *
***********************************************************************/
static const GLuint hw_prim[GL_POLYGON+1] = {
PRIM3D_POINTLIST,
PRIM3D_LINELIST,
PRIM3D_LINELIST,
PRIM3D_LINELIST,
PRIM3D_TRILIST,
PRIM3D_TRILIST,
PRIM3D_TRILIST,
PRIM3D_TRILIST,
PRIM3D_TRILIST,
PRIM3D_TRILIST
};
#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] )
#define RENDER_PRIMITIVE intel->render_primitive
#define TAG(x) x
#define IND INTEL_FALLBACK_BIT
#include "tnl_dd/t_dd_unfilled.h"
#undef IND
/***********************************************************************
* Generate GL render functions *
***********************************************************************/
#define IND (0)
#define TAG(x) x
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_OFFSET_BIT)
#define TAG(x) x##_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT)
#define TAG(x) x##_twoside_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)
#define TAG(x) x##_twoside_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_FALLBACK_BIT)
#define TAG(x) x##_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_twoside_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
#define TAG(x) x##_twoside_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \
INTEL_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
static void init_rast_tab( void )
{
init();
init_offset();
init_twoside();
init_twoside_offset();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_twoside_offset_unfilled();
init_fallback();
init_offset_fallback();
init_twoside_fallback();
init_twoside_offset_fallback();
init_unfilled_fallback();
init_offset_unfilled_fallback();
init_twoside_unfilled_fallback();
init_twoside_offset_unfilled_fallback();
}
/***********************************************************************
* Rasterization fallback helpers *
***********************************************************************/
/* This code is hit only when a mix of accelerated and unaccelerated
* primitives are being drawn, and only for the unaccelerated
* primitives.
*/
static void
intel_fallback_tri( intelContextPtr intel,
intelVertex *v0,
intelVertex *v1,
intelVertex *v2 )
{
GLcontext *ctx = &intel->ctx;
SWvertex v[3];
if (0)
fprintf(stderr, "\n%s\n", __FUNCTION__);
_swsetup_Translate( ctx, v0, &v[0] );
_swsetup_Translate( ctx, v1, &v[1] );
_swsetup_Translate( ctx, v2, &v[2] );
intelSpanRenderStart( ctx );
_swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
intelSpanRenderFinish( ctx );
}
static void
intel_fallback_line( intelContextPtr intel,
intelVertex *v0,
intelVertex *v1 )
{
GLcontext *ctx = &intel->ctx;
SWvertex v[2];
if (0)
fprintf(stderr, "\n%s\n", __FUNCTION__);
_swsetup_Translate( ctx, v0, &v[0] );
_swsetup_Translate( ctx, v1, &v[1] );
intelSpanRenderStart( ctx );
_swrast_Line( ctx, &v[0], &v[1] );
intelSpanRenderFinish( ctx );
}
static void
intel_fallback_point( intelContextPtr intel,
intelVertex *v0 )
{
GLcontext *ctx = &intel->ctx;
SWvertex v[1];
if (0)
fprintf(stderr, "\n%s\n", __FUNCTION__);
_swsetup_Translate( ctx, v0, &v[0] );
intelSpanRenderStart( ctx );
_swrast_Point( ctx, &v[0] );
intelSpanRenderFinish( ctx );
}
/**********************************************************************/
/* Render unclipped begin/end objects */
/**********************************************************************/
#define IND 0
#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint)))
#define RENDER_POINTS( start, count ) \
for ( ; start < count ; start++) POINT( V(ELT(start)) );
#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
#define INIT(x) intelRenderPrimitive( ctx, x )
#undef LOCAL_VARS
#define LOCAL_VARS \
intelContextPtr intel = INTEL_CONTEXT(ctx); \
GLubyte *vertptr = (GLubyte *)intel->verts; \
const GLuint vertsize = intel->vertex_size; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
(void) elt;
#define RESET_STIPPLE
#define RESET_OCCLUSION
#define PRESERVE_VB_DEFS
#define ELT(x) x
#define TAG(x) intel_##x##_verts
#include "tnl/t_vb_rendertmp.h"
#undef ELT
#undef TAG
#define TAG(x) intel_##x##_elts
#define ELT(x) elt[x]
#include "tnl/t_vb_rendertmp.h"
/**********************************************************************/
/* Render clipped primitives */
/**********************************************************************/
static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint prim = intel->render_primitive;
/* Render the new vertices as an unclipped polygon.
*/
{
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n,
PRIM_BEGIN|PRIM_END );
VB->Elts = tmp;
}
/* Restore the render primitive
*/
if (prim != GL_POLYGON)
tnl->Driver.Render.PrimitiveNotify( ctx, prim );
}
static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line( ctx, ii, jj );
}
static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
const GLuint vertsize = intel->vertex_size;
GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize );
GLubyte *vertptr = (GLubyte *)intel->verts;
const GLuint *start = (const GLuint *)V(elts[0]);
int i,j;
for (i = 2 ; i < n ; i++) {
COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) );
COPY_DWORDS( j, vb, vertsize, V(elts[i]) );
COPY_DWORDS( j, vb, vertsize, start );
}
}
/**********************************************************************/
/* Choose render functions */
/**********************************************************************/
#define POINT_FALLBACK (0)
#define LINE_FALLBACK (DD_LINE_STIPPLE)
#define TRI_FALLBACK (0)
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
DD_TRI_STIPPLE|DD_POINT_ATTEN)
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
void intelChooseRenderState(GLcontext *ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
intelContextPtr intel = INTEL_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current;
GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
GLuint index = 0;
if (INTEL_DEBUG & DEBUG_STATE)
fprintf(stderr,"\n%s\n",__FUNCTION__);
if ((flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) || have_wpos) {
if (flags & ANY_RASTER_FLAGS) {
if (flags & DD_TRI_LIGHT_TWOSIDE) index |= INTEL_TWOSIDE_BIT;
if (flags & DD_TRI_OFFSET) index |= INTEL_OFFSET_BIT;
if (flags & DD_TRI_UNFILLED) index |= INTEL_UNFILLED_BIT;
}
if (have_wpos) {
intel->draw_point = intel_wpos_point;
intel->draw_line = intel_wpos_line;
intel->draw_tri = intel_wpos_triangle;
/* Make sure these get called:
*/
index |= INTEL_FALLBACK_BIT;
}
else {
intel->draw_point = intel_draw_point;
intel->draw_line = intel_draw_line;
intel->draw_tri = intel_draw_triangle;
}
/* Hook in fallbacks for specific primitives.
*/
if (flags & ANY_FALLBACK_FLAGS)
{
if (flags & POINT_FALLBACK)
intel->draw_point = intel_fallback_point;
if (flags & LINE_FALLBACK)
intel->draw_line = intel_fallback_line;
if (flags & TRI_FALLBACK)
intel->draw_tri = intel_fallback_tri;
if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple)
intel->draw_tri = intel_fallback_tri;
if (flags & DD_POINT_ATTEN)
intel->draw_point = intel_atten_point;
index |= INTEL_FALLBACK_BIT;
}
}
if (intel->RenderIndex != index) {
intel->RenderIndex = index;
tnl->Driver.Render.Points = rast_tab[index].points;
tnl->Driver.Render.Line = rast_tab[index].line;
tnl->Driver.Render.Triangle = rast_tab[index].triangle;
tnl->Driver.Render.Quad = rast_tab[index].quad;
if (index == 0) {
tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts;
tnl->Driver.Render.PrimTabElts = intel_render_tab_elts;
tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly;
} else {
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ClippedLine = intelRenderClippedLine;
tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly;
}
}
}
static const GLenum reduced_prim[GL_POLYGON+1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
/**********************************************************************/
/* High level hooks for t_vb_render.c */
/**********************************************************************/
static void intelRunPipeline( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
if (intel->NewGLState) {
if (intel->NewGLState & _NEW_TEXTURE) {
intel->vtbl.update_texture_state( intel );
}
if (!intel->Fallback) {
if (intel->NewGLState & _INTEL_NEW_RENDERSTATE)
intelChooseRenderState( ctx );
}
intel->NewGLState = 0;
}
_tnl_run_pipeline( ctx );
}
static void intelRenderStart( GLcontext *ctx )
{
INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) );
}
static void intelRenderFinish( GLcontext *ctx )
{
if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT)
_swrast_flush( ctx );
}
/* System to flush dma and emit state changes based on the rasterized
* primitive.
*/
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
if (0)
fprintf(stderr, "%s %s %x\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(rprim), hwprim);
intel->vtbl.reduced_primitive_state( intel, rprim );
/* Start a new primitive. Arrange to have it flushed later on.
*/
if (hwprim != intel->prim.primitive)
intelStartInlinePrimitive( intel, hwprim );
}
/*
*/
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
if (0)
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
/* Let some clipping routines know which primitive they're dealing
* with.
*/
intel->render_primitive = prim;
/* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
* triangles. The rasterized primitive will always be reset by
* lower level functions in that case, potentially pingponging the
* state:
*/
if (reduced_prim[prim] == GL_TRIANGLES &&
(ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
/* Set some primitive-dependent state and Start? a new primitive.
*/
intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
}
/**********************************************************************/
/* Transition to/from hardware rasterization. */
/**********************************************************************/
static struct {
GLuint bit;
const char *str;
} fallbackStrings[] = {
{ INTEL_FALLBACK_DRAW_BUFFER, "Draw buffer" },
{ INTEL_FALLBACK_READ_BUFFER, "Read buffer" },
{ INTEL_FALLBACK_USER, "User" },
{ INTEL_FALLBACK_NO_BATCHBUFFER, "No Batchbuffer" },
{ INTEL_FALLBACK_NO_TEXMEM, "No Texmem" },
{ INTEL_FALLBACK_RENDERMODE, "Rendermode" },
{ I830_FALLBACK_TEXTURE, "i830 texture" },
{ I830_FALLBACK_COLORMASK, "i830 colormask" },
{ I830_FALLBACK_STENCIL, "i830 stencil" },
{ I830_FALLBACK_STIPPLE, "i830 stipple" },
{ I830_FALLBACK_LOGICOP, "i830 logicop" },
{ I915_FALLBACK_TEXTURE, "i915 texture" },
{ I915_FALLBACK_COLORMASK, "i915 colormask" },
{ I915_FALLBACK_STENCIL, "i915 stencil" },
{ I915_FALLBACK_STIPPLE, "i915 stipple" },
{ I915_FALLBACK_PROGRAM, "i915 program" },
{ I915_FALLBACK_LOGICOP, "i915 logicop" },
{ I915_FALLBACK_POLYGON_SMOOTH, "i915 polygon smooth" },
{ I915_FALLBACK_POINT_SMOOTH, "i915 point smooth" },
{ 0, NULL }
};
static const char *
getFallbackString(GLuint bit)
{
int i;
for (i = 0; fallbackStrings[i].bit; i++) {
if (fallbackStrings[i].bit == bit)
return fallbackStrings[i].str;
}
return "unknown fallback bit";
}
void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )
{
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = intel->Fallback;
if (mode) {
intel->Fallback |= bit;
if (oldfallback == 0) {
intelFlush(ctx);
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "ENTER FALLBACK 0x%x: %s\n",
bit, getFallbackString(bit));
_swsetup_Wakeup( ctx );
intel->RenderIndex = ~0;
}
}
else {
intel->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
if (INTEL_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "LEAVE FALLBACK 0x%x: %s\n",
bit, getFallbackString(bit));
tnl->Driver.Render.Start = intelRenderStart;
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
tnl->Driver.Render.Finish = intelRenderFinish;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
_tnl_install_attrs( ctx,
intel->vertex_attrs,
intel->vertex_attr_count,
intel->ViewportMatrix.m, 0 );
intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
}
}
}
/**********************************************************************/
/* Initialization. */
/**********************************************************************/
void intelInitTriFuncs( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
static int firsttime = 1;
if (firsttime) {
init_rast_tab();
firsttime = 0;
}
tnl->Driver.RunPipeline = intelRunPipeline;
tnl->Driver.Render.Start = intelRenderStart;
tnl->Driver.Render.Finish = intelRenderFinish;
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
}

View File

@ -1,46 +0,0 @@
/**************************************************************************
*
* Copyright 2003 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, 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTELTRIS_INC
#define INTELTRIS_INC
#include "mtypes.h"
#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_DD_NEW_TRI_OFFSET | \
_DD_NEW_TRI_STIPPLE | \
_NEW_PROGRAM | \
_NEW_POLYGONSTIPPLE)
extern void intelInitTriFuncs( GLcontext *ctx );
extern void intelPrintRenderState( const char *msg, GLuint state );
extern void intelChooseRenderState( GLcontext *ctx );
#endif

View File

@ -1,212 +0,0 @@
/**************************************************************************
Copyright 2001 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
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.
**************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */
#ifndef _I830_COMMON_H_
#define _I830_COMMON_H_
#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */
#define I830_LOG_MIN_TEX_REGION_SIZE 14
/* Driver specific DRM command indices
* NOTE: these are not OS specific, but they are driver specific
*/
#define DRM_I830_INIT 0x00
#define DRM_I830_FLUSH 0x01
#define DRM_I830_FLIP 0x02
#define DRM_I830_BATCHBUFFER 0x03
#define DRM_I830_IRQ_EMIT 0x04
#define DRM_I830_IRQ_WAIT 0x05
#define DRM_I830_GETPARAM 0x06
#define DRM_I830_SETPARAM 0x07
#define DRM_I830_ALLOC 0x08
#define DRM_I830_FREE 0x09
#define DRM_I830_INIT_HEAP 0x0a
#define DRM_I830_CMDBUFFER 0x0b
#define DRM_I830_DESTROY_HEAP 0x0c
typedef struct {
enum {
I830_INIT_DMA = 0x01,
I830_CLEANUP_DMA = 0x02,
I830_RESUME_DMA = 0x03
} func;
unsigned int mmio_offset;
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
unsigned int ring_size;
unsigned int front_offset;
unsigned int back_offset;
unsigned int depth_offset;
unsigned int w;
unsigned int h;
unsigned int pitch;
unsigned int pitch_bits;
unsigned int back_pitch;
unsigned int depth_pitch;
unsigned int cpp;
unsigned int chipset;
} drmI830Init;
typedef struct {
drmTextureRegion texList[I830_NR_TEX_REGIONS+1];
int last_upload; /* last time texture was uploaded */
int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
int ctxOwner; /* last context to upload state */
int texAge;
int pf_enabled; /* is pageflipping allowed? */
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
int width, height; /* screen size in pixels */
drm_handle_t front_handle;
int front_offset;
int front_size;
drm_handle_t back_handle;
int back_offset;
int back_size;
drm_handle_t depth_handle;
int depth_offset;
int depth_size;
drm_handle_t tex_handle;
int tex_offset;
int tex_size;
int log_tex_granularity;
int pitch;
int rotation; /* 0, 90, 180 or 270 */
int rotated_offset;
int rotated_size;
int rotated_pitch;
int virtualX, virtualY;
unsigned int front_tiled;
unsigned int back_tiled;
unsigned int depth_tiled;
unsigned int rotated_tiled;
unsigned int rotated2_tiled;
int planeA_x;
int planeA_y;
int planeA_w;
int planeA_h;
int planeB_x;
int planeB_y;
int planeB_w;
int planeB_h;
} drmI830Sarea;
/* Flags for perf_boxes
*/
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
#define I830_BOX_FLIP 0x2 /* populated by kernel */
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
typedef struct {
int start; /* agp offset */
int used; /* nr bytes in use */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/
int num_cliprects; /* mulitpass with multiple cliprects? */
drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */
} drmI830BatchBuffer;
typedef struct {
char *buf; /* agp offset */
int sz; /* nr bytes in use */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/
int num_cliprects; /* mulitpass with multiple cliprects? */
drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */
} drmI830CmdBuffer;
typedef struct {
int *irq_seq;
} drmI830IrqEmit;
typedef struct {
int irq_seq;
} drmI830IrqWait;
typedef struct {
int param;
int *value;
} drmI830GetParam;
#define I830_PARAM_IRQ_ACTIVE 1
#define I830_PARAM_ALLOW_BATCHBUFFER 2
typedef struct {
int param;
int value;
} drmI830SetParam;
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
#define I830_SETPARAM_ALLOW_BATCHBUFFER 3
/* A memory manager for regions of shared memory:
*/
#define I830_MEM_REGION_AGP 1
typedef struct {
int region;
int alignment;
int size;
int *region_offset; /* offset from start of fb or agp */
} drmI830MemAlloc;
typedef struct {
int region;
int region_offset;
} drmI830MemFree;
typedef struct {
int region;
int size;
int start;
} drmI830MemInitHeap;
typedef struct {
int region;
} drmI830MemDestroyHeap;
#endif /* _I830_DRM_H_ */

View File

@ -1,73 +0,0 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */
#ifndef _I830_DRI_H
#define _I830_DRI_H
#include "xf86drm.h"
#include "i830_common.h"
#define I830_MAX_DRAWABLES 256
#define I830_MAJOR_VERSION 1
#define I830_MINOR_VERSION 3
#define I830_PATCHLEVEL 0
#define I830_REG_SIZE 0x80000
typedef struct _I830DRIRec {
drm_handle_t regs;
drmSize regsSize;
drmSize backbufferSize;
drm_handle_t backbuffer;
drmSize depthbufferSize;
drm_handle_t depthbuffer;
drmSize rotatedSize;
drm_handle_t rotatedbuffer;
drm_handle_t textures;
int textureSize;
drm_handle_t agp_buffers;
drmSize agp_buf_size;
int deviceID;
int width;
int height;
int mem;
int cpp;
int bitsPerPixel;
int fbOffset;
int fbStride;
int backOffset;
int backPitch;
int depthOffset;
int depthPitch;
int rotatedOffset;
int rotatedPitch;
int logTextureGranularity;
int textureOffset;
int irq;
int sarea_priv_offset;
} I830DRIRec, *I830DRIPtr;
typedef struct {
/* Nothing here yet */
int dummy;
} I830ConfigPrivRec, *I830ConfigPrivPtr;
typedef struct {
/* Nothing here yet */
int dummy;
} I830DRIContextRec, *I830DRIContextPtr;
#endif

View File

@ -1,328 +0,0 @@
#ifndef _INTEL_H_
#define _INTEL_H_
#include "xf86drm.h" /* drm_handle_t, etc */
/* Intel */
#ifndef PCI_CHIP_I810
#define PCI_CHIP_I810 0x7121
#define PCI_CHIP_I810_DC100 0x7123
#define PCI_CHIP_I810_E 0x7125
#define PCI_CHIP_I815 0x1132
#define PCI_CHIP_I810_BRIDGE 0x7120
#define PCI_CHIP_I810_DC100_BRIDGE 0x7122
#define PCI_CHIP_I810_E_BRIDGE 0x7124
#define PCI_CHIP_I815_BRIDGE 0x1130
#endif
#define PCI_CHIP_845_G 0x2562
#define PCI_CHIP_I830_M 0x3577
#ifndef PCI_CHIP_I855_GM
#define PCI_CHIP_I855_GM 0x3582
#define PCI_CHIP_I855_GM_BRIDGE 0x3580
#endif
#ifndef PCI_CHIP_I865_G
#define PCI_CHIP_I865_G 0x2572
#define PCI_CHIP_I865_G_BRIDGE 0x2570
#endif
#ifndef PCI_CHIP_I915_G
#define PCI_CHIP_I915_G 0x2582
#define PCI_CHIP_I915_G_BRIDGE 0x2580
#endif
#ifndef PCI_CHIP_I915_GM
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I915_GM_BRIDGE 0x2590
#endif
#ifndef PCI_CHIP_E7221_G
#define PCI_CHIP_E7221_G 0x258A
/* Same as I915_G_BRIDGE */
#define PCI_CHIP_E7221_G_BRIDGE 0x2580
#endif
#ifndef PCI_CHIP_I945_G
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_G_BRIDGE 0x2770
#endif
#ifndef PCI_CHIP_I945_GM
#define PCI_CHIP_I945_GM 0x27A2
#define PCI_CHIP_I945_GM_BRIDGE 0x27A0
#endif
#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \
pI810->Chipset == PCI_CHIP_I810_DC100 || \
pI810->Chipset == PCI_CHIP_I810_E)
#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815)
#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M)
#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G)
#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM)
#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G)
#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G)
#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM)
#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G)
#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM)
#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
#define I830_GMCH_CTRL 0x52
#define I830_GMCH_GMS_MASK 0x70
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
#define I830_GMCH_GMS_STOLEN_1024 0x30
#define I830_GMCH_GMS_STOLEN_8192 0x40
#define I855_GMCH_GMS_MASK (0x7 << 4)
#define I855_GMCH_GMS_DISABLED 0x00
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
typedef unsigned char Bool;
#define TRUE 1
#define FALSE 0
#define PIPE_NONE 0<<0
#define PIPE_CRT 1<<0
#define PIPE_TV 1<<1
#define PIPE_DFP 1<<2
#define PIPE_LFP 1<<3
#define PIPE_CRT2 1<<4
#define PIPE_TV2 1<<5
#define PIPE_DFP2 1<<6
#define PIPE_LFP2 1<<7
typedef struct _I830MemPool *I830MemPoolPtr;
typedef struct _I830MemRange *I830MemRangePtr;
typedef struct _I830MemRange {
long Start;
long End;
long Size;
unsigned long Physical;
unsigned long Offset; /* Offset of AGP-allocated portion */
unsigned long Alignment;
drm_handle_t Key;
unsigned long Pitch; // add pitch
I830MemPoolPtr Pool;
} I830MemRange;
typedef struct _I830MemPool {
I830MemRange Total;
I830MemRange Free;
I830MemRange Fixed;
I830MemRange Allocated;
} I830MemPool;
typedef struct {
int tail_mask;
I830MemRange mem;
unsigned char *virtual_start;
int head;
int tail;
int space;
} I830RingBuffer;
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
unsigned int bios_version;
/* These are set in PreInit and never changed. */
long FbMapSize;
long TotalVideoRam;
I830MemRange StolenMemory; /* pre-allocated memory */
long BIOSMemorySize; /* min stolen pool size */
int BIOSMemSizeLoc;
/* These change according to what has been allocated. */
long FreeMemory;
I830MemRange MemoryAperture;
I830MemPool StolenPool;
long allocatedMemory;
/* Regions allocated either from the above pools, or from agpgart. */
/* for single and dual head configurations */
I830MemRange FrontBuffer;
I830MemRange FrontBuffer2;
I830MemRange Scratch;
I830MemRange Scratch2;
I830RingBuffer *LpRing;
I830MemRange BackBuffer;
I830MemRange DepthBuffer;
I830MemRange TexMem;
int TexGranularity;
I830MemRange ContextMem;
int drmMinor;
Bool have3DWindows;
Bool NeedRingBufferLow;
Bool allowPageFlip;
Bool disableTiling;
int Chipset;
unsigned long LinearAddr;
unsigned long MMIOAddr;
drmSize registerSize; /**< \brief MMIO register map size */
drm_handle_t registerHandle; /**< \brief MMIO register map handle */
// IOADDRESS ioBase;
int irq; /**< \brief IRQ number */
int GttBound;
drm_handle_t ring_map;
unsigned int Fence[8];
} I830Rec;
/*
* 12288 is set as the maximum, chosen because it is enough for
* 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
*/
#define I830_MAXIMUM_VBIOS_MEM 12288
#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
/* Flags for memory allocation function */
#define FROM_ANYWHERE 0x00000000
#define FROM_POOL_ONLY 0x00000001
#define FROM_NEW_ONLY 0x00000002
#define FROM_MASK 0x0000000f
#define ALLOCATE_AT_TOP 0x00000010
#define ALLOCATE_AT_BOTTOM 0x00000020
#define FORCE_GAPS 0x00000040
#define NEED_PHYSICAL_ADDR 0x00000100
#define ALIGN_BOTH_ENDS 0x00000200
#define FORCE_LOW 0x00000400
#define ALLOC_NO_TILING 0x00001000
#define ALLOC_INITIAL 0x00002000
#define ALLOCATE_DRY_RUN 0x80000000
/* Chipset registers for VIDEO BIOS memory RW access */
#define _855_DRAM_RW_CONTROL 0x58
#define _845_DRAM_RW_CONTROL 0x90
#define DRAM_WRITE 0x33330000
#define KB(x) ((x) * 1024)
#define MB(x) ((x) * KB(1024))
#define GTT_PAGE_SIZE KB(4)
#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y))
#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE)
#define ROUND_TO_MB(x) ROUND_TO((x), MB(1))
#define PRIMARY_RINGBUFFER_SIZE KB(128)
/* Ring buffer registers, p277, overview p19
*/
#define LP_RING 0x2030
#define HP_RING 0x2040
#define RING_TAIL 0x00
#define TAIL_ADDR 0x000FFFF8
#define I830_TAIL_MASK 0x001FFFF8
#define RING_HEAD 0x04
#define HEAD_WRAP_COUNT 0xFFE00000
#define HEAD_WRAP_ONE 0x00200000
#define HEAD_ADDR 0x001FFFFC
#define I830_HEAD_MASK 0x001FFFFC
#define RING_START 0x08
#define START_ADDR 0x03FFFFF8
#define I830_RING_START_MASK 0xFFFFF000
#define RING_LEN 0x0C
#define RING_NR_PAGES 0x001FF000
#define I830_RING_NR_PAGES 0x001FF000
#define RING_REPORT_MASK 0x00000006
#define RING_REPORT_64K 0x00000002
#define RING_REPORT_128K 0x00000004
#define RING_NO_REPORT 0x00000000
#define RING_VALID_MASK 0x00000001
#define RING_VALID 0x00000001
#define RING_INVALID 0x00000000
/* Fence/Tiling ranges [0..7]
*/
#define FENCE 0x2000
#define FENCE_NR 8
#define I915G_FENCE_START_MASK 0x0ff00000
#define I830_FENCE_START_MASK 0x07f80000
#define FENCE_START_MASK 0x03F80000
#define FENCE_X_MAJOR 0x00000000
#define FENCE_Y_MAJOR 0x00001000
#define FENCE_SIZE_MASK 0x00000700
#define FENCE_SIZE_512K 0x00000000
#define FENCE_SIZE_1M 0x00000100
#define FENCE_SIZE_2M 0x00000200
#define FENCE_SIZE_4M 0x00000300
#define FENCE_SIZE_8M 0x00000400
#define FENCE_SIZE_16M 0x00000500
#define FENCE_SIZE_32M 0x00000600
#define FENCE_SIZE_64M 0x00000700
#define I915G_FENCE_SIZE_1M 0x00000000
#define I915G_FENCE_SIZE_2M 0x00000100
#define I915G_FENCE_SIZE_4M 0x00000200
#define I915G_FENCE_SIZE_8M 0x00000300
#define I915G_FENCE_SIZE_16M 0x00000400
#define I915G_FENCE_SIZE_32M 0x00000500
#define I915G_FENCE_SIZE_64M 0x00000600
#define I915G_FENCE_SIZE_128M 0x00000700
#define FENCE_PITCH_1 0x00000000
#define FENCE_PITCH_2 0x00000010
#define FENCE_PITCH_4 0x00000020
#define FENCE_PITCH_8 0x00000030
#define FENCE_PITCH_16 0x00000040
#define FENCE_PITCH_32 0x00000050
#define FENCE_PITCH_64 0x00000060
#define FENCE_VALID 0x00000001
#include <mmio.h>
# define MMIO_IN8(base, offset) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset))
# define MMIO_IN32(base, offset) \
read_MMIO_LE32(base, offset)
# define MMIO_OUT8(base, offset, val) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val)
# define MMIO_OUT32(base, offset, val) \
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val)
/* Memory mapped register access macros */
#define INREG8(addr) MMIO_IN8(MMIO, addr)
#define INREG(addr) MMIO_IN32(MMIO, addr)
#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val)
#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val)
#define DSPABASE 0x70184
#endif

File diff suppressed because it is too large Load Diff