X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_program.c;h=3e52be5d4b74cb9cbeba12fac06fe5609dafe681;hb=0534e958c9d7fc854b64ad38964863e895e5a317;hp=457bc2fc7f41bdba77da35187a61e1a4dfeec317;hpb=d1a9b1f513109c975a5a7ed5a2d0c329b280afe4;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 457bc2fc7f4..3e52be5d4b7 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -31,13 +31,14 @@ #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 "talloc.h" #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" static void brwBindProgram( GLcontext *ctx, @@ -106,18 +107,32 @@ static GLboolean brwIsProgramNative( GLcontext *ctx, return GL_TRUE; } -static void brwProgramStringNotify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) +static void +shader_error(GLcontext *ctx, struct gl_program *prog, const char *msg) +{ + struct gl_shader_program *shader; + + shader = _mesa_lookup_shader_program(ctx, prog->Id); + + if (shader) { + shader->InfoLog = talloc_strdup_append(shader->InfoLog, msg); + shader->LinkStatus = GL_FALSE; + } +} + +static GLboolean brwProgramStringNotify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); - struct intel_context *intel = &brw->intel; + 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); @@ -129,22 +144,19 @@ static void brwProgramStringNotify( GLcontext *ctx, newFP->id = brw->program_id++; newFP->isGLSL = brw_wm_is_glsl(fprog); - /* alloc constant buffer/surface */ - { - const struct gl_program_parameter_list *params = prog->Parameters; - const int size = params->NumParameters * 4 * sizeof(GLfloat); - - /* free old const buffer if too small */ - if (newFP->const_buffer && newFP->const_buffer->size < size) { - dri_bo_unreference(newFP->const_buffer); - newFP->const_buffer = NULL; - } - - if (!newFP->const_buffer) { - newFP->const_buffer = drm_intel_bo_alloc(intel->bufmgr, - "fp_const_buffer", - size, 64); - } + /* 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) { @@ -164,6 +176,66 @@ static void brwProgramStringNotify( GLcontext *ctx, */ _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; } void brwInitFragProgFuncs( struct dd_function_table *functions ) @@ -175,5 +247,10 @@ 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->CompileShader = brw_compile_shader; + functions->LinkShader = brw_link_shader; }