static GLboolean brwProgramStringNotify( GLcontext *ctx, GLenum target, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); int i; if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; struct brw_fragment_program *newFP = brw_fragment_program(fprog); const struct brw_fragment_program *curFP = brw_fragment_program_const(brw->fragment_program); if (fprog->FogOption) { _mesa_append_fog_code(ctx, fprog); fprog->FogOption = GL_NONE; } if (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = brw->program_id++; newFP->isGLSL = brw_wm_is_glsl(fprog); } else if (target == GL_VERTEX_PROGRAM_ARB) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; struct brw_vertex_program *newVP = brw_vertex_program(vprog); const struct brw_vertex_program *curVP = brw_vertex_program_const(brw->vertex_program); if (newVP == curVP) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } newVP->id = brw->program_id++; /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); } /* Reject programs with subroutines, which are totally broken at the moment * (all program flows return when any program flow returns, and * the VS also hangs if a function call calls a function. * * See piglit glsl-{vs,fs}-functions-[23] tests. */ for (i = 0; i < prog->NumInstructions; i++) { if (prog->Instructions[i].Opcode == OPCODE_CAL) { shader_error(ctx, prog, "i965 driver doesn't yet support uninlined function " "calls. Move to using a single return statement at " "the end of the function to work around it."); return GL_FALSE; } } return GL_TRUE; }
static void i915ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { if (target == GL_FRAGMENT_PROGRAM_ARB) { struct i915_fragment_program *p = (struct i915_fragment_program *) prog; p->translated = 0; /* Hack: make sure fog is correctly enabled according to this * fragment program's fog options. */ if (p->FragProg.FogOption) { /* add extra instructions to do fog, then turn off FogOption field */ _mesa_append_fog_code(ctx, &p->FragProg); p->FragProg.FogOption = GL_NONE; } } _tnl_program_string(ctx, target, prog); }
static void brwProgramStringNotify( GLcontext *ctx, GLenum target, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; struct brw_fragment_program *newFP = brw_fragment_program(fprog); const struct brw_fragment_program *curFP = brw_fragment_program_const(brw->fragment_program); if (fprog->FogOption) { _mesa_append_fog_code(ctx, fprog); fprog->FogOption = GL_NONE; } if (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = brw->program_id++; newFP->isGLSL = brw_wm_is_glsl(fprog); } else if (target == GL_VERTEX_PROGRAM_ARB) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; struct brw_vertex_program *newVP = brw_vertex_program(vprog); const struct brw_vertex_program *curVP = brw_vertex_program_const(brw->vertex_program); if (newVP == curVP) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } newVP->id = brw->program_id++; /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); } }
void _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target, const GLvoid *str, GLsizei len, struct gl_fragment_program *program) { struct gl_program prog; struct asm_parser_state state; GLuint i; ASSERT(target == GL_FRAGMENT_PROGRAM_ARB); memset(&prog, 0, sizeof(prog)); memset(&state, 0, sizeof(state)); state.prog = &prog; if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &state)) { /* Error in the program. Just return. */ return; } if (program->Base.String != NULL) free(program->Base.String); /* Copy the relevant contents of the arb_program struct into the * fragment_program struct. */ program->Base.String = prog.String; program->Base.NumInstructions = prog.NumInstructions; program->Base.NumTemporaries = prog.NumTemporaries; program->Base.NumParameters = prog.NumParameters; program->Base.NumAttributes = prog.NumAttributes; program->Base.NumAddressRegs = prog.NumAddressRegs; program->Base.NumNativeInstructions = prog.NumNativeInstructions; program->Base.NumNativeTemporaries = prog.NumNativeTemporaries; program->Base.NumNativeParameters = prog.NumNativeParameters; program->Base.NumNativeAttributes = prog.NumNativeAttributes; program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; program->Base.NumAluInstructions = prog.NumAluInstructions; program->Base.NumTexInstructions = prog.NumTexInstructions; program->Base.NumTexIndirections = prog.NumTexIndirections; program->Base.NumNativeAluInstructions = prog.NumAluInstructions; program->Base.NumNativeTexInstructions = prog.NumTexInstructions; program->Base.NumNativeTexIndirections = prog.NumTexIndirections; program->Base.InputsRead = prog.InputsRead; program->Base.OutputsWritten = prog.OutputsWritten; program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { program->Base.TexturesUsed[i] = prog.TexturesUsed[i]; if (prog.TexturesUsed[i]) program->Base.SamplersUsed |= (1 << i); } program->Base.ShadowSamplers = prog.ShadowSamplers; program->OriginUpperLeft = state.option.OriginUpperLeft; program->PixelCenterInteger = state.option.PixelCenterInteger; program->UsesKill = state.fragment.UsesKill; program->UsesDFdy = state.fragment.UsesDFdy; if (program->Base.Instructions) free(program->Base.Instructions); program->Base.Instructions = prog.Instructions; if (program->Base.Parameters) _mesa_free_parameter_list(program->Base.Parameters); program->Base.Parameters = prog.Parameters; /* Append fog instructions now if the program has "OPTION ARB_fog_exp" * or similar. We used to leave this up to drivers, but it appears * there's no hardware that wants to do fog in a discrete stage separate * from the fragment shader. */ if (state.option.Fog != OPTION_NONE) { static const GLenum fog_modes[4] = { GL_NONE, GL_EXP, GL_EXP2, GL_LINEAR }; /* XXX: we should somehow recompile this to remove clamping if disabled * On the ATI driver, this is unclampled if fragment clamping is disabled */ _mesa_append_fog_code(ctx, program, fog_modes[state.option.Fog], GL_TRUE); } #if DEBUG_FP printf("____________Fragment program %u ________\n", program->Base.Id); _mesa_print_program(&program->Base); #endif }
static GLboolean brwProgramStringNotify( GLcontext *ctx, GLenum target, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); int i; if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; struct brw_fragment_program *newFP = brw_fragment_program(fprog); const struct brw_fragment_program *curFP = brw_fragment_program_const(brw->fragment_program); struct gl_shader_program *shader_program; if (fprog->FogOption) { _mesa_append_fog_code(ctx, fprog); fprog->FogOption = GL_NONE; } if (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = brw->program_id++; newFP->isGLSL = brw_wm_is_glsl(fprog); /* Don't reject fragment shaders for their Mesa IR state when we're * using the new FS backend. */ shader_program = _mesa_lookup_shader_program(ctx, prog->Id); if (shader_program) { for (i = 0; i < shader_program->_NumLinkedShaders; i++) { struct brw_shader *shader; shader = (struct brw_shader *)shader_program->_LinkedShaders[i]; if (shader->base.Type == GL_FRAGMENT_SHADER && shader->ir) { return GL_TRUE; } } } } else if (target == GL_VERTEX_PROGRAM_ARB) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; struct brw_vertex_program *newVP = brw_vertex_program(vprog); const struct brw_vertex_program *curVP = brw_vertex_program_const(brw->vertex_program); if (newVP == curVP) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } newVP->id = brw->program_id++; /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); } /* Reject programs with subroutines, which are totally broken at the moment * (all program flows return when any program flow returns, and * the VS also hangs if a function call calls a function. * * See piglit glsl-{vs,fs}-functions-[23] tests. */ for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; int r; if (prog->Instructions[i].Opcode == OPCODE_CAL) { shader_error(ctx, prog, "i965 driver doesn't yet support uninlined function " "calls. Move to using a single return statement at " "the end of the function to work around it.\n"); return GL_FALSE; } if (prog->Instructions[i].Opcode == OPCODE_RET) { shader_error(ctx, prog, "i965 driver doesn't yet support \"return\" " "from main().\n"); return GL_FALSE; } for (r = 0; r < _mesa_num_inst_src_regs(inst->Opcode); r++) { if (prog->Instructions[i].SrcReg[r].RelAddr && prog->Instructions[i].SrcReg[r].File == PROGRAM_INPUT) { shader_error(ctx, prog, "Variable indexing of shader inputs unsupported\n"); return GL_FALSE; } } if (target == GL_FRAGMENT_PROGRAM_ARB && prog->Instructions[i].DstReg.RelAddr && prog->Instructions[i].DstReg.File == PROGRAM_OUTPUT) { shader_error(ctx, prog, "Variable indexing of FS outputs unsupported\n"); return GL_FALSE; } if (target == GL_FRAGMENT_PROGRAM_ARB) { if ((prog->Instructions[i].DstReg.RelAddr && prog->Instructions[i].DstReg.File == PROGRAM_TEMPORARY) || (prog->Instructions[i].SrcReg[0].RelAddr && prog->Instructions[i].SrcReg[0].File == PROGRAM_TEMPORARY) || (prog->Instructions[i].SrcReg[1].RelAddr && prog->Instructions[i].SrcReg[1].File == PROGRAM_TEMPORARY) || (prog->Instructions[i].SrcReg[2].RelAddr && prog->Instructions[i].SrcReg[2].File == PROGRAM_TEMPORARY)) { shader_error(ctx, prog, "Variable indexing of variable arrays in the FS " "unsupported\n"); return GL_FALSE; } } } return GL_TRUE; }