Remove the old i915 driver now that i915tex works without TTM.
This commit is contained in:
parent
439fa79578
commit
8fba8d2018
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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)®_TYPE_MASK)
|
||||
#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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__);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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 = ®ion_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
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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 */
|
||||
};
|
|
@ -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
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue