diff options
Diffstat (limited to 'src/mesa/program')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 9 | ||||
-rw-r--r-- | src/mesa/program/prog_execute.c | 34 | ||||
-rw-r--r-- | src/mesa/program/prog_opt_constant_fold.c | 2 | ||||
-rw-r--r-- | src/mesa/program/prog_print.c | 10 | ||||
-rw-r--r-- | src/mesa/program/program.c | 59 | ||||
-rw-r--r-- | src/mesa/program/program.h | 80 | ||||
-rw-r--r-- | src/mesa/program/program_parse_extra.c | 50 |
7 files changed, 211 insertions, 33 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 3bffe90ff1f..b8b082e2a59 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -534,6 +534,7 @@ type_size(const struct glsl_type *type) return size; case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: + case GLSL_TYPE_SUBROUTINE: /* Samplers take up one slot in UNIFORMS[], but they're baked in * at link time. */ @@ -1343,6 +1344,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_unop_dFdx_fine: case ir_unop_dFdy_coarse: case ir_unop_dFdy_fine: + case ir_unop_subroutine_to_int: assert(!"not supported"); break; @@ -2385,7 +2387,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program ir_variable *var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_uniform) - || var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0)) + || var->is_in_buffer_block() || (strncmp(var->name, "gl_", 3) == 0)) continue; add.process(var); @@ -2452,6 +2454,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, break; case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: + case GLSL_TYPE_SUBROUTINE: format = uniform_native; columns = 1; break; @@ -2912,7 +2915,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) progress = - lower_variable_index_to_cond_assign(ir, + lower_variable_index_to_cond_assign(prog->_LinkedShaders[i]->Stage, ir, options->EmitNoIndirectInput, options->EmitNoIndirectOutput, options->EmitNoIndirectTemp, @@ -2977,6 +2980,8 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->LinkStatus) { if (!ctx->Driver.LinkShader(ctx, prog)) { prog->LinkStatus = GL_FALSE; + } else { + build_program_resource_list(ctx, prog); } } diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c index 46260b54882..2c52d0db508 100644 --- a/src/mesa/program/prog_execute.c +++ b/src/mesa/program/prog_execute.c @@ -623,7 +623,7 @@ _mesa_execute_program(struct gl_context * ctx, GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] - = (GLfloat) cos(a[0]); + = cosf(a[0]); store_vector4(inst, machine, result); } break; @@ -723,7 +723,7 @@ _mesa_execute_program(struct gl_context * ctx, * result.z = result.x * APPX(result.y) * We do what the ARB extension says. */ - q[2] = (GLfloat) pow(2.0, t[0]); + q[2] = exp2f(t[0]); } q[1] = t[0] - floor_t0; q[3] = 1.0F; @@ -734,7 +734,7 @@ _mesa_execute_program(struct gl_context * ctx, { GLfloat a[4], result[4], val; fetch_vector1(&inst->SrcReg[0], machine, a); - val = (GLfloat) pow(2.0, a[0]); + val = exp2f(a[0]); /* if (IS_INF_OR_NAN(val)) val = 1.0e10; @@ -776,7 +776,7 @@ _mesa_execute_program(struct gl_context * ctx, if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { GLfloat a[4]; fetch_vector1(&inst->SrcReg[0], machine, a); - cond = (a[0] != 0.0); + cond = (a[0] != 0.0F); } else { cond = eval_condition(machine, inst); @@ -834,7 +834,7 @@ _mesa_execute_program(struct gl_context * ctx, val = -FLT_MAX; } else { - val = (float)(log(a[0]) * 1.442695F); + val = logf(a[0]) * 1.442695F; } result[0] = result[1] = result[2] = result[3] = val; store_vector4(inst, machine, result); @@ -853,10 +853,10 @@ _mesa_execute_program(struct gl_context * ctx, result[1] = a[0]; /* XXX we could probably just use pow() here */ if (a[0] > 0.0F) { - if (a[1] == 0.0 && a[3] == 0.0) + if (a[1] == 0.0F && a[3] == 0.0F) result[2] = 1.0F; else - result[2] = (GLfloat) pow(a[1], a[3]); + result[2] = powf(a[1], a[3]); } else { result[2] = 0.0F; @@ -886,12 +886,12 @@ _mesa_execute_program(struct gl_context * ctx, int exponent; GLfloat mantissa = frexpf(t[0], &exponent); q[0] = (GLfloat) (exponent - 1); - q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ + q[1] = 2.0F * mantissa; /* map [.5, 1) -> [1, 2) */ /* The fast LOG2 macro doesn't meet the precision * requirements. */ - q[2] = (float)(log(t[0]) * 1.442695F); + q[2] = logf(t[0]) * 1.442695F; } } else { @@ -1051,7 +1051,7 @@ _mesa_execute_program(struct gl_context * ctx, fetch_vector1(&inst->SrcReg[0], machine, a); fetch_vector1(&inst->SrcReg[1], machine, b); result[0] = result[1] = result[2] = result[3] - = (GLfloat) pow(a[0], b[0]); + = powf(a[0], b[0]); store_vector4(inst, machine, result); } break; @@ -1095,10 +1095,10 @@ _mesa_execute_program(struct gl_context * ctx, { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = (GLfloat) cos(a[0]); - result[1] = (GLfloat) sin(a[0]); - result[2] = 0.0; /* undefined! */ - result[3] = 0.0; /* undefined! */ + result[0] = cosf(a[0]); + result[1] = sinf(a[0]); + result[2] = 0.0F; /* undefined! */ + result[3] = 0.0F; /* undefined! */ store_vector4(inst, machine, result); } break; @@ -1161,7 +1161,7 @@ _mesa_execute_program(struct gl_context * ctx, GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] - = (GLfloat) sin(a[0]); + = sinf(a[0]); store_vector4(inst, machine, result); } break; @@ -1360,7 +1360,7 @@ _mesa_execute_program(struct gl_context * ctx, * zero, we'd probably be fine except for an assert in * IROUND_POS() which gets triggered by the inf values created. */ - if (texcoord[3] != 0.0) { + if (texcoord[3] != 0.0F) { texcoord[0] /= texcoord[3]; texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; @@ -1380,7 +1380,7 @@ _mesa_execute_program(struct gl_context * ctx, fetch_vector4(&inst->SrcReg[0], machine, texcoord); if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && - texcoord[3] != 0.0) { + texcoord[3] != 0.0F) { texcoord[0] /= texcoord[3]; texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; diff --git a/src/mesa/program/prog_opt_constant_fold.c b/src/mesa/program/prog_opt_constant_fold.c index 3811c0d8aa6..e2518e660e6 100644 --- a/src/mesa/program/prog_opt_constant_fold.c +++ b/src/mesa/program/prog_opt_constant_fold.c @@ -38,6 +38,8 @@ src_regs_are_constant(const struct prog_instruction *inst, unsigned num_srcs) for (i = 0; i < num_srcs; i++) { if (inst->SrcReg[i].File != PROGRAM_CONSTANT) return false; + if (inst->SrcReg[i].RelAddr) + return false; } return true; diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c index e4faa63c06f..bb7c2c6e527 100644 --- a/src/mesa/program/prog_print.c +++ b/src/mesa/program/prog_print.c @@ -147,6 +147,8 @@ arb_input_attrib_string(GLuint index, GLenum progType) "fragment.(twenty-one)", /* VARYING_SLOT_VIEWPORT */ "fragment.(twenty-two)", /* VARYING_SLOT_FACE */ "fragment.(twenty-three)", /* VARYING_SLOT_PNTC */ + "fragment.(twenty-four)", /* VARYING_SLOT_TESS_LEVEL_OUTER */ + "fragment.(twenty-five)", /* VARYING_SLOT_TESS_LEVEL_INNER */ "fragment.varying[0]", "fragment.varying[1]", "fragment.varying[2]", @@ -272,6 +274,8 @@ arb_output_attrib_string(GLuint index, GLenum progType) "result.(twenty-one)", /* VARYING_SLOT_VIEWPORT */ "result.(twenty-two)", /* VARYING_SLOT_FACE */ "result.(twenty-three)", /* VARYING_SLOT_PNTC */ + "result.(twenty-four)", /* VARYING_SLOT_TESS_LEVEL_OUTER */ + "result.(twenty-five)", /* VARYING_SLOT_TESS_LEVEL_INNER */ "result.varying[0]", "result.varying[1]", "result.varying[2]", @@ -1015,6 +1019,12 @@ _mesa_write_shader_to_file(const struct gl_shader *shader) case MESA_SHADER_FRAGMENT: type = "frag"; break; + case MESA_SHADER_TESS_CTRL: + type = "tesc"; + break; + case MESA_SHADER_TESS_EVAL: + type = "tese"; + break; case MESA_SHADER_VERTEX: type = "vert"; break; diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index c13e61b1630..2d03bba3d12 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -286,6 +286,38 @@ _mesa_init_compute_program(struct gl_context *ctx, /** + * Initialize a new tessellation control program object. + */ +struct gl_program * +_mesa_init_tess_ctrl_program(struct gl_context *ctx, + struct gl_tess_ctrl_program *prog, + GLenum target, GLuint id) +{ + if (prog) { + init_program_struct(&prog->Base, target, id); + return &prog->Base; + } + return NULL; +} + + +/** + * Initialize a new tessellation evaluation program object. + */ +struct gl_program * +_mesa_init_tess_eval_program(struct gl_context *ctx, + struct gl_tess_eval_program *prog, + GLenum target, GLuint id) +{ + if (prog) { + init_program_struct(&prog->Base, target, id); + return &prog->Base; + } + return NULL; +} + + +/** * Initialize a new geometry program object. */ struct gl_program * @@ -333,6 +365,16 @@ _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id) CALLOC_STRUCT(gl_geometry_program), target, id); break; + case GL_TESS_CONTROL_PROGRAM_NV: + prog = _mesa_init_tess_ctrl_program(ctx, + CALLOC_STRUCT(gl_tess_ctrl_program), + target, id); + break; + case GL_TESS_EVALUATION_PROGRAM_NV: + prog = _mesa_init_tess_eval_program(ctx, + CALLOC_STRUCT(gl_tess_eval_program), + target, id); + break; case GL_COMPUTE_PROGRAM_NV: prog = _mesa_init_compute_program(ctx, CALLOC_STRUCT(gl_compute_program), @@ -554,6 +596,23 @@ _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog) gpc->UsesStreams = gp->UsesStreams; } break; + case GL_TESS_CONTROL_PROGRAM_NV: + { + const struct gl_tess_ctrl_program *tcp = gl_tess_ctrl_program_const(prog); + struct gl_tess_ctrl_program *tcpc = gl_tess_ctrl_program(clone); + tcpc->VerticesOut = tcp->VerticesOut; + } + break; + case GL_TESS_EVALUATION_PROGRAM_NV: + { + const struct gl_tess_eval_program *tep = gl_tess_eval_program_const(prog); + struct gl_tess_eval_program *tepc = gl_tess_eval_program(clone); + tepc->PrimitiveMode = tep->PrimitiveMode; + tepc->Spacing = tep->Spacing; + tepc->VertexOrder = tep->VertexOrder; + tepc->PointMode = tep->PointMode; + } + break; default: _mesa_problem(NULL, "Unexpected target in _mesa_clone_program"); } diff --git a/src/mesa/program/program.h b/src/mesa/program/program.h index 2d92ab2f118..a894147cafd 100644 --- a/src/mesa/program/program.h +++ b/src/mesa/program/program.h @@ -79,6 +79,16 @@ _mesa_init_fragment_program(struct gl_context *ctx, GLenum target, GLuint id); extern struct gl_program * +_mesa_init_tess_ctrl_program(struct gl_context *ctx, + struct gl_tess_ctrl_program *prog, + GLenum target, GLuint id); + +extern struct gl_program * +_mesa_init_tess_eval_program(struct gl_context *ctx, + struct gl_tess_eval_program *prog, + GLenum target, GLuint id); + +extern struct gl_program * _mesa_init_geometry_program(struct gl_context *ctx, struct gl_geometry_program *prog, GLenum target, GLuint id); @@ -147,6 +157,25 @@ _mesa_reference_compprog(struct gl_context *ctx, (struct gl_program *) prog); } + +static inline void +_mesa_reference_tesscprog(struct gl_context *ctx, + struct gl_tess_ctrl_program **ptr, + struct gl_tess_ctrl_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} + +static inline void +_mesa_reference_tesseprog(struct gl_context *ctx, + struct gl_tess_eval_program **ptr, + struct gl_tess_eval_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} + extern struct gl_program * _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog); @@ -157,6 +186,20 @@ _mesa_clone_vertex_program(struct gl_context *ctx, return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base); } +static inline struct gl_tess_ctrl_program * +_mesa_clone_tess_ctrl_program(struct gl_context *ctx, + const struct gl_tess_ctrl_program *prog) +{ + return (struct gl_tess_ctrl_program *) _mesa_clone_program(ctx, &prog->Base); +} + +static inline struct gl_tess_eval_program * +_mesa_clone_tess_eval_program(struct gl_context *ctx, + const struct gl_tess_eval_program *prog) +{ + return (struct gl_tess_eval_program *) _mesa_clone_program(ctx, &prog->Base); +} + static inline struct gl_geometry_program * _mesa_clone_geometry_program(struct gl_context *ctx, const struct gl_geometry_program *prog) @@ -216,6 +259,10 @@ _mesa_program_enum_to_shader_stage(GLenum v) return MESA_SHADER_FRAGMENT; case GL_GEOMETRY_PROGRAM_NV: return MESA_SHADER_GEOMETRY; + case GL_TESS_CONTROL_PROGRAM_NV: + return MESA_SHADER_TESS_CTRL; + case GL_TESS_EVALUATION_PROGRAM_NV: + return MESA_SHADER_TESS_EVAL; case GL_COMPUTE_PROGRAM_NV: return MESA_SHADER_COMPUTE; default: @@ -235,6 +282,10 @@ _mesa_shader_stage_to_program(unsigned stage) return GL_FRAGMENT_PROGRAM_ARB; case MESA_SHADER_GEOMETRY: return GL_GEOMETRY_PROGRAM_NV; + case MESA_SHADER_TESS_CTRL: + return GL_TESS_CONTROL_PROGRAM_NV; + case MESA_SHADER_TESS_EVAL: + return GL_TESS_EVALUATION_PROGRAM_NV; case MESA_SHADER_COMPUTE: return GL_COMPUTE_PROGRAM_NV; } @@ -244,7 +295,9 @@ _mesa_shader_stage_to_program(unsigned stage) } -/* Cast wrappers from gl_program to gl_vertex/geometry/fragment_program */ +/* Cast wrappers from gl_program to derived program types. + * (e.g. gl_vertex_program) + */ static inline struct gl_fragment_program * gl_fragment_program(struct gl_program *prog) @@ -297,6 +350,31 @@ gl_compute_program_const(const struct gl_program *prog) return (const struct gl_compute_program *) prog; } +static inline struct gl_tess_ctrl_program * +gl_tess_ctrl_program(struct gl_program *prog) +{ + return (struct gl_tess_ctrl_program *) prog; +} + +static inline const struct gl_tess_ctrl_program * +gl_tess_ctrl_program_const(const struct gl_program *prog) +{ + return (const struct gl_tess_ctrl_program *) prog; +} + + +static inline struct gl_tess_eval_program * +gl_tess_eval_program(struct gl_program *prog) +{ + return (struct gl_tess_eval_program *) prog; +} + +static inline const struct gl_tess_eval_program * +gl_tess_eval_program_const(const struct gl_program *prog) +{ + return (const struct gl_tess_eval_program *) prog; +} + #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesa/program/program_parse_extra.c b/src/mesa/program/program_parse_extra.c index 32b54afc57b..71f86d13ace 100644 --- a/src/mesa/program/program_parse_extra.c +++ b/src/mesa/program/program_parse_extra.c @@ -163,6 +163,8 @@ _mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option) int _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) { + unsigned fog_option; + /* All of the options currently supported start with "ARB_". The code is * currently structured with nested if-statements because eventually options * that start with "NV_" will be supported. This structure will result in @@ -177,20 +179,42 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) if (strncmp(option, "fog_", 4) == 0) { option += 4; - if (state->option.Fog == OPTION_NONE) { - if (strcmp(option, "exp") == 0) { - state->option.Fog = OPTION_FOG_EXP; - return 1; - } else if (strcmp(option, "exp2") == 0) { - state->option.Fog = OPTION_FOG_EXP2; - return 1; - } else if (strcmp(option, "linear") == 0) { - state->option.Fog = OPTION_FOG_LINEAR; - return 1; - } - } + if (strcmp(option, "exp") == 0) { + fog_option = OPTION_FOG_EXP; + } else if (strcmp(option, "exp2") == 0) { + fog_option = OPTION_FOG_EXP2; + } else if (strcmp(option, "linear") == 0) { + fog_option = OPTION_FOG_LINEAR; + } else { + /* invalid option */ + return 0; + } - return 0; + if (state->option.Fog == OPTION_NONE) { + state->option.Fog = fog_option; + return 1; + } + + /* The ARB_fragment_program specification instructs us to handle + * redundant options in two seemingly contradictory ways: + * + * Section 3.11.4.5.1 says: + * "Only one fog application option may be specified by any given + * fragment program. A fragment program that specifies more than one + * of the program options "ARB_fog_exp", "ARB_fog_exp2", and + * "ARB_fog_linear", will fail to load." + * + * Issue 27 says: + * "The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and + * ARB_fog_linear. As these options are mutually exclusive by + * nature, specifying more than one is not useful. If more than one + * is specified, the last one encountered in the <optionSequence> + * will be the one to actually modify the execution environment." + * + * We choose to allow programs to specify the same OPTION redundantly, + * but fail to load programs that specify contradictory options. + */ + return state->option.Fog == fog_option ? 1 : 0; } else if (strncmp(option, "precision_hint_", 15) == 0) { option += 15; |