⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prog_execute.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
   else {      return GL_FALSE;   }}/** * Store 4 floats into a register.  Observe the instructions saturate and * set-condition-code flags. */static voidstore_vector4(const struct prog_instruction *inst,              struct gl_program_machine *machine, const GLfloat value[4]){   const struct prog_dst_register *dest = &(inst->DstReg);   const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;   GLfloat *dstReg;   GLfloat dummyReg[4];   GLfloat clampedValue[4];   GLuint writeMask = dest->WriteMask;   switch (dest->File) {   case PROGRAM_OUTPUT:      ASSERT(dest->Index < MAX_PROGRAM_OUTPUTS);      dstReg = machine->Outputs[dest->Index];      break;   case PROGRAM_TEMPORARY:      ASSERT(dest->Index < MAX_PROGRAM_TEMPS);      dstReg = machine->Temporaries[dest->Index];      break;   case PROGRAM_WRITE_ONLY:      dstReg = dummyReg;      return;   default:      _mesa_problem(NULL, "bad register file in store_vector4(fp)");      return;   }#if 0   if (value[0] > 1.0e10 ||       IS_INF_OR_NAN(value[0]) ||       IS_INF_OR_NAN(value[1]) ||       IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))      printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);#endif   if (clamp) {      clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);      clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);      clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);      clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);      value = clampedValue;   }   if (dest->CondMask != COND_TR) {      /* condition codes may turn off some writes */      if (writeMask & WRITEMASK_X) {         if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)],                      dest->CondMask))            writeMask &= ~WRITEMASK_X;      }      if (writeMask & WRITEMASK_Y) {         if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)],                      dest->CondMask))            writeMask &= ~WRITEMASK_Y;      }      if (writeMask & WRITEMASK_Z) {         if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)],                      dest->CondMask))            writeMask &= ~WRITEMASK_Z;      }      if (writeMask & WRITEMASK_W) {         if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)],                      dest->CondMask))            writeMask &= ~WRITEMASK_W;      }   }   if (writeMask & WRITEMASK_X)      dstReg[0] = value[0];   if (writeMask & WRITEMASK_Y)      dstReg[1] = value[1];   if (writeMask & WRITEMASK_Z)      dstReg[2] = value[2];   if (writeMask & WRITEMASK_W)      dstReg[3] = value[3];   if (inst->CondUpdate) {      if (writeMask & WRITEMASK_X)         machine->CondCodes[0] = generate_cc(value[0]);      if (writeMask & WRITEMASK_Y)         machine->CondCodes[1] = generate_cc(value[1]);      if (writeMask & WRITEMASK_Z)         machine->CondCodes[2] = generate_cc(value[2]);      if (writeMask & WRITEMASK_W)         machine->CondCodes[3] = generate_cc(value[3]);#if DEBUG_PROG      printf("CondCodes=(%s,%s,%s,%s) for:\n",             _mesa_condcode_string(machine->CondCodes[0]),             _mesa_condcode_string(machine->CondCodes[1]),             _mesa_condcode_string(machine->CondCodes[2]),             _mesa_condcode_string(machine->CondCodes[3]));#endif   }}/** * Execute the given vertex/fragment program. * * \param ctx  rendering context * \param program  the program to execute * \param machine  machine state (must be initialized) * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. */GLboolean_mesa_execute_program(GLcontext * ctx,                      const struct gl_program *program,                      struct gl_program_machine *machine){   const GLuint numInst = program->NumInstructions;   const GLuint maxExec = 10000;   GLint pc, numExec = 0;   machine->CurProgram = program;   if (DEBUG_PROG) {      printf("execute program %u --------------------\n", program->Id);   }#if FEATURE_MESA_program_debug   CurrentMachine = machine;#endif   if (program->Target == GL_VERTEX_PROGRAM_ARB) {      machine->EnvParams = ctx->VertexProgram.Parameters;   }   else {      machine->EnvParams = ctx->FragmentProgram.Parameters;   }   for (pc = 0; pc < numInst; pc++) {      const struct prog_instruction *inst = program->Instructions + pc;#if FEATURE_MESA_program_debug      if (ctx->FragmentProgram.CallbackEnabled &&          ctx->FragmentProgram.Callback) {         ctx->FragmentProgram.CurrentPosition = inst->StringPos;         ctx->FragmentProgram.Callback(program->Target,                                       ctx->FragmentProgram.CallbackData);      }#endif      if (DEBUG_PROG) {         _mesa_print_instruction(inst);      }      switch (inst->Opcode) {      case OPCODE_ABS:         {            GLfloat a[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            result[0] = FABSF(a[0]);            result[1] = FABSF(a[1]);            result[2] = FABSF(a[2]);            result[3] = FABSF(a[3]);            store_vector4(inst, machine, result);         }         break;      case OPCODE_ADD:         {            GLfloat a[4], b[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            result[0] = a[0] + b[0];            result[1] = a[1] + b[1];            result[2] = a[2] + b[2];            result[3] = a[3] + b[3];            store_vector4(inst, machine, result);            if (DEBUG_PROG) {               printf("ADD (%g %g %g %g) = (%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]);            }         }         break;      case OPCODE_ARL:         {            GLfloat t[4];            fetch_vector4(&inst->SrcReg[0], machine, t);            machine->AddressReg[0][0] = (GLint) FLOORF(t[0]);         }         break;      case OPCODE_BGNLOOP:         /* no-op */         break;      case OPCODE_ENDLOOP:         /* subtract 1 here since pc is incremented by for(pc) loop */         pc = inst->BranchTarget - 1;   /* go to matching BNGLOOP */         break;      case OPCODE_BGNSUB:      /* begin subroutine */         break;      case OPCODE_ENDSUB:      /* end subroutine */         break;      case OPCODE_BRA:         /* branch (conditional) */         /* fall-through */      case OPCODE_BRK:         /* break out of loop (conditional) */         /* fall-through */      case OPCODE_CONT:        /* continue loop (conditional) */         if (eval_condition(machine, inst)) {            /* take branch */            /* Subtract 1 here since we'll do pc++ at end of for-loop */            pc = inst->BranchTarget - 1;         }         break;      case OPCODE_CAL:         /* Call subroutine (conditional) */         if (eval_condition(machine, inst)) {            /* call the subroutine */            if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */            }            machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */            /* Subtract 1 here since we'll do pc++ at end of for-loop */            pc = inst->BranchTarget - 1;         }         break;      case OPCODE_CMP:         {            GLfloat a[4], b[4], c[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            fetch_vector4(&inst->SrcReg[2], machine, c);            result[0] = a[0] < 0.0F ? b[0] : c[0];            result[1] = a[1] < 0.0F ? b[1] : c[1];            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);         }         break;      case OPCODE_COS:         {            GLfloat a[4], result[4];            fetch_vector1(&inst->SrcReg[0], machine, a);            result[0] = result[1] = result[2] = result[3]               = (GLfloat) _mesa_cos(a[0]);            store_vector4(inst, machine, result);         }         break;      case OPCODE_DDX:         /* Partial derivative with respect to X */         {            GLfloat result[4];            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,                                'X', result);            store_vector4(inst, machine, result);         }         break;      case OPCODE_DDY:         /* Partial derivative with respect to Y */         {            GLfloat result[4];            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,                                'Y', result);            store_vector4(inst, machine, result);         }         break;      case OPCODE_DP3:         {            GLfloat a[4], b[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            result[0] = result[1] = result[2] = result[3] = DOT3(a, b);            store_vector4(inst, machine, result);            if (DEBUG_PROG) {               printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",                      result[0], a[0], a[1], a[2], b[0], b[1], b[2]);            }         }         break;      case OPCODE_DP4:         {            GLfloat a[4], b[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            result[0] = result[1] = result[2] = result[3] = DOT4(a, b);            store_vector4(inst, machine, result);            if (DEBUG_PROG) {               printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",                      result[0], a[0], a[1], a[2], a[3],                      b[0], b[1], b[2], b[3]);            }         }         break;      case OPCODE_DPH:         {            GLfloat a[4], b[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            result[0] = result[1] = result[2] = result[3] =               a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3];            store_vector4(inst, machine, result);         }         break;      case OPCODE_DST:         /* Distance vector */         {            GLfloat a[4], b[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            fetch_vector4(&inst->SrcReg[1], machine, b);            result[0] = 1.0F;            result[1] = a[1] * b[1];            result[2] = a[2];            result[3] = b[3];            store_vector4(inst, machine, result);         }         break;      case OPCODE_EXP:         {            GLfloat t[4], q[4], floor_t0;            fetch_vector1(&inst->SrcReg[0], machine, t);            floor_t0 = FLOORF(t[0]);            if (floor_t0 > FLT_MAX_EXP) {               SET_POS_INFINITY(q[0]);               SET_POS_INFINITY(q[2]);            }            else if (floor_t0 < FLT_MIN_EXP) {               q[0] = 0.0F;               q[2] = 0.0F;            }            else {               q[0] = LDEXPF(1.0, (int) floor_t0);               /* Note: GL_NV_vertex_program expects                 * result.z = result.x * APPX(result.y)                * We do what the ARB extension says.                */               q[2] = (GLfloat) pow(2.0, t[0]);            }            q[1] = t[0] - floor_t0;            q[3] = 1.0F;            store_vector4( inst, machine, q );         }         break;      case OPCODE_EX2:         /* Exponential base 2 */         {            GLfloat a[4], result[4];            fetch_vector1(&inst->SrcReg[0], machine, a);            result[0] = result[1] = result[2] = result[3] =               (GLfloat) _mesa_pow(2.0, a[0]);            store_vector4(inst, machine, result);         }         break;      case OPCODE_FLR:         {            GLfloat a[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            result[0] = FLOORF(a[0]);            result[1] = FLOORF(a[1]);            result[2] = FLOORF(a[2]);            result[3] = FLOORF(a[3]);            store_vector4(inst, machine, result);         }         break;      case OPCODE_FRC:         {            GLfloat a[4], result[4];            fetch_vector4(&inst->SrcReg[0], machine, a);            result[0] = a[0] - FLOORF(a[0]);            result[1] = a[1] - FLOORF(a[1]);            result[2] = a[2] - FLOORF(a[2]);            result[3] = a[3] - FLOORF(a[3]);            store_vector4(inst, machine, result);         }         break;      case OPCODE_IF:         {            GLboolean cond;            /* eval condition */            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {               GLfloat a[4];               fetch_vector1(&inst->SrcReg[0], machine, a);               cond = (a[0] != 0.0);            }            else {               cond = eval_condition(machine, inst);            }            if (DEBUG_PROG) {               printf("IF: %d\n", cond);            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -