static void r300_insert_wpos(struct r300_vertex_program_compiler* c, struct r300_shader_semantics* outputs) { int i, lastOutput = 0; /* Find the max output index. */ lastOutput = MAX2(lastOutput, outputs->psize); for (i = 0; i < ATTR_COLOR_COUNT; i++) { lastOutput = MAX2(lastOutput, outputs->color[i]); lastOutput = MAX2(lastOutput, outputs->bcolor[i]); } for (i = 0; i < ATTR_GENERIC_COUNT; i++) { lastOutput = MAX2(lastOutput, outputs->generic[i]); } lastOutput = MAX2(lastOutput, outputs->fog); /* Set WPOS after the last output. */ lastOutput++; rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */ outputs->wpos = lastOutput; }
static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_key *wanted_key, const struct gl_vertex_program *mesa_vp) { struct r300_vertex_program *vp; struct r300_vertex_program_compiler compiler; vp = _mesa_calloc(sizeof(*vp)); vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base); _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); rc_init(&compiler.Base); compiler.Base.Debug = (RADEON_DEBUG & RADEON_VERTS) ? GL_TRUE : GL_FALSE; compiler.code = &vp->code; compiler.RequiredOutputs = compute_required_outputs(vp->Base, vp->key.FpReads); compiler.SetHwInputOutput = &t_inputs_outputs; if (compiler.Base.Debug) { fprintf(stderr, "Initial vertex program:\n"); _mesa_print_program(&vp->Base->Base); fflush(stderr); } if (mesa_vp->IsPositionInvariant) { _mesa_insert_mvp_code(ctx, vp->Base); } radeon_mesa_to_rc_program(&compiler.Base, &vp->Base->Base); if (mesa_vp->IsNVProgram) initialize_NV_registers(&compiler.Base); rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X); if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) { rc_copy_output(&compiler.Base, VERT_RESULT_HPOS, vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0); } if (vp->key.FogAttr != FRAG_ATTRIB_MAX) { rc_move_output(&compiler.Base, VERT_RESULT_FOGC, vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X); } r3xx_compile_vertex_program(&compiler); if (vp->code.constants.Count > ctx->Const.VertexProgram.MaxParameters) { rc_error(&compiler.Base, "Program exceeds constant buffer size limit\n"); } vp->error = compiler.Base.Error; vp->Base->Base.InputsRead = vp->code.InputsRead; vp->Base->Base.OutputsWritten = vp->code.OutputsWritten; rc_destroy(&compiler.Base); return vp; }
void r300_translate_vertex_shader(struct r300_context *r300, struct r300_vertex_shader *vs) { struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; unsigned i; /* Setup the compiler */ memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base, NULL); DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; compiler.code = &vs->code; compiler.UserData = vs; compiler.Base.is_r500 = r300->screen->caps.is_r500; compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT); compiler.Base.has_half_swizzles = FALSE; compiler.Base.has_presub = FALSE; compiler.Base.has_omod = FALSE; compiler.Base.max_temp_regs = 32; compiler.Base.max_constants = 256; compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256; if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_VP, "r300: Initial vertex program\n"); tgsi_dump(vs->state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &vs->info; ttr.use_half_swizzles = FALSE; r300_tgsi_to_rc(&ttr, vs->state.tokens); if (ttr.error) { fprintf(stderr, "r300 VP: Cannot translate a shader. " "Using a dummy shader instead.\n"); r300_dummy_vertex_shader(r300, vs); return; } if (compiler.Base.Program.Constants.Count > 200) { compiler.Base.remove_unused_constants = TRUE; } compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1)); compiler.SetHwInputOutput = &set_vertex_inputs_outputs; /* Insert the WPOS output. */ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader" " instead.\n", compiler.Base.ErrorMsg); if (vs->dummy) { fprintf(stderr, "r300 VP: Cannot compile the dummy shader! " "Giving up...\n"); abort(); } rc_destroy(&compiler.Base); r300_dummy_vertex_shader(r300, vs); return; } /* Initialize numbers of constants for each type. */ vs->externals_count = 0; for (i = 0; i < vs->code.constants.Count && vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) { vs->externals_count = i+1; } for (; i < vs->code.constants.Count; i++) { assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE); } vs->immediates_count = vs->code.constants.Count - vs->externals_count; /* And, finally... */ rc_destroy(&compiler.Base); }