diff options
Diffstat (limited to 'src/mesa/shader')
-rw-r--r-- | src/mesa/shader/nvprogram.c | 6 | ||||
-rw-r--r-- | src/mesa/shader/prog_execute.c | 25 | ||||
-rw-r--r-- | src/mesa/shader/prog_parameter.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/program.h | 16 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 131 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link.c | 4 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_typeinfo.c | 27 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_typeinfo.h | 20 |
11 files changed, 193 insertions, 44 deletions
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 87f295e39a..c3b10f5d9b 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -570,15 +570,15 @@ _mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program) inst->DstReg.Index + 1); } if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[0].Index + 1); } if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[1].Index + 1); } if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[2].Index + 1); } } diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 7781cb3f7f..ee422e7ec8 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -599,13 +599,13 @@ store_vector4ui(const struct prog_instruction *inst, if (inst->CondUpdate) { if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc(value[0]); + machine->CondCodes[0] = generate_cc((float)value[0]); if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc(value[1]); + machine->CondCodes[1] = generate_cc((float)value[1]); if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc(value[2]); + machine->CondCodes[2] = generate_cc((float)value[2]); if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc(value[3]); + machine->CondCodes[3] = generate_cc((float)value[3]); #if DEBUG_PROG printf("CondCodes=(%s,%s,%s,%s) for:\n", _mesa_condcode_string(machine->CondCodes[0]), @@ -1000,7 +1000,7 @@ _mesa_execute_program(GLcontext * ctx, val = -FLT_MAX; } else { - val = log(a[0]) * 1.442695F; + val = (float)(log(a[0]) * 1.442695F); } result[0] = result[1] = result[2] = result[3] = val; store_vector4(inst, machine, result); @@ -1065,7 +1065,7 @@ _mesa_execute_program(GLcontext * ctx, /* The fast LOG2 macro doesn't meet the precision * requirements. */ - q[2] = (log(t[0]) * 1.442695F); + q[2] = (float)(log(t[0]) * 1.442695F); } } else { @@ -1780,15 +1780,10 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_PRINT: { - if (inst->SrcReg[0].File != -1) { - GLfloat a[4]; - fetch_vector4(&inst->SrcReg[0], machine, a); - _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - _mesa_printf("%s\n", (const char *) inst->Data); - } + GLfloat a[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, + a[0], a[1], a[2], a[3]); } break; case OPCODE_END: diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 5822510701..d4970c4e44 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -209,7 +209,7 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, { /* first check if this is a duplicate constant */ GLint pos; - for (pos = 0; pos < paramList->NumParameters; pos++) { + for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) { const GLfloat *pvals = paramList->ParameterValues[pos]; if (pvals[0] == values[0] && pvals[1] == values[1] && diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index aaf5f96e2a..18ef6d5ccf 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -505,6 +505,8 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone; fpc->FogOption = fp->FogOption; fpc->UsesKill = fp->UsesKill; + fpc->OriginUpperLeft = fp->OriginUpperLeft; + fpc->PixelCenterInteger = fp->PixelCenterInteger; } break; default: diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 0187a2c55f..af9f4170d1 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -108,6 +108,22 @@ _mesa_reference_fragprog(GLcontext *ctx, extern struct gl_program * _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); +static INLINE struct gl_vertex_program * +_mesa_clone_vertex_program(GLcontext *ctx, + const struct gl_vertex_program *prog) +{ + return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base); +} + + +static INLINE struct gl_fragment_program * +_mesa_clone_fragment_program(GLcontext *ctx, + const struct gl_fragment_program *prog) +{ + return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base); +} + + extern GLboolean _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 83098b7350..fe4bddf9ad 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -3117,7 +3117,7 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) if (start >= end) return GL_FALSE; /* degenerate case */ - if (end - start > MAX_FOR_LOOP_UNROLL_ITERATIONS) { + if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) { slang_info_log_print(A->log, "Note: 'for (%s=%d; %s<%d; ++%s)' is too" " many iterations to unroll", diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 852274119c..33964e0c3b 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -239,7 +239,7 @@ parse_general_number(slang_parse_ctx *ctx, float *number) } parse_identifier_str(ctx, &flt); - flt = strdup(flt); + flt = _mesa_strdup(flt); if (!flt) { return 0; } @@ -636,6 +636,38 @@ parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid) } +/* Layout qualifiers */ +#define LAYOUT_QUALIFIER_NONE 0 +#define LAYOUT_QUALIFIER_UPPER_LEFT 1 +#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER 2 + +static int +parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout) +{ + *layout = 0x0; + + /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens, + * terminated by LAYOUT_QUALIFIER_NONE. + */ + while (1) { + GLuint c = *C->I++; + switch (c) { + case LAYOUT_QUALIFIER_NONE: + /* end of list of qualifiers */ + return 1; + case LAYOUT_QUALIFIER_UPPER_LEFT: + *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT; + break; + case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER: + *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT; + break; + default: + assert(0 && "Bad layout qualifier"); + } + } +} + + /* type qualifier */ #define TYPE_QUALIFIER_NONE 0 #define TYPE_QUALIFIER_CONST 1 @@ -907,9 +939,12 @@ static int parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, slang_fully_specified_type * type) { + if (!parse_layout_qualifiers(C, &type->layout)) + RETURN0; + if (!parse_type_variant(C, &type->variant)) RETURN0; - + if (!parse_type_centroid(C, &type->centroid)) RETURN0; @@ -2029,6 +2064,30 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) /** + * Check if it's OK to re-declare a variable with the given new type. + * This happens when applying layout qualifiers to gl_FragCoord or + * (re)setting an array size. + * If redeclaration is OK, return a pointer to the incoming variable + * updated with new type info. Else return NULL; + */ +static slang_variable * +redeclare_variable(slang_variable *var, + const slang_fully_specified_type *type) +{ + if (slang_fully_specified_types_compatible(&var->type, type)) { + /* replace orig var layout with new layout */ + var->type.layout = type->layout; + + /* XXX there may be other type updates in the future here */ + + return var; + } + else + return NULL; +} + + +/** * Parse the initializer for a variable declaration. */ static int @@ -2036,7 +2095,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, const slang_fully_specified_type * type) { GET_CURRENT_CONTEXT(ctx); /* a hack */ - slang_variable *var; + slang_variable *var = NULL, *prevDecl; slang_atom a_name; /* empty init declatator (without name, e.g. "float ;") */ @@ -2046,29 +2105,41 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, a_name = parse_identifier(C); /* check if name is already in this scope */ - if (_slang_variable_locate(O->vars, a_name, GL_FALSE)) { - slang_info_log_error(C->L, + prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope); + if (prevDecl) { + /* A var with this name has already been declared. + * Check if redeclaring the var with a different type/layout is legal. + */ + if (C->global_scope) { + var = redeclare_variable(prevDecl, type); + } + if (!var) { + slang_info_log_error(C->L, "declaration of '%s' conflicts with previous declaration", (char *) a_name); - RETURN0; + RETURN0; + } } - /* make room for the new variable and initialize it */ - var = slang_variable_scope_grow(O->vars); if (!var) { - slang_info_log_memory(C->L); - RETURN0; - } + /* make room for a new variable and initialize it */ + var = slang_variable_scope_grow(O->vars); + if (!var) { + slang_info_log_memory(C->L); + RETURN0; + } - /* copy the declarator type qualifier/etc info, parse the identifier */ - var->type.qualifier = type->qualifier; - var->type.centroid = type->centroid; - var->type.precision = type->precision; - var->type.variant = type->variant; - var->type.array_len = type->array_len; - var->a_name = a_name; - if (var->a_name == SLANG_ATOM_NULL) - RETURN0; + /* copy the declarator type qualifier/etc info, parse the identifier */ + var->type.qualifier = type->qualifier; + var->type.centroid = type->centroid; + var->type.precision = type->precision; + var->type.variant = type->variant; + var->type.layout = type->layout; + var->type.array_len = type->array_len; + var->a_name = a_name; + if (var->a_name == SLANG_ATOM_NULL) + RETURN0; + } switch (*C->I++) { case VARIABLE_NONE: @@ -2169,6 +2240,21 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, RETURN0; } } + + if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT && + var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) { + /* set the program's PixelCenterInteger, OriginUpperLeft fields */ + struct gl_fragment_program *fragProg = + (struct gl_fragment_program *) O->program; + + if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) { + fragProg->OriginUpperLeft = GL_TRUE; + } + if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) { + fragProg->PixelCenterInteger = GL_TRUE; + } + } + return 1; } @@ -2615,6 +2701,11 @@ compile_with_grammar(const char *source, return GL_FALSE; } + if (type == SLANG_UNIT_FRAGMENT_SHADER) { + sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions"); + } + + #if FEATURE_es2_glsl if (sl_pp_context_add_predefined(context, "GL_ES", "1") || sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) { diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c9ecbd275b..0f670360ee 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1122,6 +1122,8 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) return inst; } } +#else + (void) inst; #endif if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index df524ce078..75b0022b56 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -773,7 +773,7 @@ _slang_link(GLcontext *ctx, _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); if (vertProg) { struct gl_vertex_program *linked_vprog = - vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + _mesa_clone_vertex_program(ctx, vertProg); shProg->VertexProgram = linked_vprog; /* refcount OK */ /* vertex program ID not significant; just set Id for debugging purposes */ shProg->VertexProgram->Base.Id = shProg->Name; @@ -783,7 +783,7 @@ _slang_link(GLcontext *ctx, _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); if (fragProg) { struct gl_fragment_program *linked_fprog = - fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + _mesa_clone_fragment_program(ctx, fragProg); shProg->FragmentProgram = linked_fprog; /* refcount OK */ /* vertex program ID not significant; just set Id for debugging purposes */ shProg->FragmentProgram->Base.Id = shProg->Name; diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c index 4a48bc8b8e..a96f2fb4c2 100644 --- a/src/mesa/shader/slang/slang_typeinfo.c +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -258,6 +258,7 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x, z.precision = y->precision; z.variant = y->variant; z.centroid = y->centroid; + z.layout = y->layout; z.array_len = y->array_len; if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) { slang_fully_specified_type_destruct(&z); @@ -269,6 +270,32 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x, } +/** + * Test if two fully specified types are compatible. This is a bit + * looser than testing for equality. We don't check the precision, + * variant, centroid, etc. information. + * XXX this may need some tweaking. + */ +GLboolean +slang_fully_specified_types_compatible(const slang_fully_specified_type * x, + const slang_fully_specified_type * y) +{ + if (!slang_type_specifier_equal(&x->specifier, &y->specifier)) + return GL_FALSE; + + if (x->qualifier == SLANG_QUAL_FIXEDINPUT && + y->qualifier == SLANG_QUAL_VARYING) + ; /* ok */ + else if (x->qualifier != y->qualifier) + return GL_FALSE; + + /* Note: don't compare precision, variant, centroid */ + + /* XXX array length? */ + + return GL_TRUE; +} + GLvoid slang_type_specifier_ctr(slang_type_specifier * self) diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index e6fecd350a..aa5f14ebc7 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -68,6 +68,18 @@ typedef enum slang_type_centroid_ } slang_type_centroid; +/** + * These only apply to gl_FragCoord, but other layout qualifiers may + * appear in the future. + */ +typedef enum slang_layout_qualifier_ +{ + SLANG_LAYOUT_NONE = 0x0, + SLANG_LAYOUT_UPPER_LEFT_BIT = 0x1, + SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT = 0x2 +} slang_layout_qualifier; + + typedef enum slang_type_qualifier_ { SLANG_QUAL_NONE, @@ -170,8 +182,8 @@ slang_type_specifier_equal(const slang_type_specifier *, extern GLboolean -slang_type_specifier_compatible(const slang_type_specifier * x, - const slang_type_specifier * y); +slang_type_specifier_compatible(const slang_type_specifier *x, + const slang_type_specifier *y); typedef struct slang_fully_specified_type_ @@ -181,6 +193,7 @@ typedef struct slang_fully_specified_type_ slang_type_precision precision; slang_type_variant variant; slang_type_centroid centroid; + slang_layout_qualifier layout; GLint array_len; /**< -1 if not an array type */ } slang_fully_specified_type; @@ -194,6 +207,9 @@ extern int slang_fully_specified_type_copy(slang_fully_specified_type *, const slang_fully_specified_type *); +GLboolean +slang_fully_specified_types_compatible(const slang_fully_specified_type * x, + const slang_fully_specified_type * y); typedef struct slang_typeinfo_ |