diff options
Diffstat (limited to 'src')
26 files changed, 339 insertions, 175 deletions
| diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index f22ba40824..b1ccfc0374 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -765,12 +765,30 @@ void cso_restore_vertex_shader(struct cso_context *ctx)  } +/** + * Copy framebuffer state from src to dst with refcounting of surfaces. + */ +static void +copy_framebuffer_state(struct pipe_framebuffer_state *dst, +                       const struct pipe_framebuffer_state *src) +{ +   uint i; + +   dst->width = src->width; +   dst->height = src->height; +   dst->num_cbufs = src->num_cbufs; +   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { +      pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]); +   } +   pipe_surface_reference(&dst->zsbuf, src->zsbuf); +} +  enum pipe_error cso_set_framebuffer(struct cso_context *ctx,                                      const struct pipe_framebuffer_state *fb)  {     if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) { -      ctx->fb = *fb; +      copy_framebuffer_state(&ctx->fb, fb);        ctx->pipe->set_framebuffer_state(ctx->pipe, fb);     }     return PIPE_OK; @@ -778,13 +796,13 @@ enum pipe_error cso_set_framebuffer(struct cso_context *ctx,  void cso_save_framebuffer(struct cso_context *ctx)  { -   ctx->fb_saved = ctx->fb; +   copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);  }  void cso_restore_framebuffer(struct cso_context *ctx)  {     if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) { -      ctx->fb = ctx->fb_saved; +      copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);        ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);     }  } diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 4f1326053d..e1af9e56a2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -222,8 +222,8 @@ static void widepoint_first_point( struct draw_stage *stage,        /* find fragment shader PointCoord/Fog input */        wide->point_coord_fs_input = 0; /* XXX fix this! */ -      /* setup extra vp output */ -      draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_FOG; +      /* setup extra vp output (point coord implemented as a texcoord) */ +      draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;        draw->extra_vp_outputs.semantic_index = 0;        draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs;     } diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 806a2bd4c5..c5d2082087 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current  LIBNAME = tgsi  C_SOURCES = \ +	tgsi_sanity.c \  	tgsi_build.c \  	tgsi_dump.c \  	tgsi_exec.c \ diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index a4899cd4c2..68c7a6b7f5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -69,7 +69,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =     { 1, 1, 0, 0, "COS" },     { 1, 1, 0, 0, "DDX" },     { 1, 1, 0, 0, "DDY" }, -   { 0, 1, 0, 0, "KILP" }, +   { 0, 0, 0, 0, "KILP" },     { 1, 1, 0, 0, "PK2H" },     { 1, 1, 0, 0, "PK2US" },     { 1, 1, 0, 0, "PK4B" }, @@ -146,7 +146,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =     { 0, 1, 0, 0, "CALLNZ" },     { 0, 1, 0, 0, "IFC" },     { 0, 1, 0, 0, "BREAKC" }, -   { 0, 0, 0, 0, "KIL" }, +   { 0, 1, 0, 0, "KIL" },     { 0, 0, 0, 0, "END" },     { 1, 1, 0, 0, "SWZ" }  }; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index c659027296..11659247c0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -152,6 +152,12 @@ check_register_usage(  {     if (!check_file_name( ctx, file ))        return FALSE; + +   if (index < 0 || index > MAX_REGISTERS) { +      report_error( ctx, "%s[%i]: Invalid index %s", file_names[file], index, name ); +      return FALSE; +   } +     if (indirect_access) {        if (!is_any_register_declared( ctx, file ))           report_error( ctx, "%s: Undeclared %s register", file_names[file], name ); @@ -174,12 +180,10 @@ iter_instruction(     const struct tgsi_opcode_info *info;     uint i; -   /* There must be no other instructions after END. -    */ -   if (ctx->index_of_END != ~0) { -      report_error( ctx, "Unexpected instruction after END" ); -   } -   else if (inst->Instruction.Opcode == TGSI_OPCODE_END) { +   if (inst->Instruction.Opcode == TGSI_OPCODE_END) { +      if (ctx->index_of_END != ~0) { +         report_error( ctx, "Too many END instructions" ); +      }        ctx->index_of_END = ctx->num_instructions;     } @@ -301,10 +305,10 @@ epilog(     struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;     uint file; -   /* There must be an END instruction at the end. +   /* There must be an END instruction somewhere.      */ -   if (ctx->index_of_END == ~0 || ctx->index_of_END != ctx->num_instructions - 1) { -      report_error( ctx, "Expected END at end of instruction sequence" ); +   if (ctx->index_of_END == ~0) { +      report_error( ctx, "Missing END instruction" );     }     /* Check if all declared registers were used. diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 9b4ca39371..0b10622ee7 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -272,8 +272,10 @@ util_fast_log2(float val)  static INLINE float  util_fast_pow(float x, float y)  { -   /* XXX this test may need adjustment */ -   if (y >= 3.0 && -0.02f <= x && x <= 0.02f) +   /* XXX these tests may need adjustment */ +   if (y >= 3.0f && (-0.02f <= x && x <= 0.02f)) +      return 0.0f; +   if (y >= 50.0f && (-0.9f <= x && x <= 0.9f))        return 0.0f;     return util_fast_exp2(util_fast_log2(x) * y);  } diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index e04cf5f274..475c6ef0ce 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -48,8 +48,9 @@ cell_create_blend_state(struct pipe_context *pipe,     struct cell_blend_state *cb = MALLOC(sizeof(struct cell_blend_state));     (void) memcpy(cb, blend, sizeof(*blend)); +#if 0     cell_generate_alpha_blend(cb); - +#endif     return cb;  } @@ -100,8 +101,9 @@ cell_create_depth_stencil_alpha_state(struct pipe_context *pipe,         MALLOC(sizeof(struct cell_depth_stencil_alpha_state));     (void) memcpy(cdsa, depth_stencil, sizeof(*depth_stencil)); +#if 0     cell_generate_depth_stencil_test(cdsa); - +#endif     return cdsa;  } diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index e7a2f12b02..f0e1cd596d 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -10,7 +10,7 @@ This directory contains a Gallium3D pipe driver which traces all incoming calls.  To build, invoke scons on the top dir as - scons statetrackers=mesa drivers=softpipe,i915simple,trace winsys=xlib + scons statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib  = Usage = diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 2acbc94fc8..3334af175b 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -349,19 +349,26 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)           if (x + w > surf->width)              w = surf->width - x; -         offset *= 4 * TILE_SIZE * TILE_SIZE; - -         twiddle_tile((uint *) ((char *) xm_buf->data + offset), -                      tmpTile); -         ximage->data = (char*) tmpTile; +         /* offset in pixels */ +         offset *= TILE_SIZE * TILE_SIZE;           if (XSHM_ENABLED(xm_buf)) { +            ximage->data = (char *) xm_buf->data + 4 * offset; +            /* make copy of tile data */ +            memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); +            /* twiddle from temp to ximage in shared memory */ +            twiddle_tile(tmpTile, (uint *) ximage->data); +            /* display image in shared memory */  #if defined(USE_XSHM) && !defined(XFree86Server)              XShmPutImage(b->xm_visual->display, b->drawable, b->gc,                           ximage, 0, 0, x, y, w, h, False);  #endif           }           else { +            /* twiddel from ximage buffer to temp tile */ +            twiddle_tile((uint *) xm_buf->data + offset, tmpTile); +            /* display temp tile data */ +            ximage->data = (char *) tmpTile;              XPutImage(b->xm_visual->display, b->drawable, b->gc,                        ximage, 0, 0, x, y, w, h);           } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index f1e0932b07..ecdb4d219c 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -205,11 +205,14 @@ _mesa_reference_buffer_object(GLcontext *ctx,        if (deleteFlag) {           /* some sanity checking: don't delete a buffer still in use */ +#if 0 +         /* unfortunately, these tests are invalid during context tear-down */  	 ASSERT(ctx->Array.ArrayBufferObj != bufObj);  	 ASSERT(ctx->Array.ElementArrayBufferObj != bufObj);  	 ASSERT(ctx->Array.ArrayObj->Vertex.BufferObj != bufObj); -	 ASSERT(ctx->Driver.DeleteBuffer); +#endif +	 ASSERT(ctx->Driver.DeleteBuffer);           ctx->Driver.DeleteBuffer(ctx, oldObj);        } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index b4ed300b2e..ffe6dbfe08 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -6737,6 +6737,11 @@ _mesa_EndList(void)        _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");        return;     } +    +   /* Call before emitting END_OF_LIST, in case the driver wants to +    * emit opcodes itself. +    */ +   ctx->Driver.EndList(ctx);     (void) ALLOC_INSTRUCTION(ctx, OPCODE_END_OF_LIST, 0); @@ -6750,8 +6755,6 @@ _mesa_EndList(void)     if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)        mesa_print_display_list(ctx->ListState.CurrentListNum); -   ctx->Driver.EndList(ctx); -     ctx->ListState.CurrentList = NULL;     ctx->ListState.CurrentListNum = 0;     ctx->ListState.CurrentListPtr = NULL; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 71a4ca55bc..a5e1cf6a27 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1953,7 +1953,10 @@ struct gl_fragment_program  {     struct gl_program Base;   /**< base class */     GLenum FogOption; -   GLboolean UsesKill; +   GLboolean UsesKill;          /**< shader uses KIL instruction */ +   GLboolean UsesPointCoord;    /**< shader uses gl_PointCoord */ +   GLboolean UsesFrontFacing;   /**< shader used gl_FrontFacing */ +   GLboolean UsesFogFragCoord;  /**< shader used gl_FogFragCoord */  }; @@ -2143,12 +2146,14 @@ struct gl_shader_program     GLuint NumShaders;          /**< number of attached shaders */     struct gl_shader **Shaders; /**< List of attached the shaders */ +   /** User-defined attribute bindings (glBindAttribLocation) */ +   struct gl_program_parameter_list *Attributes; +     /* post-link info: */     struct gl_vertex_program *VertexProgram;     /**< Linked vertex program */     struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */     struct gl_uniform_list *Uniforms;     struct gl_program_parameter_list *Varying; -   struct gl_program_parameter_list *Attributes; /**< Vertex attributes */     GLboolean LinkStatus;   /**< GL_LINK_STATUS */     GLboolean Validated;     GLchar *InfoLog; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 344af91e17..d355f78a0e 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -295,10 +295,10 @@ static void  update_multisample(GLcontext *ctx)  {     ctx->Multisample._Enabled = GL_FALSE; -   if (ctx->DrawBuffer) { -      if (ctx->DrawBuffer->Visual.sampleBuffers) -         ctx->Multisample._Enabled = GL_TRUE; -   } +   if (ctx->Multisample.Enabled && +       ctx->DrawBuffer && +       ctx->DrawBuffer->Visual.sampleBuffers) +      ctx->Multisample._Enabled = GL_TRUE;  } diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index d8b210be53..decdec53ed 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1,6 +1,6 @@  /*   * Mesa 3-D graphics library - * Version:  7.1 + * Version:  7.2   *   * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.   * @@ -497,10 +497,14 @@ _mesa_get_attrib_location(GLcontext *ctx, GLuint program,     if (!name)        return -1; -   if (shProg->Attributes) { -      GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name); -      if (i >= 0) { -         return shProg->Attributes->Parameters[i].StateIndexes[0]; +   if (shProg->VertexProgram) { +      const struct gl_program_parameter_list *attribs = +         shProg->VertexProgram->Base.Attributes; +      if (attribs) { +         GLint i = _mesa_lookup_parameter_index(attribs, -1, name); +         if (i >= 0) { +            return attribs->Parameters[i].StateIndexes[0]; +         }        }     }     return -1; @@ -513,7 +517,7 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,  {     struct gl_shader_program *shProg;     const GLint size = -1; /* unknown size */ -   GLint i, oldIndex; +   GLint i;     GLenum datatype = GL_FLOAT_VEC4;     shProg = _mesa_lookup_shader_program_err(ctx, program, @@ -536,14 +540,6 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,        return;     } -   if (shProg->LinkStatus) { -      /* get current index/location for the attribute */ -      oldIndex = _mesa_get_attrib_location(ctx, program, name); -   } -   else { -      oldIndex = -1; -   } -     /* this will replace the current value if it's already in the list */     i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);     if (i < 0) { @@ -551,12 +547,10 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,        return;     } -   if (shProg->VertexProgram && oldIndex >= 0 && oldIndex != index) { -      /* If the index changed, need to search/replace references to that attribute -       * in the vertex program. -       */ -      _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index); -   } +   /* +    * Note that this attribute binding won't go into effect until +    * glLinkProgram is called again. +    */  } @@ -798,24 +792,29 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,                          GLsizei maxLength, GLsizei *length, GLint *size,                          GLenum *type, GLchar *nameOut)  { +   const struct gl_program_parameter_list *attribs = NULL;     struct gl_shader_program *shProg;     shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");     if (!shProg)        return; -   if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) { +   if (shProg->VertexProgram) +      attribs = shProg->VertexProgram->Base.Attributes; + +   if (!attribs || index >= attribs->NumParameters) {        _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");        return;     } -   copy_string(nameOut, maxLength, length, -               shProg->Attributes->Parameters[index].Name); +   copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name); +     if (size) -      *size = shProg->Attributes->Parameters[index].Size -         / sizeof_glsl_type(shProg->Attributes->Parameters[index].DataType); +      *size = attribs->Parameters[index].Size +         / sizeof_glsl_type(attribs->Parameters[index].DataType); +     if (type) -      *type = shProg->Attributes->Parameters[index].DataType; +      *type = attribs->Parameters[index].DataType;  } @@ -937,6 +936,7 @@ static void  _mesa_get_programiv(GLcontext *ctx, GLuint program,                      GLenum pname, GLint *params)  { +   const struct gl_program_parameter_list *attribs;     struct gl_shader_program *shProg        = _mesa_lookup_shader_program(ctx, program); @@ -945,6 +945,11 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,        return;     } +   if (shProg->VertexProgram) +      attribs = shProg->VertexProgram->Base.Attributes; +   else +      attribs = NULL; +     switch (pname) {     case GL_DELETE_STATUS:        *params = shProg->DeletePending; @@ -962,11 +967,10 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,        *params = shProg->NumShaders;        break;     case GL_ACTIVE_ATTRIBUTES: -      *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0; +      *params = attribs ? attribs->NumParameters : 0;        break;     case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: -      *params = _mesa_longest_parameter_name(shProg->Attributes, -                                             PROGRAM_INPUT) + 1; +      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;        break;     case GL_ACTIVE_UNIFORMS:        *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; @@ -1108,7 +1112,8 @@ get_matrix_dims(GLenum type, GLint *rows, GLint *cols)  /**   * Determine the number of rows and columns occupied by a uniform - * according to its datatype. + * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4), + * the number of rows = 1 and cols = number of elements in the vector.   */  static void  get_uniform_rows_cols(const struct gl_program_parameter *p, @@ -1117,11 +1122,17 @@ get_uniform_rows_cols(const struct gl_program_parameter *p,     get_matrix_dims(p->DataType, rows, cols);     if (*rows == 0 && *cols == 0) {        /* not a matrix type, probably a float or vector */ -      *rows = p->Size / 4 + 1; -      if (p->Size % 4 == 0) -         *cols = 4; -      else -         *cols = p->Size % 4; +      if (p->Size <= 4) { +         *rows = 1; +         *cols = p->Size; +      } +      else { +         *rows = p->Size / 4 + 1; +         if (p->Size % 4 == 0) +            *cols = 4; +         else +            *cols = p->Size % 4; +      }     }  } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 57dbfc2388..dd7d5be6d8 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.3 + * Version:  7.2   * - * Copyright (C) 2007  Brian Paul   All Rights Reserved. + * Copyright (C) 2008  Brian Paul   All Rights Reserved.   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the "Software"), @@ -42,6 +42,24 @@  #include "slang_link.h" +/** cast wrapper */ +static struct gl_vertex_program * +vertex_program(struct gl_program *prog) +{ +   assert(prog->Target == GL_VERTEX_PROGRAM_ARB); +   return (struct gl_vertex_program *) prog; +} + + +/** cast wrapper */ +static struct gl_fragment_program * +fragment_program(struct gl_program *prog) +{ +   assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); +   return (struct gl_fragment_program *) prog; +} + +  /**   * Record a linking error.   */ @@ -215,74 +233,112 @@ link_uniform_vars(struct gl_shader_program *shProg,   * For example, if the vertex shader declared "attribute vec4 foobar" we'll   * allocate a generic vertex attribute for "foobar" and plug that value into   * the vertex program instructions. + * But if the user called glBindAttributeLocation(), those bindings will + * have priority.   */  static GLboolean  _slang_resolve_attributes(struct gl_shader_program *shProg, -                          struct gl_program *prog) +                          const struct gl_program *origProg, +                          struct gl_program *linkedProg)  { +   GLint attribMap[MAX_VERTEX_ATTRIBS];     GLuint i, j;     GLbitfield usedAttributes; -   assert(prog->Target == GL_VERTEX_PROGRAM_ARB); +   assert(origProg != linkedProg); +   assert(origProg->Target == GL_VERTEX_PROGRAM_ARB); +   assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB);     if (!shProg->Attributes)        shProg->Attributes = _mesa_new_parameter_list(); +   if (linkedProg->Attributes) { +      _mesa_free_parameter_list(linkedProg->Attributes); +   } +   linkedProg->Attributes = _mesa_new_parameter_list(); + +     /* Build a bitmask indicating which attribute indexes have been      * explicitly bound by the user with glBindAttributeLocation().      */     usedAttributes = 0x0;     for (i = 0; i < shProg->Attributes->NumParameters; i++) {        GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0]; -      usedAttributes |= attr; +      usedAttributes |= (1 << attr); +   } + +   /* initialize the generic attribute map entries to -1 */ +   for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) { +      attribMap[i] = -1;     }     /*      * Scan program for generic attribute references      */ -   for (i = 0; i < prog->NumInstructions; i++) { -      struct prog_instruction *inst = prog->Instructions + i; +   for (i = 0; i < linkedProg->NumInstructions; i++) { +      struct prog_instruction *inst = linkedProg->Instructions + i;        for (j = 0; j < 3; j++) {           if (inst->SrcReg[j].File == PROGRAM_INPUT &&               inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { -            /* this is a generic attrib */ -            const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; -            const char *name = prog->Attributes->Parameters[k].Name; -            /* See if this attrib name is in the program's attribute list -             * (i.e. was bound by the user). +            /* +             * OK, we've found a generic vertex attribute reference.               */ -            GLint index = _mesa_lookup_parameter_index(shProg->Attributes, -                                                          -1, name); -            GLint attr; -            if (index >= 0) { -               /* found, user must have specified a binding */ -               attr = shProg->Attributes->Parameters[index].StateIndexes[0]; -            } -            else { -               /* Not found, choose our own attribute number. -                * Start at 1 since generic attribute 0 always aliases -                * glVertex/position. +            const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; + +            GLint attr = attribMap[k]; + +            if (attr < 0) { +               /* Need to figure out attribute mapping now. +                */ +               const char *name = origProg->Attributes->Parameters[k].Name; +               const GLint size = origProg->Attributes->Parameters[k].Size; +               const GLenum type =origProg->Attributes->Parameters[k].DataType; +               GLint index; + +               /* See if there's a user-defined attribute binding for +                * this name.                  */ -               GLint size = prog->Attributes->Parameters[k].Size; -               GLenum datatype = prog->Attributes->Parameters[k].DataType; -               for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { -                  if (((1 << attr) & usedAttributes) == 0) -                     break; +               index = _mesa_lookup_parameter_index(shProg->Attributes, +                                                    -1, name); +               if (index >= 0) { +                  /* Found a user-defined binding */ +                  attr = shProg->Attributes->Parameters[index].StateIndexes[0];                 } -               if (attr == MAX_VERTEX_ATTRIBS) { -                  /* too many!  XXX record error log */ -                  return GL_FALSE; +               else { +                  /* No user-defined binding, choose our own attribute number. +                   * Start at 1 since generic attribute 0 always aliases +                   * glVertex/position. +                   */ +                  for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { +                     if (((1 << attr) & usedAttributes) == 0) +                        break; +                  } +                  if (attr == MAX_VERTEX_ATTRIBS) { +                     link_error(shProg, "Too many vertex attributes"); +                     return GL_FALSE; +                  } + +                  /* mark this attribute as used */ +                  usedAttributes |= (1 << attr);                 } -               _mesa_add_attribute(shProg->Attributes, name, size, datatype,attr); -	       /* set the attribute as used */ -	       usedAttributes |= 1<<attr; +               attribMap[k] = attr; + +               /* Save the final name->attrib binding so it can be queried +                * with glGetAttributeLocation(). +                */ +               _mesa_add_attribute(linkedProg->Attributes, name, +                                   size, type, attr);              } +            assert(attr >= 0); + +            /* update the instruction's src reg */              inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;           }        }     } +     return GL_TRUE;  } @@ -325,6 +381,7 @@ static void  _slang_update_inputs_outputs(struct gl_program *prog)  {     GLuint i, j; +   GLuint maxAddrReg = 0;     prog->InputsRead = 0x0;     prog->OutputsWritten = 0x0; @@ -335,60 +392,34 @@ _slang_update_inputs_outputs(struct gl_program *prog)        for (j = 0; j < numSrc; j++) {           if (inst->SrcReg[j].File == PROGRAM_INPUT) {              prog->InputsRead |= 1 << inst->SrcReg[j].Index; +            if (prog->Target == GL_FRAGMENT_PROGRAM_ARB && +                inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) { +               /* The fragment shader FOGC input is used for fog, +                * front-facing and sprite/point coord. +                */ +               struct gl_fragment_program *fp = fragment_program(prog); +               const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0); +               if (swz == SWIZZLE_X) +                  fp->UsesFogFragCoord = GL_TRUE; +               else if (swz == SWIZZLE_Y) +                  fp->UsesFrontFacing = GL_TRUE; +               else if (swz == SWIZZLE_Z || swz == SWIZZLE_W) +                  fp->UsesPointCoord = GL_TRUE; +            } +         } +         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { +            maxAddrReg = MAX2(maxAddrReg, inst->SrcReg[j].Index + 1);           }        }        if (inst->DstReg.File == PROGRAM_OUTPUT) {           prog->OutputsWritten |= 1 << inst->DstReg.Index;        } -   } -} - - -/** - * Scan a vertex program looking for instances of - * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + oldAttrib) and replace with - * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + newAttrib). - * This is used when the user calls glBindAttribLocation on an already linked - * shader program. - */ -void -_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib) -{ -   GLuint i, j; - -   assert(prog->Target == GL_VERTEX_PROGRAM_ARB); - -   for (i = 0; i < prog->NumInstructions; i++) { -      struct prog_instruction *inst = prog->Instructions + i; -      for (j = 0; j < 3; j++) { -         if (inst->SrcReg[j].File == PROGRAM_INPUT) { -            if (inst->SrcReg[j].Index == VERT_ATTRIB_GENERIC0 + oldAttrib) { -               inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + newAttrib; -            } -         } +      else if (inst->DstReg.File == PROGRAM_ADDRESS) { +         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);        }     } -   _slang_update_inputs_outputs(prog); -} - - - -/** cast wrapper */ -static struct gl_vertex_program * -vertex_program(struct gl_program *prog) -{ -   assert(prog->Target == GL_VERTEX_PROGRAM_ARB); -   return (struct gl_vertex_program *) prog; -} - - -/** cast wrapper */ -static struct gl_fragment_program * -fragment_program(struct gl_program *prog) -{ -   assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); -   return (struct gl_fragment_program *) prog; +   prog->NumAddressRegs = maxAddrReg;  } @@ -492,9 +523,8 @@ _slang_link(GLcontext *ctx,     /*_mesa_print_uniforms(shProg->Uniforms);*/     if (shProg->VertexProgram) { -      if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) { -         /*goto cleanup;*/ -         _mesa_problem(ctx, "_slang_resolve_attributes() failed"); +      if (!_slang_resolve_attributes(shProg, &vertProg->Base, +                                     &shProg->VertexProgram->Base)) {           return;        }     } diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 8ef8a6b4b3..2b44d20787 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.3 + * Version:  7.2   * - * Copyright (C) 2007  Brian Paul   All Rights Reserved. + * Copyright (C) 2008  Brian Paul   All Rights Reserved.   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the "Software"), @@ -32,10 +32,6 @@ extern void  _slang_link(GLcontext *ctx, GLhandleARB h,              struct gl_shader_program *shProg); -extern void -_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, -                       GLuint newAttrib); -  #endif diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index e286dc5116..fc47896c24 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -254,7 +254,7 @@ static void update_raster_state( struct st_context *st )     raster->line_stipple_factor = ctx->Line.StippleFactor - 1;     /* _NEW_MULTISAMPLE */ -   if (ctx->Multisample._Enabled) +   if (ctx->Multisample._Enabled || st->force_msaa)        raster->multisample = 1;     /* _NEW_SCISSOR */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 8406bf247f..00076f61e0 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -170,6 +170,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,                                                    0, 0, 0,                                                    surface_usage ); +   assert(strb->surface->texture);     assert(strb->surface->buffer);     assert(strb->surface->format);     assert(strb->surface->block.size); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index a3e8fc992d..2e1ad93942 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -455,6 +455,11 @@ st_TexImage(GLcontext * ctx,        _mesa_align_free(texImage->Data);     } +   if (width == 0 || height == 0 || depth == 0) { +      /* stop after freeing old image */ +      return; +   } +     /* If this is the only mipmap level in the texture, could call      * bmBufferData with NULL data to free the old block and avoid      * waiting on any outstanding fences. @@ -1048,7 +1053,8 @@ st_copy_texsubimage(GLcontext *ctx,     GLboolean use_fallback = GL_TRUE;     GLboolean matching_base_formats; -   st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); +   /* any rendering in progress must complete before we grab the fb image */ +   st_finish(ctx->st);     /* determine if copying depth or color data */     if (texBaseFormat == GL_DEPTH_COMPONENT) { diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 08d4db7f7f..cca808d328 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -88,6 +88,19 @@ void st_invalidate_state(GLcontext * ctx, GLuint new_state)  } +/** + * Check for multisample env var override. + */ +int +st_get_msaa(void) +{ +   const char *msaa = _mesa_getenv("__GL_FSAA_MODE"); +   if (msaa) +      return atoi(msaa); +   return 0; +} + +  static struct st_context *  st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )  { @@ -141,6 +154,8 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )     st->pixel_xfer.cache = _mesa_new_program_cache(); +   st->force_msaa = st_get_msaa(); +     /* GL limits and extensions */     st_init_limits(st);     st_init_extensions(st); @@ -188,8 +203,6 @@ static void st_destroy_context_priv( struct st_context *st )     st_destroy_drawtex(st);  #endif -   _vbo_DestroyContext(st->ctx); -     for (i = 0; i < Elements(st->state.sampler_texture); i++) {        pipe_texture_reference(&st->state.sampler_texture[i], NULL);     } @@ -223,6 +236,8 @@ void st_destroy_context( struct st_context *st )     _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); +   _vbo_DestroyContext(st->ctx); +     _mesa_free_context_data(ctx);     st_destroy_context_priv(st); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 4314d9af5c..1d1aca3111 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -181,6 +181,8 @@ struct st_context     struct blit_state *blit;     struct cso_context *cso_context; + +   int force_msaa;  }; @@ -238,4 +240,8 @@ st_fb_orientation(const struct gl_framebuffer *fb)  } +extern int +st_get_msaa(void); + +  #endif diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 0f4a03fa48..ec8928f200 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -51,13 +51,12 @@ st_create_framebuffer( const __GLcontextModes *visual,  {     struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer);     if (stfb) { -      int samples = 0; -      const char *msaa_override = _mesa_getenv("__GL_FSAA_MODE"); +      int samples = st_get_msaa(); + +      if (visual->sampleBuffers) +         samples = visual->samples; +        _mesa_initialize_framebuffer(&stfb->Base, visual); -      if (visual->sampleBuffers) samples = visual->samples; -      if (msaa_override) { -         samples = _mesa_atoi(msaa_override); -      }        {           /* fake frontbuffer */ diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 5ec9fddd7f..b9807bb807 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -35,10 +35,13 @@  #include "tgsi/tgsi_parse.h"  #include "tgsi/tgsi_build.h"  #include "tgsi/tgsi_util.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_sanity.h"  #include "st_mesa_to_tgsi.h"  #include "shader/prog_instruction.h"  #include "shader/prog_parameter.h" - +#include "shader/prog_print.h" +#include "pipe/p_debug.h"  /*   * Map mesa register file to TGSI register file. @@ -239,6 +242,15 @@ compile_instruction(           immediateMapping,           indirectAccess ); +      /** +       * This not at all the correct solution. +       * FIXME: Roll this up in the above map functions +       */ +      if (fullsrc->SrcRegister.File == TGSI_FILE_IMMEDIATE && fullsrc->SrcRegister.Index == ~0) { +         fullsrc->SrcRegister.File = TGSI_FILE_CONSTANT; +         fullsrc->SrcRegister.Index = inst->SrcReg[i].Index; +      } +        /* swizzle (ext swizzle also depends on negation) */        {           GLuint swz[4]; @@ -980,5 +992,17 @@ tgsi_translate_mesa_program(           maxTokens - ti );     } +#if DEBUG +   if(!tgsi_sanity_check(tokens)) { +      debug_printf("Due to sanity check failure(s) above the following shader program is invalid:\n"); +      debug_printf("\nOriginal program:\n%s", program->String); +      debug_printf("\nMesa program:\n"); +      _mesa_print_program(program); +      debug_printf("\nTGSI program:\n"); +      tgsi_dump(tokens, 0); +      assert(0); +   } +#endif +     return ti;  } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 936a6e32ea..b2abf0286e 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -409,7 +409,10 @@ st_translate_fragment_program(struct st_context *st,              interpMode[slot] = TGSI_INTERPOLATE_LINEAR;              break;           case FRAG_ATTRIB_FOGC: -            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG; +            if (stfp->Base.UsesPointCoord) +               stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; +            else +               stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;              stfp->input_semantic_index[slot] = 0;              interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;              break; diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index dc7c534251..b452ac8a38 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -246,12 +246,14 @@ void _vbo_DestroyContext( GLcontext *ctx )        ctx->aelt_context = NULL;     } -   vbo_exec_destroy(ctx); +   if (vbo_context(ctx)) { +      vbo_exec_destroy(ctx);  #if FEATURE_dlist -   vbo_save_destroy(ctx); +      vbo_save_destroy(ctx);  #endif -   FREE(vbo_context(ctx)); -   ctx->swtnl_im = NULL; +      FREE(vbo_context(ctx)); +      ctx->swtnl_im = NULL; +   }  } diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 88d573f128..f69a33d817 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -1045,6 +1045,32 @@ void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )  void vbo_save_EndList( GLcontext *ctx )  {     struct vbo_save_context *save = &vbo_context(ctx)->save; + +   /* EndList called inside a (saved) Begin/End pair? +    */ +   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) { + +      if (save->prim_count > 0) { +         GLint i = save->prim_count - 1; +         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; +         save->prim[i].end = 0; +         save->prim[i].count = (save->vert_count -  +                                save->prim[i].start); +      } + +      /* Make sure this vertex list gets replayed by the "loopback" +       * mechanism: +       */ +      save->dangling_attr_ref = 1; +      vbo_save_SaveFlushVertices( ctx ); + +      /* Swap out this vertex format while outside begin/end.  Any color, +       * etc. received between here and the next begin will be compiled +       * as opcodes. +       */    +      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +   } +     unmap_vertex_store( ctx, save->vertex_store );     assert(save->vertex_size == 0); | 
