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