X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_program.c;h=b5ec55b2ae3c13c4ec0f3a49dd54116cf38fac8c;hb=1ca55854591d647a485364c2db67899e7f9aaae1;hp=1fd957b3ad66ad55b6475f54e7ae170de4c9a120;hpb=a56da1005d30da60701e33b75d5f4f37096df060;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 1fd957b3ad6..b5ec55b2ae3 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -31,15 +31,17 @@ #include "main/imports.h" #include "main/enums.h" -#include "shader/prog_parameter.h" -#include "shader/program.h" -#include "shader/programopt.h" +#include "main/shaderobj.h" +#include "program/prog_parameter.h" +#include "program/program.h" +#include "program/programopt.h" #include "tnl/tnl.h" +#include "../glsl/ralloc.h" #include "brw_context.h" #include "brw_wm.h" -static void brwBindProgram( GLcontext *ctx, +static void brwBindProgram( struct gl_context *ctx, GLenum target, struct gl_program *prog ) { @@ -55,7 +57,7 @@ static void brwBindProgram( GLcontext *ctx, } } -static struct gl_program *brwNewProgram( GLcontext *ctx, +static struct gl_program *brwNewProgram( struct gl_context *ctx, GLenum target, GLuint id ) { @@ -91,56 +93,64 @@ static struct gl_program *brwNewProgram( GLcontext *ctx, } } -static void brwDeleteProgram( GLcontext *ctx, +static void brwDeleteProgram( struct gl_context *ctx, struct gl_program *prog ) { - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - struct gl_fragment_program *fp = (struct gl_fragment_program *) prog; - struct brw_fragment_program *brw_fp = brw_fragment_program(fp); - - dri_bo_unreference(brw_fp->const_buffer); - } - - if (prog->Target == GL_VERTEX_PROGRAM_ARB) { - struct gl_vertex_program *vp = (struct gl_vertex_program *) prog; - struct brw_vertex_program *brw_vp = brw_vertex_program(vp); - - dri_bo_unreference(brw_vp->const_buffer); - } - _mesa_delete_program( ctx, prog ); } -static GLboolean brwIsProgramNative( GLcontext *ctx, +static GLboolean brwIsProgramNative( struct gl_context *ctx, GLenum target, struct gl_program *prog ) { return GL_TRUE; } +static void +shader_error(struct gl_context *ctx, struct gl_program *prog, const char *msg) +{ + struct gl_shader_program *shader; -static GLboolean brwProgramStringNotify( GLcontext *ctx, + shader = _mesa_lookup_shader_program(ctx, prog->Id); + + if (shader) { + ralloc_strcat(&shader->InfoLog, msg); + shader->LinkStatus = GL_FALSE; + } +} + +static GLboolean brwProgramStringNotify( struct gl_context *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); + _mesa_append_fog_code(ctx, fprog, GL_TRUE); 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 + && shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]) { + return GL_TRUE; + } } else if (target == GL_VERTEX_PROGRAM_ARB) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; @@ -160,7 +170,64 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx, _tnl_program_string(ctx, target, prog); } - /* XXX check if program is legal, within limits */ + /* 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; } @@ -173,5 +240,9 @@ void brwInitFragProgFuncs( struct dd_function_table *functions ) functions->DeleteProgram = brwDeleteProgram; functions->IsProgramNative = brwIsProgramNative; functions->ProgramStringNotify = brwProgramStringNotify; + + functions->NewShader = brw_new_shader; + functions->NewShaderProgram = brw_new_shader_program; + functions->LinkShader = brw_link_shader; }