X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fprogram%2Fprog_execute.c;h=9ee2f20145b69994c9c9d5d3cd7de540c8cea0d0;hb=fd8655aa7a78f3ded44e9dee572f17309a44a945;hp=6c50f409d29a9b66a3b30637364a0e54bc22d691;hpb=b4ad7c28430e4084d843cd99cf68209e95363963;p=mesa.git diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c index 6c50f409d29..9ee2f20145b 100644 --- a/src/mesa/program/prog_execute.c +++ b/src/mesa/program/prog_execute.c @@ -37,7 +37,7 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" +#include "main/macros.h" #include "prog_execute.h" #include "prog_instruction.h" #include "prog_parameter.h" @@ -79,28 +79,11 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - -/** - * Return TRUE for +0 and other positive values, FALSE otherwise. - * Used for RCC opcode. - */ -static INLINE GLboolean -positive(float x) -{ - fi_type fi; - fi.f = x; - if (fi.i & 0x80000000) - return GL_FALSE; - return GL_TRUE; -} - - - /** * Return a pointer to the 4-element float vector specified by the given * source register. */ -static INLINE const GLfloat * +static inline const GLfloat * get_src_register_pointer(const struct prog_src_register *source, const struct gl_program_machine *machine) { @@ -153,11 +136,13 @@ get_src_register_pointer(const struct prog_src_register *source, case PROGRAM_CONSTANT: /* Fallthrough */ case PROGRAM_UNIFORM: - /* Fallthrough */ - case PROGRAM_NAMED_PARAM: if (reg >= (GLint) prog->Parameters->NumParameters) return ZeroVec; - return prog->Parameters->ParameterValues[reg]; + return (GLfloat *) prog->Parameters->ParameterValues[reg]; + + case PROGRAM_SYSTEM_VALUE: + assert(reg < Elements(machine->SystemValues)); + return machine->SystemValues[reg]; default: _mesa_problem(NULL, @@ -172,7 +157,7 @@ get_src_register_pointer(const struct prog_src_register *source, * Return a pointer to the 4-element float vector specified by the given * destination register. */ -static INLINE GLfloat * +static inline GLfloat * get_dst_register_pointer(const struct prog_dst_register *dest, struct gl_program_machine *machine) { @@ -198,9 +183,6 @@ get_dst_register_pointer(const struct prog_dst_register *dest, return dummyReg; return machine->Outputs[reg]; - case PROGRAM_WRITE_ONLY: - return dummyReg; - default: _mesa_problem(NULL, "Invalid dest register file %d in get_dst_register_pointer()", @@ -296,7 +278,7 @@ fetch_vector4ui(const struct prog_src_register *source, * XXX this currently only works for fragment program input attribs. */ static void -fetch_vector4_deriv(GLcontext * ctx, +fetch_vector4_deriv(struct gl_context * ctx, const struct prog_src_register *source, const struct gl_program_machine *machine, char xOrY, GLfloat result[4]) @@ -379,8 +361,8 @@ fetch_vector1ui(const struct prog_src_register *source, /** * Fetch texel from texture. Use partial derivatives when possible. */ -static INLINE void -fetch_texel(GLcontext *ctx, +static inline void +fetch_texel(struct gl_context *ctx, const struct gl_program_machine *machine, const struct prog_instruction *inst, const GLfloat texcoord[4], GLfloat lodBias, @@ -409,7 +391,7 @@ fetch_texel(GLcontext *ctx, /** * Test value against zero and return GT, LT, EQ or UN if NaN. */ -static INLINE GLuint +static inline GLuint generate_cc(float value) { if (value != value) @@ -426,7 +408,7 @@ generate_cc(float value) * Test if the ccMaskRule is satisfied by the given condition code. * Used to mask destination writes according to the current condition code. */ -static INLINE GLboolean +static inline GLboolean test_cc(GLuint condCode, GLuint ccMaskRule) { switch (ccMaskRule) { @@ -447,7 +429,7 @@ test_cc(GLuint condCode, GLuint ccMaskRule) * Evaluate the 4 condition codes against a predicate and return GL_TRUE * or GL_FALSE to indicate result. */ -static INLINE GLboolean +static inline GLboolean eval_condition(const struct gl_program_machine *machine, const struct prog_instruction *inst) { @@ -630,12 +612,12 @@ store_vector4ui(const struct prog_instruction *inst, * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. */ GLboolean -_mesa_execute_program(GLcontext * ctx, +_mesa_execute_program(struct gl_context * ctx, const struct gl_program *program, struct gl_program_machine *machine) { const GLuint numInst = program->NumInstructions; - const GLuint maxExec = 10000; + const GLuint maxExec = 65536; GLuint pc, numExec = 0; machine->CurProgram = program; @@ -724,13 +706,6 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_ENDSUB: /* end subroutine */ break; - case OPCODE_BRA: /* branch (conditional) */ - if (eval_condition(machine, inst)) { - /* take branch */ - /* Subtract 1 here since we'll do pc++ below */ - pc = inst->BranchTarget - 1; - } - break; case OPCODE_BRK: /* break out of loop (conditional) */ ASSERT(program->Instructions[inst->BranchTarget].Opcode == OPCODE_ENDLOOP); @@ -771,6 +746,13 @@ _mesa_execute_program(GLcontext * ctx, result[2] = a[2] < 0.0F ? b[2] : c[2]; result[3] = a[3] < 0.0F ? b[3] : c[3]; store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%g %g %g %g) : (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } } break; case OPCODE_COS: @@ -1297,8 +1279,8 @@ _mesa_execute_program(GLcontext * ctx, fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = CLAMP(a[0], 0.0F, 1.0F); a[1] = CLAMP(a[1], 0.0F, 1.0F); - usx = IROUND(a[0] * 65535.0F); - usy = IROUND(a[1] * 65535.0F); + usx = F_TO_I(a[0] * 65535.0F); + usy = F_TO_I(a[1] * 65535.0F); result[0] = result[1] = result[2] = @@ -1315,10 +1297,10 @@ _mesa_execute_program(GLcontext * ctx, a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); - ubx = IROUND(127.0F * a[0] + 128.0F); - uby = IROUND(127.0F * a[1] + 128.0F); - ubz = IROUND(127.0F * a[2] + 128.0F); - ubw = IROUND(127.0F * a[3] + 128.0F); + ubx = F_TO_I(127.0F * a[0] + 128.0F); + uby = F_TO_I(127.0F * a[1] + 128.0F); + ubz = F_TO_I(127.0F * a[2] + 128.0F); + ubw = F_TO_I(127.0F * a[3] + 128.0F); result[0] = result[1] = result[2] = @@ -1335,10 +1317,10 @@ _mesa_execute_program(GLcontext * ctx, a[1] = CLAMP(a[1], 0.0F, 1.0F); a[2] = CLAMP(a[2], 0.0F, 1.0F); a[3] = CLAMP(a[3], 0.0F, 1.0F); - ubx = IROUND(255.0F * a[0]); - uby = IROUND(255.0F * a[1]); - ubz = IROUND(255.0F * a[2]); - ubw = IROUND(255.0F * a[3]); + ubx = F_TO_I(255.0F * a[0]); + uby = F_TO_I(255.0F * a[1]); + ubz = F_TO_I(255.0F * a[2]); + ubw = F_TO_I(255.0F * a[3]); result[0] = result[1] = result[2] = @@ -1356,43 +1338,6 @@ _mesa_execute_program(GLcontext * ctx, store_vector4(inst, machine, result); } break; - case OPCODE_RCC: /* clamped riciprocal */ - { - const float largest = 1.884467e+19, smallest = 5.42101e-20; - GLfloat a[4], r, result[4]; - fetch_vector1(&inst->SrcReg[0], machine, a); - if (DEBUG_PROG) { - if (a[0] == 0) - printf("RCC(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCC(inf)\n"); - } - if (a[0] == 1.0F) { - r = 1.0F; - } - else { - r = 1.0F / a[0]; - } - if (positive(r)) { - if (r > largest) { - r = largest; - } - else if (r < smallest) { - r = smallest; - } - } - else { - if (r < -largest) { - r = -largest; - } - else if (r > -smallest) { - r = -smallest; - } - } - result[0] = result[1] = result[2] = result[3] = r; - store_vector4(inst, machine, result); - } - break; case OPCODE_RCP: { @@ -1640,6 +1585,14 @@ _mesa_execute_program(GLcontext * ctx, GLfloat texcoord[4], color[4]; fetch_vector4(&inst->SrcReg[0], machine, texcoord); + /* For TEX, texcoord.Q should not be used and its value should not + * matter (at most, we pass coord.xyz to texture3D() in GLSL). + * Set Q=1 so that FetchTexelDeriv() doesn't get a garbage value + * which is effectively what happens when the texcoord swizzle + * is .xyzz + */ + texcoord[3] = 1.0f; + fetch_texel(ctx, machine, inst, texcoord, 0.0, color); if (DEBUG_PROG) { @@ -1663,6 +1616,18 @@ _mesa_execute_program(GLcontext * ctx, fetch_texel(ctx, machine, inst, texcoord, lodBias, color); + if (DEBUG_PROG) { + printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]" + " bias %g\n", + color[0], color[1], color[2], color[3], + inst->TexSrcUnit, + texcoord[0], + texcoord[1], + texcoord[2], + texcoord[3], + lodBias); + } + store_vector4(inst, machine, color); } break; @@ -1679,6 +1644,22 @@ _mesa_execute_program(GLcontext * ctx, store_vector4(inst, machine, color); } break; + case OPCODE_TXL: + /* Texel lookup with explicit LOD */ + { + GLfloat texcoord[4], color[4], lod; + + fetch_vector4(&inst->SrcReg[0], machine, texcoord); + + /* texcoord[3] is the LOD */ + lod = texcoord[3]; + + machine->FetchTexelLod(ctx, texcoord, lod, + machine->Samplers[inst->TexSrcUnit], color); + + store_vector4(inst, machine, color); + } + break; case OPCODE_TXP: /* GL_ARB_fragment_program only */ /* Texture lookup w/ projective divide */ { @@ -1842,7 +1823,11 @@ _mesa_execute_program(GLcontext * ctx, numExec++; if (numExec > maxExec) { - _mesa_problem(ctx, "Infinite loop detected in fragment program"); + static GLboolean reported = GL_FALSE; + if (!reported) { + _mesa_problem(ctx, "Infinite loop detected in fragment program"); + reported = GL_TRUE; + } return GL_TRUE; }