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

📄 brw_vs_emit.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* Post-vertex-program processing.  Send the results to the URB. */static void emit_vertex_write( struct brw_vs_compile *c){   struct brw_compile *p = &c->func;   struct brw_reg m0 = brw_message_reg(0);   struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];   struct brw_reg ndc;   if (c->key.copy_edgeflag) {      brw_MOV(p, 	      get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE),	      get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG));   }   /* Build ndc coords?   TODO: Shortcircuit when w is known to be one.    */   if (!c->key.know_w_is_one) {      ndc = get_tmp(c);      emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL);      brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc);   }   else {      ndc = pos;   }   /* This includes the workaround for -ve rhw, so is no longer an    * optional step:    */   if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) ||       c->key.nr_userclip ||       !c->key.know_w_is_one)   {      struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);      GLuint i;      brw_MOV(p, header1, brw_imm_ud(0));      brw_set_access_mode(p, BRW_ALIGN_16);	      if (c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) {	 struct brw_reg psiz = c->regs[PROGRAM_OUTPUT][VERT_RESULT_PSIZ];	 brw_MUL(p, brw_writemask(header1, WRITEMASK_W), brw_swizzle1(psiz, 0), brw_imm_f(1<<11));	 brw_AND(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(0x7ff<<8));      }      for (i = 0; i < c->key.nr_userclip; i++) {	 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);	 brw_DP4(p, brw_null_reg(), pos, c->userplane[i]);	 brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<i));	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);      }      /* i965 clipping workaround:        * 1) Test for -ve rhw       * 2) If set,        *      set ndc = (0,0,0,0)       *      set ucp[6] = 1       *       * Later, clipping will detect ucp[6] and ensure the primitive is       * clipped against all fixed planes.       */      if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw)) && !c->key.know_w_is_one) {	 brw_CMP(p,		 vec8(brw_null_reg()),		 BRW_CONDITIONAL_L,		 brw_swizzle1(ndc, 3),		 brw_imm_f(0));   	 brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<6));	 brw_MOV(p, ndc, brw_imm_f(0));	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);      }      brw_set_access_mode(p, BRW_ALIGN_1);	/* why? */      brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1);      brw_set_access_mode(p, BRW_ALIGN_16);      release_tmp(c, header1);   }   else {      brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0));   }   /* Emit the (interleaved) headers for the two vertices - an 8-reg    * of zeros followed by two sets of NDC coordinates:    */   brw_set_access_mode(p, BRW_ALIGN_1);   brw_MOV(p, offset(m0, 2), ndc);   brw_MOV(p, offset(m0, 3), pos);      brw_urb_WRITE(p, 		 brw_null_reg(), /* dest */		 0,		/* starting mrf reg nr */		 c->r0,		/* src */		 0,		/* allocate */		 1,		/* used */		 c->nr_outputs + 3, /* msg len */		 0,		/* response len */		 1, 		/* eot */		 1, 		/* writes complete */		 0, 		/* urb destination offset */		 BRW_URB_SWIZZLE_INTERLEAVE);}static void post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst ){   GLuint nr_insns = c->vp->program.Base.NumInstructions;   GLuint insn, target_insn;   struct prog_instruction *inst1, *inst2;   struct brw_instruction *brw_inst1, *brw_inst2;   int offset;   for (insn = 0; insn < nr_insns; insn++) {       inst1 = &c->vp->program.Base.Instructions[insn];       brw_inst1 = inst1->Data;       switch (inst1->Opcode) {	   case OPCODE_CAL:	   case OPCODE_BRA:	       target_insn = inst1->BranchTarget;	       inst2 = &c->vp->program.Base.Instructions[target_insn];	       brw_inst2 = inst2->Data;	       offset = brw_inst2 - brw_inst1;	       brw_set_src1(brw_inst1, brw_imm_d(offset*16));	       break;	   case OPCODE_END:	       offset = end_inst - brw_inst1;	       brw_set_src1(brw_inst1, brw_imm_d(offset*16));	       break;	   default:	       break;       }   }}/* Emit the fragment program instructions here. */void brw_vs_emit(struct brw_vs_compile *c ){#define MAX_IFSN 32   struct brw_compile *p = &c->func;   GLuint nr_insns = c->vp->program.Base.NumInstructions;   GLuint insn, if_insn = 0;   struct brw_instruction *end_inst;   struct brw_instruction *if_inst[MAX_IFSN];   struct brw_indirect stack_index = brw_indirect(0, 0);      GLuint index;   GLuint file;   if (INTEL_DEBUG & DEBUG_VS) {      _mesa_printf("\n\n\nvs-emit:\n");      _mesa_print_program(&c->vp->program.Base);       _mesa_printf("\n");   }   brw_set_compression_control(p, BRW_COMPRESSION_NONE);   brw_set_access_mode(p, BRW_ALIGN_16);      /* Message registers can't be read, so copy the output into GRF register      if they are used in source registers */   for (insn = 0; insn < nr_insns; insn++) {       GLuint i;       struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];       for (i = 0; i < 3; i++) {	   struct prog_src_register *src = &inst->SrcReg[i];	   GLuint index = src->Index;	   GLuint file = src->File;		   if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)	       c->output_regs[index].used_in_src = GL_TRUE;       }   }   /* Static register allocation    */   brw_vs_alloc_regs(c);   brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));   for (insn = 0; insn < nr_insns; insn++) {      struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];      struct brw_reg args[3], dst;      GLuint i;            /* Get argument regs.  SWZ is special and does this itself.       */      inst->Data = &p->store[p->nr_insn];      if (inst->Opcode != OPCODE_SWZ)	  for (i = 0; i < 3; i++) {	      struct prog_src_register *src = &inst->SrcReg[i];	      index = src->Index;	      file = src->File;		      if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src)		  args[i] = c->output_regs[index].reg;	      else		  args[i] = get_arg(c, src);	  }      /* Get dest regs.  Note that it is possible for a reg to be both       * dst and arg, given the static allocation of registers.  So       * care needs to be taken emitting multi-operation instructions.       */       index = inst->DstReg.Index;      file = inst->DstReg.File;      if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)	  dst = c->output_regs[index].reg;      else	  dst = get_dst(c, inst->DstReg);      switch (inst->Opcode) {      case OPCODE_ABS:	 brw_MOV(p, dst, brw_abs(args[0]));	 break;      case OPCODE_ADD:	 brw_ADD(p, dst, args[0], args[1]);	 break;      case OPCODE_DP3:	 brw_DP3(p, dst, args[0], args[1]);	 break;      case OPCODE_DP4:	 brw_DP4(p, dst, args[0], args[1]);	 break;      case OPCODE_DPH:	 brw_DPH(p, dst, args[0], args[1]);	 break;      case OPCODE_DST:	 unalias2(c, dst, args[0], args[1], emit_dst_noalias); 	 break;      case OPCODE_EXP:	 unalias1(c, dst, args[0], emit_exp_noalias);	 break;      case OPCODE_EX2:	 emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);	 break;      case OPCODE_ARL:	 emit_arl(c, dst, args[0]);	 break;      case OPCODE_FLR:	 brw_RNDD(p, dst, args[0]);	 break;      case OPCODE_FRC:	 brw_FRC(p, dst, args[0]);	 break;      case OPCODE_LOG:	 unalias1(c, dst, args[0], emit_log_noalias);	 break;      case OPCODE_LG2:	 emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL);	 break;      case OPCODE_LIT:	 unalias1(c, dst, args[0], emit_lit_noalias);	 break;      case OPCODE_MAD:	 brw_MOV(p, brw_acc_reg(), args[2]);	 brw_MAC(p, dst, args[0], args[1]);	 break;      case OPCODE_MAX:	 emit_max(p, dst, args[0], args[1]);	 break;      case OPCODE_MIN:	 emit_min(p, dst, args[0], args[1]);	 break;      case OPCODE_MOV:	 brw_MOV(p, dst, args[0]);	 break;      case OPCODE_MUL:	 brw_MUL(p, dst, args[0], args[1]);	 break;      case OPCODE_POW:	 emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL); 	 break;      case OPCODE_RCP:	 emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);	 break;      case OPCODE_RSQ:	 emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);	 break;      case OPCODE_SEQ:         emit_seq(p, dst, args[0], args[1]);         break;      case OPCODE_SNE:         emit_sne(p, dst, args[0], args[1]);         break;      case OPCODE_SGE:	 emit_sge(p, dst, args[0], args[1]);	 break;      case OPCODE_SGT:         emit_sgt(p, dst, args[0], args[1]);        break;      case OPCODE_SLT:	 emit_slt(p, dst, args[0], args[1]);	 break;      case OPCODE_SLE:         emit_sle(p, dst, args[0], args[1]);         break;      case OPCODE_SUB:	 brw_ADD(p, dst, args[0], negate(args[1]));	 break;      case OPCODE_SWZ:	 /* The args[0] value can't be used here as it won't have	  * correctly encoded the full swizzle:	  */	 emit_swz(c, dst, inst->SrcReg[0] );	 break;      case OPCODE_XPD:	 emit_xpd(p, dst, args[0], args[1]);	 break;      case OPCODE_IF:	 assert(if_insn < MAX_IFSN);         if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);	 break;      case OPCODE_ELSE:	 if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);	 break;      case OPCODE_ENDIF:         assert(if_insn > 0);	 brw_ENDIF(p, if_inst[--if_insn]);	 break;			      case OPCODE_BRA:         brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));         brw_set_predicate_control_flag_value(p, 0xff);        break;      case OPCODE_CAL:	 brw_set_access_mode(p, BRW_ALIGN_1);	 brw_ADD(p, deref_1d(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));	 brw_set_access_mode(p, BRW_ALIGN_16);	 brw_ADD(p, get_addr_reg(stack_index),			 get_addr_reg(stack_index), brw_imm_d(4));	 inst->Data = &p->store[p->nr_insn];	 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));        break;      case OPCODE_RET:	 brw_ADD(p, get_addr_reg(stack_index),			 get_addr_reg(stack_index), brw_imm_d(-4));	 brw_set_access_mode(p, BRW_ALIGN_1);         brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0));	 brw_set_access_mode(p, BRW_ALIGN_16);      case OPCODE_END:	         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));        break;      case OPCODE_PRINT:      case OPCODE_BGNSUB:      case OPCODE_ENDSUB:	 break;      default:	 _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);	 break;      }      if ((inst->DstReg.File == PROGRAM_OUTPUT)          && (inst->DstReg.Index != VERT_RESULT_HPOS)          && c->output_regs[inst->DstReg.Index].used_in_src) {         brw_MOV(p, get_dst(c, inst->DstReg), dst);      }      /* Result color clamping.       *       * When destination register is an output register and       * it's primary/secondary front/back color, we have to clamp       * the result to [0,1]. This is done by enabling the       * saturation bit for the last instruction.       *       * We don't use brw_set_saturate() as it modifies       * p->current->header.saturate, which affects all the subsequent       * instructions. Instead, we directly modify the header       * of the last (already stored) instruction.       */      if (inst->DstReg.File == PROGRAM_OUTPUT) {         if ((inst->DstReg.Index == VERT_RESULT_COL0)             || (inst->DstReg.Index == VERT_RESULT_COL1)             || (inst->DstReg.Index == VERT_RESULT_BFC0)             || (inst->DstReg.Index == VERT_RESULT_BFC1)) {            p->store[p->nr_insn-1].header.saturate = 1;         }      }      release_tmps(c);   }   end_inst = &p->store[p->nr_insn];   emit_vertex_write(c);   post_vs_emit(c, end_inst);   for (insn = 0; insn < nr_insns; insn++)       c->vp->program.Base.Instructions[insn].Data = NULL;}

⌨️ 快捷键说明

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