X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fprogramopt.c;h=92a8831d2085aa3fb164937649289a73c2a7fda2;hb=990aaf87c4740e0225db9f4395541938571727cd;hp=fb2ebe6338f5f5801c4e38e25723ce61fd4765bc;hpb=afe125e0a18ac3886c45c7e6b02b122fb2d327b5;p=mesa.git diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c index fb2ebe6338f..92a8831d208 100644 --- a/src/mesa/program/programopt.c +++ b/src/mesa/program/programopt.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -17,9 +16,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /** @@ -46,7 +46,7 @@ * May be used to implement the position_invariant option. */ static void -_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) +_mesa_insert_mvp_dp4_code(struct gl_context *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -89,7 +89,7 @@ _mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) for (i = 0; i < 4; i++) { newInst[i].Opcode = OPCODE_DP4; newInst[i].DstReg.File = PROGRAM_OUTPUT; - newInst[i].DstReg.Index = VERT_RESULT_HPOS; + newInst[i].DstReg.Index = VARYING_SLOT_POS; newInst[i].DstReg.WriteMask = (WRITEMASK_X << i); newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR; newInst[i].SrcReg[0].Index = mvpRef[i]; @@ -109,12 +109,12 @@ _mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) vprog->Base.Instructions = newInst; vprog->Base.NumInstructions = newLen; vprog->Base.InputsRead |= VERT_BIT_POS; - vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS); + vprog->Base.OutputsWritten |= BITFIELD64_BIT(VARYING_SLOT_POS); } static void -_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +_mesa_insert_mvp_mad_code(struct gl_context *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -188,7 +188,7 @@ _mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) newInst[3].Opcode = OPCODE_MAD; newInst[3].DstReg.File = PROGRAM_OUTPUT; - newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.Index = VARYING_SLOT_POS; newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; newInst[3].SrcReg[0].File = PROGRAM_INPUT; newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; @@ -211,14 +211,14 @@ _mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) vprog->Base.Instructions = newInst; vprog->Base.NumInstructions = newLen; vprog->Base.InputsRead |= VERT_BIT_POS; - vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS); + vprog->Base.OutputsWritten |= BITFIELD64_BIT(VARYING_SLOT_POS); } void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog) { - if (ctx->mvp_with_dp4) + if (ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS) _mesa_insert_mvp_dp4_code( ctx, vprog ); else _mesa_insert_mvp_mad_code( ctx, vprog ); @@ -230,15 +230,25 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) /** - * Append extra instructions onto the given fragment program to implement - * the fog mode specified by fprog->FogOption. - * The fragment.fogcoord input is used to compute the fog blend factor. + * Append instructions to implement fog * - * XXX with a little work, this function could be adapted to add fog code + * The \c fragment.fogcoord input is used to compute the fog blend factor. + * + * \param ctx The GL context + * \param fprog Fragment program that fog instructions will be appended to. + * \param fog_mode Fog mode. One of \c GL_EXP, \c GL_EXP2, or \c GL_LINEAR. + * \param saturate True if writes to color outputs should be clamped to [0, 1] + * + * \note + * This function sets \c VARYING_BIT_FOGC in \c fprog->Base.InputsRead. + * + * \todo With a little work, this function could be adapted to add fog code * to vertex programs too. */ void -_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) +_mesa_append_fog_code(struct gl_context *ctx, + struct gl_fragment_program *fprog, GLenum fog_mode, + GLboolean saturate) { static const gl_state_index fogPStateOpt[STATE_LENGTH] = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 }; @@ -251,9 +261,14 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) GLint fogPRefOpt, fogColorRef; /* state references */ GLuint colorTemp, fogFactorTemp; /* temporary registerss */ - if (fprog->FogOption == GL_NONE) { + if (fog_mode == GL_NONE) { _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program" - " with FogOption == GL_NONE"); + " with fog_mode == GL_NONE"); + return; + } + + if (!(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR))) { + /* program doesn't output color, so nothing to do */ return; } @@ -290,7 +305,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) /* change the instruction to write to colorTemp w/ clamping */ inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = colorTemp; - inst->SaturateMode = SATURATE_ZERO_ONE; + inst->SaturateMode = saturate; /* don't break (may be several writes to result.color) */ } inst++; @@ -300,14 +315,15 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) _mesa_init_instructions(inst, 5); /* emit instructions to compute fog blending factor */ - if (fprog->FogOption == GL_LINEAR) { + /* this is always clamped to [0, 1] regardless of fragment clamping */ + if (fog_mode == GL_LINEAR) { /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */ inst->Opcode = OPCODE_MAD; inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = fogFactorTemp; inst->DstReg.WriteMask = WRITEMASK_X; inst->SrcReg[0].File = PROGRAM_INPUT; - inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC; + inst->SrcReg[0].Index = VARYING_SLOT_FOGC; inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; inst->SrcReg[1].File = PROGRAM_STATE_VAR; inst->SrcReg[1].Index = fogPRefOpt; @@ -319,7 +335,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst++; } else { - ASSERT(fprog->FogOption == GL_EXP || fprog->FogOption == GL_EXP2); + ASSERT(fog_mode == GL_EXP || fog_mode == GL_EXP2); /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */ /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */ /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */ @@ -330,12 +346,12 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst->SrcReg[0].File = PROGRAM_STATE_VAR; inst->SrcReg[0].Index = fogPRefOpt; inst->SrcReg[0].Swizzle - = (fprog->FogOption == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW; + = (fog_mode == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW; inst->SrcReg[1].File = PROGRAM_INPUT; - inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC; + inst->SrcReg[1].Index = VARYING_SLOT_FOGC; inst->SrcReg[1].Swizzle = SWIZZLE_XXXX; inst++; - if (fprog->FogOption == GL_EXP2) { + if (fog_mode == GL_EXP2) { /* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */ inst->Opcode = OPCODE_MUL; inst->DstReg.File = PROGRAM_TEMPORARY; @@ -395,8 +411,8 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) /* install new instructions */ fprog->Base.Instructions = newInst; fprog->Base.NumInstructions = inst - newInst; - fprog->Base.InputsRead |= FRAG_BIT_FOGC; - /* XXX do this? fprog->FogOption = GL_NONE; */ + fprog->Base.InputsRead |= VARYING_BIT_FOGC; + assert(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR)); } @@ -483,9 +499,7 @@ _mesa_count_texture_instructions(struct gl_program *prog) /** * Scan/rewrite program to remove reads of custom (output) registers. - * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING - * (for vertex shaders). - * In GLSL shaders, varying vars can be read and written. + * The passed type has to be PROGRAM_OUTPUT. * On some hardware, trying to read an output register causes trouble. * So, rewrite the program to use a temporary register in this case. */ @@ -493,7 +507,7 @@ void _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) { GLuint i; - GLint outputMap[VERT_RESULT_MAX]; + GLint outputMap[VARYING_SLOT_MAX]; GLuint numVaryingReads = 0; GLboolean usedTemps[MAX_PROGRAM_TEMPS]; GLuint firstTemp = 0; @@ -501,10 +515,9 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) _mesa_find_used_registers(prog, PROGRAM_TEMPORARY, usedTemps, MAX_PROGRAM_TEMPS); - assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); - assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); + assert(type == PROGRAM_OUTPUT); - for (i = 0; i < VERT_RESULT_MAX; i++) + for (i = 0; i < VARYING_SLOT_MAX; i++) outputMap[i] = -1; /* look for instructions which read from varying vars */ @@ -563,7 +576,7 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) /* insert new MOV instructions here */ inst = prog->Instructions + endPos; - for (var = 0; var < VERT_RESULT_MAX; var++) { + for (var = 0; var < VARYING_SLOT_MAX; var++) { if (outputMap[var] >= 0) { /* MOV VAR[var], TEMP[tmp]; */ inst->Opcode = OPCODE_MOV; @@ -585,7 +598,7 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) * This is for debug/test purposes. */ void -_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog) +_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog) { struct prog_instruction *inst; GLuint inputAttr; @@ -602,10 +615,10 @@ _mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog) inst[0].DstReg.File = PROGRAM_OUTPUT; inst[0].DstReg.Index = FRAG_RESULT_COLOR; inst[0].SrcReg[0].File = PROGRAM_INPUT; - if (prog->Base.InputsRead & FRAG_BIT_COL0) - inputAttr = FRAG_ATTRIB_COL0; + if (prog->Base.InputsRead & VARYING_BIT_COL0) + inputAttr = VARYING_SLOT_COL0; else - inputAttr = FRAG_ATTRIB_TEX0; + inputAttr = VARYING_SLOT_TEX0; inst[0].SrcReg[0].Index = inputAttr; inst[1].Opcode = OPCODE_END; @@ -615,7 +628,7 @@ _mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog) prog->Base.Instructions = inst; prog->Base.NumInstructions = 2; - prog->Base.InputsRead = 1 << inputAttr; + prog->Base.InputsRead = BITFIELD64_BIT(inputAttr); prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR); } @@ -626,7 +639,7 @@ _mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog) * transforms vertex position and emits color. */ void -_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog) +_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog) { struct prog_instruction *inst; GLuint inputAttr; @@ -644,7 +657,7 @@ _mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog) inst[0].Opcode = OPCODE_MOV; inst[0].DstReg.File = PROGRAM_OUTPUT; - inst[0].DstReg.Index = VERT_RESULT_COL0; + inst[0].DstReg.Index = VARYING_SLOT_COL0; inst[0].SrcReg[0].File = PROGRAM_INPUT; if (prog->Base.InputsRead & VERT_BIT_COLOR0) inputAttr = VERT_ATTRIB_COLOR0; @@ -659,8 +672,8 @@ _mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog) prog->Base.Instructions = inst; prog->Base.NumInstructions = 2; - prog->Base.InputsRead = 1 << inputAttr; - prog->Base.OutputsWritten = BITFIELD64_BIT(VERT_RESULT_COL0); + prog->Base.InputsRead = BITFIELD64_BIT(inputAttr); + prog->Base.OutputsWritten = BITFIELD64_BIT(VARYING_SLOT_COL0); /* * Now insert code to do standard modelview/projection transformation.