bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_vs_prog_key key; uint32_t old_prog_offset = brw->vs.base.prog_offset; struct brw_vs_prog_data *old_prog_data = brw->vs.prog_data; bool success; if (!prog->_LinkedShaders[MESA_SHADER_VERTEX]) return true; struct gl_vertex_program *vp = (struct gl_vertex_program *) prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program; struct brw_vertex_program *bvp = brw_vertex_program(vp); memset(&key, 0, sizeof(key)); brw_vec4_setup_prog_key_for_precompile(ctx, &key.base, bvp->id, &vp->Base); success = do_vs_prog(brw, prog, bvp, &key); brw->vs.base.prog_offset = old_prog_offset; brw->vs.prog_data = old_prog_data; return success; }
bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *shader_prog, struct gl_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_vs_prog_key key; uint32_t old_prog_offset = brw->vs.base.prog_offset; struct brw_vs_prog_data *old_prog_data = brw->vs.prog_data; bool success; struct gl_vertex_program *vp = (struct gl_vertex_program *) prog; struct brw_vertex_program *bvp = brw_vertex_program(vp); memset(&key, 0, sizeof(key)); brw_setup_tex_for_precompile(brw, &key.tex, prog); key.program_string_id = bvp->id; key.clamp_vertex_color = (prog->OutputsWritten & (VARYING_BIT_COL0 | VARYING_BIT_COL1 | VARYING_BIT_BFC0 | VARYING_BIT_BFC1)); success = brw_codegen_vs_prog(brw, shader_prog, bvp, &key); brw->vs.base.prog_offset = old_prog_offset; brw->vs.prog_data = old_prog_data; return success; }
bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_vs_prog_key key; if (!prog->_LinkedShaders[MESA_SHADER_VERTEX]) return true; struct gl_vertex_program *vp = (struct gl_vertex_program *) prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program; struct brw_vertex_program *bvp = brw_vertex_program(vp); memset(&key, 0, sizeof(key)); brw_vec4_setup_prog_key_for_precompile(ctx, &key.base, bvp->id, &vp->Base); // In VK, user clipping is triggered solely from the shader. key.base.userclip_active = vp->Base.UsesClipDistanceOut; struct brw_vs_compile c; brw_vs_init_compile(brw, prog, bvp, &key, &c); if (!brw_vs_do_compile(brw, &c)) { brw_vs_clear_compile(brw, &c); return false; } // Rather than defer or upload to cache, hand off // the compile results back to the brw_context brw_shader_program_save_vs_compile(brw->shader_prog, &c); return true; }
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 brwDeleteProgram( GLcontext *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 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); } }
bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_vs_prog_key key; uint32_t old_prog_offset = brw->vs.base.prog_offset; struct brw_vs_prog_data *old_prog_data = brw->vs.prog_data; bool success; if (!prog->_LinkedShaders[MESA_SHADER_VERTEX]) return true; struct gl_vertex_program *vp = (struct gl_vertex_program *) prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program; struct brw_vertex_program *bvp = brw_vertex_program(vp); memset(&key, 0, sizeof(key)); key.base.program_string_id = bvp->id; key.base.clamp_vertex_color = ctx->API == API_OPENGL_COMPAT; unsigned sampler_count = _mesa_fls(vp->Base.SamplersUsed); for (unsigned i = 0; i < sampler_count; i++) { if (vp->Base.ShadowSamplers & (1 << i)) { /* Assume DEPTH_TEXTURE_MODE is the default: X, X, X, 1 */ key.base.tex.swizzles[i] = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); } else { /* Color sampler: assume no swizzling. */ key.base.tex.swizzles[i] = SWIZZLE_XYZW; } } success = do_vs_prog(brw, prog, bvp, &key); brw->vs.base.prog_offset = old_prog_offset; brw->vs.prog_data = old_prog_data; return success; }
static GLboolean brwProgramStringNotify(struct gl_context *ctx, GLenum target, struct gl_program *prog) { struct brw_context *brw = brw_context(ctx); const struct brw_compiler *compiler = brw->intelScreen->compiler; switch (target) { case 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 (newFP == curFP) brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = get_new_program_id(brw->intelScreen); brw_add_texrect_params(prog); prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_FRAGMENT, true); brw_fs_precompile(ctx, NULL, prog); break; } case 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->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } newVP->id = get_new_program_id(brw->intelScreen); /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); brw_add_texrect_params(prog); prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_VERTEX, compiler->scalar_stage[MESA_SHADER_VERTEX]); brw_vs_precompile(ctx, NULL, prog); break; } default: /* * driver->ProgramStringNotify is only called for ARB programs, fixed * function vertex programs, and ir_to_mesa (which isn't used by the * i965 back-end). Therefore, even after geometry shaders are added, * this function should only ever be called with a target of * GL_VERTEX_PROGRAM_ARB or GL_FRAGMENT_PROGRAM_ARB. */ unreachable("Unexpected target in brwProgramStringNotify"); } return true; }
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 (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = brw->program_id++; /* 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; 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; }