diff options
Diffstat (limited to 'src/mesa/main')
29 files changed, 472 insertions, 156 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 98dfbb105f..bbc5933ab9 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -119,6 +119,12 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* use indices in the buffer object */ GLuint indexBytes; + if (!ctx->Array.ElementArrayBufferObj->Size) { + _mesa_warning(ctx, + "glDrawElements called with empty array elements buffer"); + return GL_FALSE; + } + if (type == GL_UNSIGNED_INT) { indexBytes = count * sizeof(GLuint); } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 918e87246f..190e6ab564 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -38,6 +38,13 @@ #include "bufferobj.h" +#ifdef FEATURE_OES_mapbuffer +#define DEFAULT_ACCESS GL_WRITE_ONLY; +#else +#define DEFAULT_ACCESS GL_READ_WRITE; +#endif + + /** * Get the buffer object bound to the specified target in a GL context. * @@ -255,7 +262,7 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj, obj->RefCount = 1; obj->Name = name; obj->Usage = GL_STATIC_DRAW_ARB; - obj->Access = GL_READ_WRITE_ARB; + obj->Access = DEFAULT_ACCESS; } @@ -664,8 +671,8 @@ _mesa_map_drawpix_pbo(GLcontext *ctx, * \sa _mesa_unmap_bitmap_pbo */ void -_mesa_unmap_drapix_pbo(GLcontext *ctx, - const struct gl_pixelstore_attrib *unpack) +_mesa_unmap_drawpix_pbo(GLcontext *ctx, + const struct gl_pixelstore_attrib *unpack) { if (unpack->BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, @@ -1065,7 +1072,7 @@ _mesa_UnmapBufferARB(GLenum target) status = ctx->Driver.UnmapBuffer( ctx, target, bufObj ); } - bufObj->Access = GL_READ_WRITE_ARB; /* initial value, OK? */ + bufObj->Access = DEFAULT_ACCESS; bufObj->Pointer = NULL; return status; diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 163fe241aa..3c08f0083c 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -103,9 +103,8 @@ _mesa_map_drawpix_pbo(GLcontext *ctx, const GLvoid *pixels); extern void -_mesa_unmap_drapix_pbo(GLcontext *ctx, - const struct gl_pixelstore_attrib *unpack); - +_mesa_unmap_drawpix_pbo(GLcontext *ctx, + const struct gl_pixelstore_attrib *unpack); extern void * _mesa_map_readpix_pbo(GLcontext *ctx, diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index b23d2f612b..5dd85de272 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -419,7 +419,7 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, } } - ctx->NewState |= _NEW_COLOR; + ctx->NewState |= _NEW_BUFFERS; } @@ -494,6 +494,7 @@ _mesa_ReadBuffer(GLenum buffer) /* OK, all error checking has been completed now */ _mesa_readbuffer(ctx, buffer, srcBuffer); + ctx->NewState |= _NEW_BUFFERS; /* * Call device driver function. diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index f1f12b8a0e..e29964a1e8 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -176,13 +176,11 @@ /** For GL_ARB_fragment_program */ /*@{*/ #define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0 -#define MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS 48 -#define MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS 24 -#define MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS 4 /*@}*/ /** For any program target/extension */ /*@{*/ +#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024) #define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */ #define MAX_PROGRAM_ENV_PARAMS 128 #define MAX_PROGRAM_MATRICES 8 diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index a41cb42952..61c0861cbd 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -145,9 +145,7 @@ #include "glapi/glthread.h" #include "glapi/glapioffsets.h" #include "glapi/glapitable.h" -#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program #include "shader/program.h" -#endif #include "shader/shader_api.h" #if FEATURE_ATI_fragment_shader #include "shader/atifragshader.h" @@ -186,9 +184,11 @@ GLfloat _mesa_ubyte_to_float_color_tab[256]; * We have to finish any pending rendering. */ void -_mesa_notifySwapBuffers(__GLcontext *gc) +_mesa_notifySwapBuffers(__GLcontext *ctx) { - FLUSH_VERTICES( gc, 0 ); + if (ctx->Driver.Flush) { + ctx->Driver.Flush(ctx); + } } @@ -611,6 +611,7 @@ delete_program_cb(GLuint id, void *data, void *userData) ctx->Driver.DeleteProgram(ctx, prog); } +#if FEATURE_ATI_fragment_shader /** * Callback for deleting an ATI fragment shader object. * Called by _mesa_HashDeleteAll(). @@ -622,6 +623,7 @@ delete_fragshader_cb(GLuint id, void *data, void *userData) GLcontext *ctx = (GLcontext *) userData; _mesa_delete_ati_fragment_shader(ctx, shader); } +#endif /** * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll(). @@ -712,7 +714,6 @@ delete_renderbuffer_cb(GLuint id, void *data, void *userData) } - /** * Deallocate a shared state object and all children structures. * @@ -818,11 +819,33 @@ _mesa_init_current(GLcontext *ctx) /** - * Init vertex/fragment program native limits from logical limits. + * Init vertex/fragment program limits. + * Important: drivers should override these with actual limits. */ static void -init_natives(struct gl_program_constants *prog) +init_program_limits(GLenum type, struct gl_program_constants *prog) { + prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTemps = MAX_PROGRAM_TEMPS; + prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; + prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; + prog->MaxUniformComponents = 4 * MAX_UNIFORMS; + + if (type == GL_VERTEX_PROGRAM_ARB) { + prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; + prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; + prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; + } + else { + prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; + prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; + prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; + } + + /* copy the above limits to init native limits */ prog->MaxNativeInstructions = prog->MaxInstructions; prog->MaxNativeAluInstructions = prog->MaxAluInstructions; prog->MaxNativeTexInstructions = prog->MaxTexInstructions; @@ -884,33 +907,10 @@ _mesa_init_constants(GLcontext *ctx) ctx->Const.MaxViewportWidth = MAX_WIDTH; ctx->Const.MaxViewportHeight = MAX_HEIGHT; #if FEATURE_ARB_vertex_program - ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS; - ctx->Const.VertexProgram.MaxAluInstructions = 0; - ctx->Const.VertexProgram.MaxTexInstructions = 0; - ctx->Const.VertexProgram.MaxTexIndirections = 0; - ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; - ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS; - ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; - ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; - ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; - ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; - init_natives(&ctx->Const.VertexProgram); + init_program_limits(GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); #endif - #if FEATURE_ARB_fragment_program - ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS; - ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS; - ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS; - ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS; - ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; - ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS; - ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; - ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; - ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; - ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; - ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; - init_natives(&ctx->Const.FragmentProgram); + init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); #endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; @@ -1063,6 +1063,7 @@ init_attrib_groups(GLcontext *ctx) /* Miscellaneous */ ctx->NewState = _NEW_ALL; ctx->ErrorValue = (GLenum) GL_NO_ERROR; + ctx->varying_vp_inputs = ~0; return GL_TRUE; } @@ -1162,7 +1163,7 @@ _mesa_initialize_context(GLcontext *ctx, const struct dd_function_table *driverFunctions, void *driverContext) { - ASSERT(driverContext); + /*ASSERT(driverContext);*/ assert(driverFunctions->NewTextureObject); assert(driverFunctions->FreeTexImageData); @@ -1267,7 +1268,7 @@ _mesa_create_context(const GLvisual *visual, GLcontext *ctx; ASSERT(visual); - ASSERT(driverContext); + /*ASSERT(driverContext);*/ ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext)); if (!ctx) @@ -1315,7 +1316,9 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); +#if FEATURE_attrib_stack _mesa_free_attrib_data(ctx); +#endif _mesa_free_lighting_data( ctx ); #if FEATURE_evaluators _mesa_free_eval_data( ctx ); @@ -1632,7 +1635,22 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, * or not bound to a user-created FBO. */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { + /* KW: merge conflict here, revisit. + */ + /* fix up the fb fields - these will end up wrong otherwise + * if the DRIdrawable changes, and everything relies on them. + * This is a bit messy (same as needed in _mesa_BindFramebufferEXT) + */ + unsigned int i; + GLenum buffers[MAX_DRAW_BUFFERS]; + _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); + + for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) { + buffers[i] = newCtx->Color.DrawBuffer[i]; + } + + _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, buffers, NULL); } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index ac97bc1ff9..13cfa0e756 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -153,7 +153,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, return; } - if (!ctx->Current.RasterPosValid) { + if (!ctx->Current.RasterPosValid || width ==0 || height == 0) { return; } @@ -218,7 +218,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, if (ctx->RenderMode == GL_RENDER) { /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ - const GLfloat epsilon = (const GLfloat)0.0001; + const GLfloat epsilon = 0.0001F; GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig); GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig); diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index e0483a72e8..248df1badc 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -929,6 +929,7 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) break; /* GL_MESA_program_debug */ +#if FEATURE_MESA_program_debug case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: CHECK_EXTENSION(MESA_program_debug, cap); ctx->FragmentProgram.CallbackEnabled = state; @@ -937,6 +938,7 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) CHECK_EXTENSION(MESA_program_debug, cap); ctx->VertexProgram.CallbackEnabled = state; break; +#endif #if FEATURE_ATI_fragment_shader case GL_FRAGMENT_SHADER_ATI: @@ -1378,12 +1380,15 @@ _mesa_IsEnabled( GLenum cap ) return ctx->Depth.BoundsTest; /* GL_MESA_program_debug */ +#if FEATURE_MESA_program_debug case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: CHECK_EXTENSION(MESA_program_debug); return ctx->FragmentProgram.CallbackEnabled; case GL_VERTEX_PROGRAM_CALLBACK_MESA: CHECK_EXTENSION(MESA_program_debug); return ctx->VertexProgram.CallbackEnabled; +#endif + #if FEATURE_ATI_fragment_shader case GL_FRAGMENT_SHADER_ATI: CHECK_EXTENSION(ATI_fragment_shader); diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index de75325f15..95bf1165f4 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -86,7 +86,7 @@ static const struct { { OFF, "GL_EXT_blend_logic_op", F(EXT_blend_logic_op) }, { OFF, "GL_EXT_blend_minmax", F(EXT_blend_minmax) }, { OFF, "GL_EXT_blend_subtract", F(EXT_blend_subtract) }, - { ON, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) }, + { OFF, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) }, { OFF, "GL_EXT_cull_vertex", F(EXT_cull_vertex) }, { ON, "GL_EXT_compiled_vertex_array", F(EXT_compiled_vertex_array) }, { OFF, "GL_EXT_convolution", F(EXT_convolution) }, diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 4c92d1fb5a..dd06327972 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -173,7 +173,7 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); if (ctx->Driver.FinishRenderTexture) { - /* tell driver we're done rendering to this texobj */ + /* tell driver that we're done rendering to this texture. */ ctx->Driver.FinishRenderTexture(ctx, att); } _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index ebc02940de..ec0a5e3896 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -47,17 +47,17 @@ struct state_key { + unsigned light_color_material_mask:12; + unsigned light_material_mask:12; unsigned light_global_enabled:1; unsigned light_local_viewer:1; unsigned light_twoside:1; unsigned light_color_material:1; - unsigned light_color_material_mask:12; - unsigned light_material_mask:12; unsigned material_shininess_is_zero:1; - unsigned need_eye_coords:1; unsigned normalize:1; unsigned rescale_normals:1; + unsigned fog_source_is_depth:1; unsigned tnl_do_vertex_fog:1; unsigned separate_specular:1; @@ -67,6 +67,8 @@ struct state_key { unsigned texture_enabled_global:1; unsigned fragprog_inputs_read:12; + unsigned varying_vp_inputs; + struct { unsigned light_enabled:1; unsigned light_eyepos3_is_zero:1; @@ -193,6 +195,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) key->need_eye_coords = ctx->_NeedEyeCoords; key->fragprog_inputs_read = fp->Base.InputsRead; + key->varying_vp_inputs = ctx->varying_vp_inputs; if (ctx->RenderMode == GL_FEEDBACK) { /* make sure the vertprog emits color and tex0 */ @@ -448,14 +451,46 @@ static void release_temps( struct tnl_program *p ) } +static struct ureg register_param5(struct tnl_program *p, + GLint s0, + GLint s1, + GLint s2, + GLint s3, + GLint s4) +{ + gl_state_index tokens[STATE_LENGTH]; + GLint idx; + tokens[0] = s0; + tokens[1] = s1; + tokens[2] = s2; + tokens[3] = s3; + tokens[4] = s4; + idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); + return make_ureg(PROGRAM_STATE_VAR, idx); +} + + +#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) +#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) +#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) +#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) + + /** * \param input one of VERT_ATTRIB_x tokens. */ static struct ureg register_input( struct tnl_program *p, GLuint input ) { - p->program->Base.InputsRead |= (1<<input); - return make_ureg(PROGRAM_INPUT, input); + /* Material attribs are passed here as inputs >= 32 + */ + if (input >= 32 || (p->state->varying_vp_inputs & (1<<input))) { + p->program->Base.InputsRead |= (1<<input); + return make_ureg(PROGRAM_INPUT, input); + } + else { + return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, input ); + } } /** @@ -504,31 +539,6 @@ static struct ureg get_identity_param( struct tnl_program *p ) return p->identity; } -static struct ureg register_param5(struct tnl_program *p, - GLint s0, - GLint s1, - GLint s2, - GLint s3, - GLint s4) -{ - gl_state_index tokens[STATE_LENGTH]; - GLint idx; - tokens[0] = s0; - tokens[1] = s1; - tokens[2] = s2; - tokens[3] = s3; - tokens[4] = s4; - idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); - return make_ureg(PROGRAM_STATE_VAR, idx); -} - - -#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) -#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) -#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) -#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) - - static void register_matrix_param5( struct tnl_program *p, GLint s0, /* modelview, projection, etc */ GLint s1, /* texture matrix number */ diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 1d0f178dc4..d69c7bbb21 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -64,22 +64,33 @@ #include <stdarg.h> -/* Get typedefs for uintptr_t and friends */ -#if defined(__MINGW32__) || defined(__NetBSD__) -# include <stdint.h> -#elif defined(_WIN32) -# include <BaseTsd.h> -# if _MSC_VER == 1200 - typedef UINT_PTR uintptr_t; -# endif -#elif defined(__INTERIX) -/* Interix 3.x has a gcc that shadows this. */ -# ifndef _UINTPTR_T_DEFINED - typedef unsigned long uintptr_t; -# define _UINTPTR_T_DEFINED +/* Get standard integer types */ +#if defined(_MSC_VER) + + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; +# ifndef __eglplatform_h_ + typedef __int32 int32_t; +# endif + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + +# if defined(_WIN64) + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +# else + typedef __int32 intptr_t; + typedef unsigned __int32 uintptr_t; # endif + +# define INT64_C(__val) __val##i64 +# define UINT64_C(__val) __val##ui64 + #else -# include <inttypes.h> +# include <stdint.h> #endif diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 4551b4a3b5..d3282d42e9 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -5119,7 +5119,7 @@ _mesa_clip_copytexsubimage(const GLcontext *ctx, const struct gl_framebuffer *fb = ctx->ReadBuffer; const GLint srcX0 = *srcX, srcY0 = *srcY; - if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, + if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height, srcX, srcY, width, height)) { *destX = *destX + *srcX - srcX0; *destY = *destY + *srcY - srcY0; diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 13cb84ca4b..6cfd7ccc72 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -557,7 +557,7 @@ _mesa_pow(double x, double y) * Find the first bit set in a word. */ int -_mesa_ffs(int i) +_mesa_ffs(int32_t i) { #if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__) register int bit = 0; @@ -594,11 +594,7 @@ _mesa_ffs(int i) * if no bits set. */ int -#ifdef __MINGW32__ -_mesa_ffsll(long val) -#else -_mesa_ffsll(long long val) -#endif +_mesa_ffsll(int64_t val) { #ifdef ffsll return ffsll(val); @@ -607,11 +603,11 @@ _mesa_ffsll(long long val) assert(sizeof(val) == 8); - bit = _mesa_ffs(val); + bit = _mesa_ffs((int32_t)val); if (bit != 0) return bit; - bit = _mesa_ffs(val >> 32); + bit = _mesa_ffs((int32_t)(val >> 32)); if (bit != 0) return 32 + bit; @@ -938,12 +934,10 @@ _mesa_sprintf( char *str, const char *fmt, ... ) void _mesa_printf( const char *fmtString, ... ) { - char s[MAXSTRING]; va_list args; va_start( args, fmtString ); - vsnprintf(s, MAXSTRING, fmtString, args); + vfprintf(stderr, fmtString, args); va_end( args ); - fprintf(stderr,"%s", s); } /** Wrapper around vsprintf() */ diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 453151ce0b..bab0042071 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -708,14 +708,10 @@ extern double _mesa_pow(double x, double y); extern int -_mesa_ffs(int i); +_mesa_ffs(int32_t i); extern int -#ifdef __MINGW32__ -_mesa_ffsll(long i); -#else -_mesa_ffsll(long long i); -#endif +_mesa_ffsll(int64_t i); extern unsigned int _mesa_bitcount(unsigned int n); diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 10ee088a2d..d4db960f1b 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1367,6 +1367,7 @@ _mesa_init_lighting( GLcontext *ctx ) /* Miscellaneous */ ctx->Light._NeedEyeCoords = GL_FALSE; ctx->_NeedEyeCoords = GL_FALSE; + ctx->_ForceEyeCoords = GL_FALSE; ctx->_ModelViewInvScale = 1.0; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 9b40d8fb6c..556b4ed016 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -126,6 +126,8 @@ struct gl_program_cache; struct gl_texture_format; struct gl_texture_image; struct gl_texture_object; +struct st_context; +struct pipe_surface; typedef struct __GLcontextRec GLcontext; typedef struct __GLcontextModesRec GLvisual; typedef struct gl_framebuffer GLframebuffer; @@ -1567,7 +1569,6 @@ struct gl_texture_attrib struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; - /** Proxy texture objects */ struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; /** GL_EXT_shared_texture_palette */ @@ -1989,6 +1990,8 @@ struct gl_vertex_program_state GLboolean CallbackEnabled; GLuint CurrentPosition; #endif + + GLboolean _Overriden; }; @@ -2262,6 +2265,7 @@ struct gl_renderbuffer GLubyte IndexBits; GLubyte DepthBits; GLubyte StencilBits; + GLubyte Samples; /**< Number of samples - 0 if not multisampled */ GLvoid *Data; /**< This may not be used by some kinds of RBs */ /* Used to wrap one renderbuffer around another: */ @@ -2722,6 +2726,7 @@ struct gl_matrix_stack #define _NEW_MULTISAMPLE 0x2000000 /**< __GLcontextRec::Multisample */ #define _NEW_TRACK_MATRIX 0x4000000 /**< __GLcontextRec::VertexProgram */ #define _NEW_PROGRAM 0x8000000 /**< __GLcontextRec::VertexProgram */ +#define _NEW_CURRENT_ATTRIB 0x10000000 /**< __GLcontextRec::Current */ #define _NEW_ALL ~0 /*@}*/ @@ -3049,6 +3054,8 @@ struct __GLcontextRec GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ + /** \name Derived state */ /*@{*/ /** Bitwise-or of DD_* flags. Note that this bitfield may be used before @@ -3094,7 +3101,7 @@ struct __GLcontextRec void *swsetup_context; void *swtnl_context; void *swtnl_im; - void *acache_context; + struct st_context *st; void *aelt_context; /*@}*/ }; diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index 6f1d7c3960..3c37d05b40 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -1199,7 +1199,8 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, if (width > 0 && height > 0) { /* allocate new buffer storage */ - rb->Data = _mesa_malloc(width * height * pixelSize); + rb->Data = malloc(width * height * pixelSize); + if (rb->Data == NULL) { rb->Width = 0; rb->Height = 0; diff --git a/src/mesa/main/sources b/src/mesa/main/sources index eb8cd900ee..468121bd1d 100644 --- a/src/mesa/main/sources +++ b/src/mesa/main/sources @@ -78,7 +78,6 @@ vsnprintf.c MESA_MAIN_HEADERS = \ accum.h \ api_arrayelt.h \ -api_eval.h \ api_exec.h \ api_loopback.h \ api_noop.h \ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index e87a62f59d..0d452fd879 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -439,6 +439,9 @@ _mesa_update_state_locked( GLcontext *ctx ) GLbitfield new_state = ctx->NewState; GLbitfield prog_flags = _NEW_PROGRAM; + if (new_state == _NEW_CURRENT_ATTRIB) + goto out; + if (MESA_VERBOSE & VERBOSE_STATE) _mesa_print_state("_mesa_update_state", new_state); @@ -448,7 +451,7 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) _mesa_update_texture( ctx, new_state ); - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) + if (new_state & _NEW_BUFFERS) _mesa_update_framebuffer(ctx); if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) @@ -502,10 +505,13 @@ _mesa_update_state_locked( GLcontext *ctx ) _mesa_update_tnl_spaces( ctx, new_state ); if (ctx->FragmentProgram._MaintainTexEnvProgram) { - prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); + prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE_MATRIX | _NEW_LIGHT | + _NEW_RENDERMODE | + _NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); } if (ctx->VertexProgram._MaintainTnlProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | + _NEW_RENDERMODE | _NEW_TRANSFORM | _NEW_POINT | _NEW_FOG | _NEW_LIGHT | _MESA_NEW_NEED_EYE_COORDS); @@ -524,6 +530,7 @@ _mesa_update_state_locked( GLcontext *ctx ) * Set ctx->NewState to zero to avoid recursion if * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) */ + out: new_state = ctx->NewState; ctx->NewState = 0; ctx->Driver.UpdateState(ctx, new_state); @@ -540,3 +547,59 @@ _mesa_update_state( GLcontext *ctx ) _mesa_update_state_locked(ctx); _mesa_unlock_context_textures(ctx); } + + + + +/** + * Want to figure out which fragment program inputs are actually + * constant/current values from ctx->Current. These should be + * referenced as a tracked state variable rather than a fragment + * program input, to save the overhead of putting a constant value in + * every submitted vertex, transferring it to hardware, interpolating + * it across the triangle, etc... + * + * When there is a VP bound, just use vp->outputs. But when we're + * generating vp from fixed function state, basically want to + * calculate: + * + * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | + * potential_vp_outputs ) + * + * Where potential_vp_outputs is calculated by looking at enabled + * texgen, etc. + * + * The generated fragment program should then only declare inputs that + * may vary or otherwise differ from the ctx->Current values. + * Otherwise, the fp should track them as state values instead. + */ +void +_mesa_set_varying_vp_inputs( GLcontext *ctx, + GLbitfield varying_inputs ) +{ + if (ctx->varying_vp_inputs != varying_inputs) { + ctx->varying_vp_inputs = varying_inputs; + ctx->NewState |= _NEW_ARRAY; + /*_mesa_printf("%s %x\n", __FUNCTION__, varying_inputs);*/ + } +} + + +/** + * Used by drivers to tell core Mesa that the driver is going to + * install/ use its own vertex program. In particular, this will + * prevent generated fragment programs from using state vars instead + * of ordinary varyings/inputs. + */ +void +_mesa_set_vp_override(GLcontext *ctx, GLboolean flag) +{ + if (ctx->VertexProgram._Overriden != flag) { + ctx->VertexProgram._Overriden = flag; + + /* Set one of the bits which will trigger fragment program + * regeneration: + */ + ctx->NewState |= _NEW_ARRAY; + } +} diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index bb7cb8f32a..29db08a0b9 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -29,13 +29,21 @@ #include "mtypes.h" extern void -_mesa_update_state( GLcontext *ctx ); +_mesa_update_state(GLcontext *ctx); /* As above but can only be called between _mesa_lock_context_textures() and * _mesa_unlock_context_textures(). */ extern void -_mesa_update_state_locked( GLcontext *ctx ); +_mesa_update_state_locked(GLcontext *ctx); + + +extern void +_mesa_set_varying_vp_inputs(GLcontext *ctx, GLbitfield varying_inputs); + + +extern void +_mesa_set_vp_override(GLcontext *ctx, GLboolean flag); #endif diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index c44d594d68..5ad936419b 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -137,8 +137,10 @@ _mesa_compressed_texture_size( GLcontext *ctx, ASSERT(depth == 1); (void) depth; + (void) size; switch (mesaFormat) { +#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: /* round up width to next multiple of 8, height to next multiple of 4 */ @@ -152,6 +154,8 @@ _mesa_compressed_texture_size( GLcontext *ctx, if (size < 16) size = 16; return size; +#endif +#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: /* round up width, height to next multiple of 4 */ @@ -178,6 +182,7 @@ _mesa_compressed_texture_size( GLcontext *ctx, if (size < 16) size = 16; return size; +#endif default: _mesa_problem(ctx, "bad mesaFormat in _mesa_compressed_texture_size"); return 0; @@ -202,12 +207,15 @@ _mesa_compressed_texture_size_glenum(GLcontext *ctx, GLuint mesaFormat; switch (glformat) { +#if FEATURE_texture_fxt1 case GL_COMPRESSED_RGB_FXT1_3DFX: mesaFormat = MESA_FORMAT_RGB_FXT1; break; case GL_COMPRESSED_RGBA_FXT1_3DFX: mesaFormat = MESA_FORMAT_RGBA_FXT1; break; +#endif +#if FEATURE_texture_s3tc case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_RGB_S3TC: mesaFormat = MESA_FORMAT_RGB_DXT1; @@ -224,6 +232,7 @@ _mesa_compressed_texture_size_glenum(GLcontext *ctx, case GL_RGBA4_S3TC: mesaFormat = MESA_FORMAT_RGBA_DXT5; break; +#endif default: return 0; } @@ -245,10 +254,13 @@ _mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width) GLint stride; switch (mesaFormat) { +#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */ break; +#endif +#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */ @@ -257,6 +269,7 @@ _mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width) case MESA_FORMAT_RGBA_DXT5: stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */ break; +#endif default: _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_row_stride"); return 0; @@ -293,10 +306,13 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img, */ switch (mesaFormat) { +#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8); break; +#endif +#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4); @@ -305,6 +321,7 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img, case MESA_FORMAT_RGBA_DXT5: addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4); break; +#endif default: _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_image_address"); addr = NULL; diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c index 45f344b0c5..fc151605c9 100644 --- a/src/mesa/main/texcompress_fxt1.c +++ b/src/mesa/main/texcompress_fxt1.c @@ -298,17 +298,17 @@ const struct gl_texture_format _mesa_texformat_rgba_fxt1 = { /* * Define a 64-bit unsigned integer type and macros */ -#ifdef GL_EXT_timer_query /* this extensions defines the GLuint64EXT type */ +#if 1 #define FX64_NATIVE 1 -typedef GLuint64EXT Fx64; +typedef uint64_t Fx64; #define FX64_MOV32(a, b) a = b #define FX64_OR32(a, b) a |= b #define FX64_SHL(a, c) a <<= c -#else /* !GL_EXT_timer_query */ +#else #define FX64_NATIVE 0 @@ -330,7 +330,7 @@ typedef struct { } \ } while (0) -#endif /* !GL_EXT_timer_query */ +#endif #define F(i) (GLfloat)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */ diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index ba7ce4a3cc..3cb103f51f 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -48,24 +48,24 @@ struct texenvprog_cache_item /** - * This MAX is probably a bit generous, but that's OK. There can be - * up to four instructions per texture unit (TEX + 3 for combine), - * then there's fog and specular add. + * Up to nine instructions per tex unit, plus fog, specular color. */ -#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 4) + 12) +#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 9) + 12) #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) struct mode_opt { - GLuint Source:4; - GLuint Operand:3; + GLubyte Source:4; + GLubyte Operand:3; }; struct state_key { - GLbitfield enabled_units; + GLuint nr_enabled_units:8; + GLuint enabled_units:8; GLuint separate_specular:1; GLuint fog_enabled:1; GLuint fog_mode:2; + GLuint inputs_available:12; struct { GLuint enabled:1; @@ -76,10 +76,10 @@ struct state_key { GLuint NumArgsRGB:2; GLuint ModeRGB:4; - struct mode_opt OptRGB[3]; - GLuint NumArgsA:2; GLuint ModeA:4; + + struct mode_opt OptRGB[3]; struct mode_opt OptA[3]; } unit[8]; }; @@ -201,6 +201,88 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) } } +#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) +#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) + +/** + * Identify all possible varying inputs. The fragment program will + * never reference non-varying inputs, but will track them via state + * constants instead. + * + * This function figures out all the inputs that the fragment program + * has access to. The bitmask is later reduced to just those which + * are actually referenced. + */ +static GLbitfield get_fp_input_mask( GLcontext *ctx ) +{ + GLbitfield fp_inputs = 0x0; + + if (ctx->VertexProgram._Overriden) { + /* Somebody's messing with the vertex program and we don't have + * a clue what's happening. Assume that it could be producing + * all possible outputs. + */ + fp_inputs = ~0; + } + else if (ctx->RenderMode == GL_FEEDBACK) { + fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); + } + else if (!ctx->VertexProgram._Enabled || + !ctx->VertexProgram._Current) { + + /* Fixed function logic */ + GLbitfield varying_inputs = ctx->varying_vp_inputs; + + /* These get generated in the setup routine regardless of the + * vertex program: + */ + if (ctx->Point.PointSprite) + varying_inputs |= FRAG_BITS_TEX_ANY; + + /* First look at what values may be computed by the generated + * vertex program: + */ + if (ctx->Light.Enabled) { + fp_inputs |= FRAG_BIT_COL0; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + fp_inputs |= FRAG_BIT_COL1; + } + + fp_inputs |= (ctx->Texture._TexGenEnabled | + ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; + + /* Then look at what might be varying as a result of enabled + * arrays, etc: + */ + if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0; + if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1; + + fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) + << FRAG_ATTRIB_TEX0); + + } + else { + /* calculate from vp->outputs */ + GLbitfield vp_outputs = ctx->VertexProgram._Current->Base.OutputsWritten; + + /* These get generated in the setup routine regardless of the + * vertex program: + */ + if (ctx->Point.PointSprite) + vp_outputs |= FRAG_BITS_TEX_ANY; + + if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; + if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; + + fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) + << FRAG_ATTRIB_TEX0); + } + + return fp_inputs; +} + + /** * Examine current texture environment state and generate a unique * key to identify it. @@ -208,7 +290,9 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) static void make_state_key( GLcontext *ctx, struct state_key *key ) { GLuint i, j; - + GLbitfield inputs_referenced = FRAG_BIT_COL0; + GLbitfield inputs_available = get_fp_input_mask( ctx ); + memset(key, 0, sizeof(*key)); for (i=0;i<MAX_TEXTURE_UNITS;i++) { @@ -222,6 +306,8 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) key->unit[i].enabled = 1; key->enabled_units |= (1<<i); + key->nr_enabled_units = i+1; + inputs_referenced |= FRAG_BIT_TEX(i); key->unit[i].source_index = translate_tex_src_bit(texUnit->_ReallyEnabled); @@ -252,16 +338,22 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) } } - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { key->separate_specular = 1; + inputs_referenced |= FRAG_BIT_COL1; + } if (ctx->Fog.Enabled) { key->fog_enabled = 1; key->fog_mode = translate_fog_mode(ctx->Fog.Mode); + inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ } + + key->inputs_available = (inputs_available & inputs_referenced); } -/* Use uregs to represent registers internally, translate to Mesa's +/** + * Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. * * NOTE: These are passed by value extensively in this file rather @@ -294,16 +386,16 @@ static const struct ureg undef = { }; -/* State used to build the fragment program: +/** State used to build the fragment program: */ struct texenv_fragment_program { struct gl_fragment_program *program; GLcontext *ctx; struct state_key *state; - GLbitfield alu_temps; /* Track texture indirections, see spec. */ - GLbitfield temps_output; /* Track texture indirections, see spec. */ - GLbitfield temp_in_use; /* Tracks temporary regs which are in use. */ + GLbitfield alu_temps; /**< Track texture indirections, see spec. */ + GLbitfield temps_output; /**< Track texture indirections, see spec. */ + GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ GLboolean error; struct ureg src_texture[MAX_TEXTURE_UNITS]; @@ -311,11 +403,11 @@ struct texenv_fragment_program { * else undef. */ - struct ureg src_previous; /* Reg containing color from previous + struct ureg src_previous; /**< Reg containing color from previous * stage. May need to be decl'd. */ - GLuint last_tex_stage; /* Number of last enabled texture unit */ + GLuint last_tex_stage; /**< Number of last enabled texture unit */ struct ureg half; struct ureg one; @@ -393,7 +485,7 @@ static struct ureg get_tex_temp( struct texenv_fragment_program *p ) { int bit; - /* First try to find availble temp not previously used (to avoid + /* First try to find available temp not previously used (to avoid * starting a new texture indirection). According to the spec, the * ~p->temps_output isn't necessary, but will keep it there for * now: @@ -418,6 +510,14 @@ static struct ureg get_tex_temp( struct texenv_fragment_program *p ) } +/** Mark a temp reg as being no longer allocatable. */ +static void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) +{ + if (r.file == PROGRAM_TEMPORARY) + p->temps_output |= (1 << r.idx); +} + + static void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) { GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; @@ -456,11 +556,29 @@ static struct ureg register_param5( struct texenv_fragment_program *p, #define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) +static GLuint frag_to_vert_attrib( GLuint attrib ) +{ + switch (attrib) { + case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; + case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; + default: + assert(attrib >= FRAG_ATTRIB_TEX0); + assert(attrib <= FRAG_ATTRIB_TEX7); + return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; + } +} + static struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) { - p->program->Base.InputsRead |= (1 << input); - return make_ureg(PROGRAM_INPUT, input); + if (p->state->inputs_available & (1<<input)) { + p->program->Base.InputsRead |= (1 << input); + return make_ureg(PROGRAM_INPUT, input); + } + else { + GLuint idx = frag_to_vert_attrib( input ); + return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); + } } @@ -511,10 +629,12 @@ emit_op(struct texenv_fragment_program *p, emit_dst( &inst->DstReg, dest, mask ); +#if 0 /* Accounting for indirection tracking: */ if (dest.file == PROGRAM_TEMPORARY) p->temps_output |= 1 << dest.idx; +#endif return inst; } @@ -569,6 +689,10 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, p->program->Base.NumTexInstructions++; + /* Accounting for indirection tracking: + */ + reserve_temp(p, dest); + /* Is this a texture indirection? */ if ((coord.file == PROGRAM_TEMPORARY && @@ -593,14 +717,16 @@ static struct ureg register_const4f( struct texenv_fragment_program *p, { GLfloat values[4]; GLuint idx, swizzle; + struct ureg r; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, &swizzle ); - ASSERT(swizzle == SWIZZLE_NOOP); - return make_ureg(PROGRAM_CONSTANT, idx); + r = make_ureg(PROGRAM_CONSTANT, idx); + r.swz = swizzle; + return r; } #define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) @@ -958,6 +1084,7 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) p->src_texture[unit] = emit_texld( p, OPCODE_TXP, tmp, WRITEMASK_XYZW, unit, dim, texcoord ); + if (p->state->unit[unit].shadow) p->program->Base.ShadowSamplers |= 1 << unit; @@ -1083,6 +1210,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) if (key->enabled_units & (1<<unit)) { p.src_previous = emit_texenv( &p, unit ); + reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */ release_temps(ctx, &p); /* release all temps */ } } @@ -1194,6 +1322,9 @@ _mesa_get_fixed_func_fragment_program(GLcontext *ctx) * If _MaintainTexEnvProgram is set we'll generate a fragment program that * implements the current texture env/combine mode. * This function generates that program and puts it into effect. + * + * XXX: remove this function. currently only called by some drivers, + * not by mesa core. We now handle this properly from inside mesa. */ void _mesa_UpdateTexEnvProgram( GLcontext *ctx ) diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 4442ce39a4..ce2772c299 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -1673,6 +1673,11 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format, *comps = 1; /* XXX OK? */ return; + case MESA_FORMAT_S8_Z24: + *datatype = GL_UNSIGNED_INT; + *comps = 1; /* XXX OK? */ + return; + case MESA_FORMAT_Z16: *datatype = GL_UNSIGNED_SHORT; *comps = 1; @@ -1683,6 +1688,7 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format, *comps = 1; return; +#if FEATURE_EXT_texture_sRGB case MESA_FORMAT_SRGB8: *datatype = GL_UNSIGNED_BYTE; *comps = 3; @@ -1699,9 +1705,13 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format, *datatype = GL_UNSIGNED_BYTE; *comps = 2; return; +#endif +#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: +#endif +#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGBA_DXT3: @@ -1710,6 +1720,7 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format, *datatype = GL_UNSIGNED_BYTE; *comps = 0; return; +#endif case MESA_FORMAT_RGBA: *datatype = CHAN_TYPE; diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 18900fe08b..f34b3b8223 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -106,12 +106,16 @@ enum _format { * \name Compressed texture formats. */ /*@{*/ +#if FEATURE_texture_fxt1 MESA_FORMAT_RGB_FXT1, MESA_FORMAT_RGBA_FXT1, +#endif +#if FEATURE_texture_s3tc MESA_FORMAT_RGB_DXT1, MESA_FORMAT_RGBA_DXT1, MESA_FORMAT_RGBA_DXT3, MESA_FORMAT_RGBA_DXT5, +#endif /*@}*/ /** @@ -225,12 +229,16 @@ extern const struct gl_texture_format _mesa_texformat_ycbcr_rev; /** \name Compressed formats */ /*@{*/ +#if FEATURE_texture_fxt1 extern const struct gl_texture_format _mesa_texformat_rgb_fxt1; extern const struct gl_texture_format _mesa_texformat_rgba_fxt1; +#endif +#if FEATURE_texture_s3tc extern const struct gl_texture_format _mesa_texformat_rgb_dxt1; extern const struct gl_texture_format _mesa_texformat_rgba_dxt1; extern const struct gl_texture_format _mesa_texformat_rgba_dxt3; extern const struct gl_texture_format _mesa_texformat_rgba_dxt5; +#endif /*@}*/ /** \name The null format */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 9e968ba743..a5e0db736e 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1217,19 +1217,30 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, img->Width = width; img->Height = height; img->Depth = depth; + img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ - img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ - img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ img->WidthLog2 = logbase2(img->Width2); - if (height == 1) /* 1-D texture */ + + if (height == 1) { /* 1-D texture */ + img->Height2 = 1; img->HeightLog2 = 0; - else + } + else { + img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ img->HeightLog2 = logbase2(img->Height2); - if (depth == 1) /* 2-D texture */ + } + + if (depth == 1) { /* 2-D texture */ + img->Depth2 = 1; img->DepthLog2 = 0; - else + } + else { + img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ img->DepthLog2 = logbase2(img->Depth2); + } + img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); + img->IsCompressed = GL_FALSE; img->CompressedSize = 0; diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 4b2b129468..7278180a5c 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -885,8 +885,8 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx, /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */ - if (srcRowStride == dstRowStride && - srcComponents == dstComponents && + if (srcComponents == dstComponents && + srcRowStride == dstRowStride && srcRowStride == srcWidth * srcComponents && dimensions < 3) { /* 1 and 2D images only */ diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index 6385689fcc..97d5c8219d 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -156,6 +156,20 @@ _mesa_LockArraysEXT(GLint first, GLsizei count); extern void GLAPIENTRY _mesa_UnlockArraysEXT( void ); + +extern void GLAPIENTRY +_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count); + +extern void GLAPIENTRY +_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + +extern void GLAPIENTRY +_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const GLvoid *indices); + + + extern void _mesa_init_varray( GLcontext * ctx ); |