diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/main/mtypes.h | 12 | ||||
| -rw-r--r-- | src/mesa/shader/prog_parameter.c | 28 | ||||
| -rw-r--r-- | src/mesa/shader/prog_parameter.h | 4 | ||||
| -rw-r--r-- | src/mesa/shader/prog_statevars.h | 2 | ||||
| -rw-r--r-- | src/mesa/shader/program.c | 2 | ||||
| -rw-r--r-- | src/mesa/shader/shader_api.c | 39 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 24 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 1 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_link.h | 3 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_link2.c | 138 | 
10 files changed, 209 insertions, 44 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b6c72055e1..cbb1fd47eb 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1844,16 +1844,16 @@ struct gl_program_parameter_list;  struct gl_program  {     GLuint Id; -   GLubyte *String;          /**< Null-terminated program text */ +   GLubyte *String;  /**< Null-terminated program text */     GLint RefCount; -   GLenum Target; -   GLenum Format;            /**< String encoding format */ +   GLenum Target;    /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */ +   GLenum Format;    /**< String encoding format */     GLboolean Resident;     struct prog_instruction *Instructions; -   GLbitfield InputsRead;     /* Bitmask of which input regs are read */ -   GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */ +   GLbitfield InputsRead;     /**< Bitmask of which input regs are read */ +   GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */     GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];  /**< TEXTURE_x_BIT bitmask */     /** Named parameters, constants, etc. from program text */ @@ -1863,6 +1863,8 @@ struct gl_program     /** Vertex/fragment shader varying vars */     struct gl_program_parameter_list *Varying; +   /** Vertex program user-defined attributes */ +   struct gl_program_parameter_list *Attributes;     /** Logical counts */     /*@{*/ diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index d09cc65937..e543871ab7 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -239,6 +239,9 @@ _mesa_add_sampler(struct gl_program_parameter_list *paramList,  } +/** + * Add parameter representing a varying variable. + */  GLint  _mesa_add_varying(struct gl_program_parameter_list *paramList,                    const char *name, GLuint size) @@ -256,6 +259,31 @@ _mesa_add_varying(struct gl_program_parameter_list *paramList,  } +/** + * Add parameter representing a vertex program attribute. + */ +GLint +_mesa_add_attribute(struct gl_program_parameter_list *paramList, +                    const char *name, GLint attrib) +{ +   GLint size = 4; /* XXX ok? */ +   GLint i = _mesa_lookup_parameter_index(paramList, -1, name); +   if (i >= 0) { +      /* replace */ +      ASSERT(paramList->Parameters[i].StateIndexes[0] == STATE_USER_ATTRIB); +      paramList->Parameters[i].StateIndexes[1] = attrib; +   } +   else { +      /* add */ +      i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_INPUT); +      if (i >= 0) { +         paramList->Parameters[i].StateIndexes[0] = STATE_USER_ATTRIB; +         paramList->Parameters[i].StateIndexes[1] = attrib; +      } +   } +   return i; +} +  #if 0 /* not used yet */ diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 0db2bcd314..ab4d730018 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -108,6 +108,10 @@ _mesa_add_varying(struct gl_program_parameter_list *paramList,                    const char *name, GLuint size);  extern GLint +_mesa_add_attribute(struct gl_program_parameter_list *paramList, +                    const char *name, GLint attrib); + +extern GLint  _mesa_add_state_reference(struct gl_program_parameter_list *paramList,                            const GLint *stateTokens); diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 17e38054bb..da672c9ec8 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -96,6 +96,8 @@ typedef enum gl_state_index_ {     STATE_NORMAL_SCALE,     STATE_TEXRECT_SCALE,     STATE_POSITION_NORMALIZED,   /* normalized light position */ +   STATE_USER_ATTRIB,           /** shader vertex attrib: user-specified */ +   STATE_AUTO_ATTRIB,           /** shader vertex attrib: linker-specified */     STATE_INTERNAL_DRIVER	/* first available state index for drivers (must be last) */  } gl_state_index; diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 1b26b6c932..7a31949673 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -365,6 +365,8 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)     memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));     if (prog->Varying)        clone->Varying = _mesa_clone_parameter_list(prog->Varying); +   if (prog->Attributes) +      clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);     memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));     clone->NumInstructions = prog->NumInstructions;     clone->NumTemporaries = prog->NumTemporaries; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index bd258f8737..d1b0e21b94 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -40,6 +40,8 @@  #include "hash.h"  #include "program.h"  #include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h"  #include "shader_api.h"  #include "slang_compile.h" @@ -59,6 +61,7 @@ _mesa_new_shader_program(GLcontext *ctx, GLuint name)        shProg->Type = GL_SHADER_PROGRAM;        shProg->Name = name;        shProg->RefCount = 1; +      shProg->Attributes = _mesa_new_parameter_list();     }     return shProg;  } @@ -275,6 +278,8 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,  {     struct gl_shader_program *shProg        = _mesa_lookup_shader_program(ctx, program); +   GLint i; +   GLint oldIndex;     if (!shProg) {        _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(program)"); @@ -290,15 +295,21 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,        return;     } -#if 0 /* XXXX */ -   if (name == NULL || index >= MAX_VERTEX_ATTRIBS) -      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); -   else if (IS_NAME_WITH_GL_PREFIX(name)) -      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB"); -   else -      (**pro).OverrideAttribBinding(pro, index, name); -   RELEASE_PROGRAM(pro); -#endif +   oldIndex = _mesa_get_attrib_location(ctx, program, name); + +   /* this will replace the current value if it's already in the list */ +   i = _mesa_add_attribute(shProg->Attributes, name, index); +   if (i < 0) { +      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); +   } + +   if (shProg->VertexProgram && oldIndex >= 0) { +      _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index); +   } + +   printf("===== post BindAttrib:\n"); +   _mesa_print_program(&shProg->VertexProgram->Base); +  } @@ -541,11 +552,9 @@ _mesa_get_attrib_location(GLcontext *ctx, GLuint program,        return -1;     if (shProg->Attributes) { -      GLuint i; -      for (i = 0; i < shProg->Attributes->NumParameters; i++) { -         if (!strcmp(shProg->Attributes->Parameters[i].Name, name)) { -            return i; -         } +      GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name); +      if (i >= 0) { +         return shProg->Attributes->Parameters[i].StateIndexes[1];        }     }     return -1; @@ -605,7 +614,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,        *params = shProg->NumShaders;        break;     case GL_ACTIVE_ATTRIBUTES: -      *params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0; +      *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0;        break;     case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:        *params = _mesa_parameter_longest_name(shProg->Attributes); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 79261ee29a..cc70d1de2a 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -540,7 +540,8 @@ _slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,     }     else if (var->type.qualifier == slang_qual_const) {        if (prog) { -         abort(); +         /* user-defined constant */ +         abort(); /* XXX fix */        }        else {           /* pre-defined global constant, like gl_MaxLights */ @@ -550,11 +551,22 @@ _slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,        if (dbg) printf("CONST ");     }     else if (var->type.qualifier == slang_qual_attribute) { -      /* Vertex attribute */ -      GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB); -      GLint size = 4; /* XXX? */ -      assert(index >= 0); -      store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); +      if (prog) { +         /* user-defined vertex attribute */ +         const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); +         GLint index = _mesa_add_parameter(prog->Attributes, varName, +                                           NULL, size, PROGRAM_INPUT); +         assert(index >= 0); +         store = _slang_new_ir_storage(PROGRAM_INPUT, +                                       VERT_ATTRIB_GENERIC0 + index, size); +      } +      else { +         /* pre-defined vertex attrib */ +         GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB); +         GLint size = 4; /* XXX? */ +         assert(index >= 0); +         store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); +      }        if (dbg) printf("ATTRIB ");     }     else if (var->type.qualifier == slang_qual_fixedinput) { diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index efb23255f9..314c32f707 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -2260,6 +2260,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)        shader->Programs[0]->Parameters = _mesa_new_parameter_list();        shader->Programs[0]->Varying = _mesa_new_parameter_list(); +      shader->Programs[0]->Attributes = _mesa_new_parameter_list();     }     slang_info_log_construct(&info_log); diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 2fc5525000..d9819289ca 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -357,6 +357,9 @@ extern void  _slang_resolve_samplers(struct gl_shader_program *shProg,                          struct gl_program *prog); +extern void +_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib); +  #ifdef __cplusplus  } diff --git a/src/mesa/shader/slang/slang_link2.c b/src/mesa/shader/slang/slang_link2.c index 3a5bce0099..0965f3e4c4 100644 --- a/src/mesa/shader/slang/slang_link2.c +++ b/src/mesa/shader/slang/slang_link2.c @@ -36,6 +36,7 @@  #include "prog_instruction.h"  #include "prog_parameter.h"  #include "prog_print.h" +#include "prog_statevars.h"  #include "shader_api.h"  #include "slang_link.h" @@ -311,31 +312,71 @@ _slang_resolve_branches(struct gl_program *prog)  /** - * Scan program for texture instructions, lookup sampler/uniform's value - * to determine which texture unit to use. - * Also, update the program's TexturesUsed[] array. + * Resolve binding of generic vertex attributes. + * 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.   */ -void -_slang_resolve_samplers(struct gl_shader_program *shProg, -                        struct gl_program *prog) +static GLboolean +_slang_resolve_attributes(struct gl_shader_program *shProg, +                          struct gl_program *prog)  { -   GLuint i; +   GLuint i, j; +   GLbitfield usedAttributes; -   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) -      prog->TexturesUsed[i] = 0; +   assert(prog->Target == GL_VERTEX_PROGRAM_ARB); + +   /* 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[1]; +      usedAttributes |= attr; +   } + +   if (!shProg->Attributes) +      shProg->Attributes = _mesa_new_parameter_list(); +   /* +    * Scan program for generic attribute references +    */     for (i = 0; i < prog->NumInstructions; i++) {        struct prog_instruction *inst = prog->Instructions + i; -      if (inst->Opcode == OPCODE_TEX || -          inst->Opcode == OPCODE_TXB || -          inst->Opcode == OPCODE_TXP) { -         GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0]; -         assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS); -         inst->TexSrcUnit = sampleUnit; +      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). +             */ +            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[1]; +            } +            else { +               /* not found, choose our own attribute number */ +               for (attr = 0; attr < MAX_VERTEX_ATTRIBS; attr++) { +                  if (((1 << attr) & usedAttributes) == 0) +                     break; +               } +               if (attr == MAX_VERTEX_ATTRIBS) { +                  /* too many!  XXX record error log */ +                  return GL_FALSE; +               } +               _mesa_add_attribute(shProg->Attributes, name, attr); +            } -         prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget); +            inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr; +         }        }     } +   return GL_TRUE;  } @@ -366,6 +407,65 @@ _slang_update_inputs_outputs(struct gl_program *prog)  } +/** + * 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; +            } +         } +      } +   } + +   _slang_update_inputs_outputs(prog); +} + + + +/** + * Scan program for texture instructions, lookup sampler/uniform's value + * to determine which texture unit to use. + * Also, update the program's TexturesUsed[] array. + */ +void +_slang_resolve_samplers(struct gl_shader_program *shProg, +                        struct gl_program *prog) +{ +   GLuint i; + +   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) +      prog->TexturesUsed[i] = 0; + +   for (i = 0; i < prog->NumInstructions; i++) { +      struct prog_instruction *inst = prog->Instructions + i; +      if (inst->Opcode == OPCODE_TEX || +          inst->Opcode == OPCODE_TXB || +          inst->Opcode == OPCODE_TXP) { +         GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0]; +         assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS); +         inst->TexSrcUnit = sampleUnit; + +         prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget); +      } +   } +} + +  /** cast wrapper */  static struct gl_vertex_program * @@ -463,10 +563,12 @@ _slang_link2(GLcontext *ctx,     _slang_resolve_branches(&shProg->VertexProgram->Base);     _slang_resolve_branches(&shProg->FragmentProgram->Base); -#if 1 +     _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);     _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); -#endif + +   _slang_resolve_attributes(shProg, &shProg->VertexProgram->Base); +     _slang_update_inputs_outputs(&shProg->VertexProgram->Base);     _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);  | 
