struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, struct gl_vertex_program *mesa_vp) { context_t *context = R700_CONTEXT(ctx); struct r700_vertex_program *vp; unsigned int i; vp = _mesa_calloc(sizeof(*vp)); vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base); if (mesa_vp->IsPositionInvariant) { _mesa_insert_mvp_code(ctx, vp->mesa_program); } for(i=0; i<context->nNumActiveAos; i++) { vp->aos_desc[i].size = context->stream_desc[i].size; vp->aos_desc[i].stride = context->stream_desc[i].stride; vp->aos_desc[i].type = context->stream_desc[i].type; } if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) { vp->r700AsmCode.bR6xx = 1; } //Init_Program Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) ); Map_Vertex_Program(ctx, vp, vp->mesa_program ); if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program)) { return NULL; } if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions, &(vp->mesa_program->Base.Instructions[0]), &(vp->r700AsmCode)) ) { return NULL; } if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) ) { return NULL; } vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0 : (vp->r700AsmCode.number_used_registers - 1); vp->r700Shader.nParamExports = vp->r700AsmCode.number_of_exports; vp->translated = GL_TRUE; return vp; }
void r300TranslateFragmentShader(r300ContextPtr r300, struct r300_fragment_program *fp) { struct r300_fragment_program_external_state state; build_state(r300, fp, &state); if (_mesa_memcmp(&fp->state, &state, sizeof(state))) { /* TODO: cache compiled programs */ fp->translated = GL_FALSE; _mesa_memcpy(&fp->state, &state, sizeof(state)); } if (!fp->translated) { struct r300_fragment_program_compiler compiler; compiler.r300 = r300; compiler.fp = fp; compiler.code = &fp->code; compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base); if (RADEON_DEBUG & DEBUG_PIXEL) { _mesa_printf("Fragment Program: Initial program:\n"); _mesa_print_program(compiler.program); } insert_WPOS_trailer(&compiler); struct radeon_program_transformation transformations[] = { { &transform_TEX, &compiler }, { &radeonTransformALU, 0 }, { &radeonTransformTrigSimple, 0 } }; radeonLocalTransform( r300->radeon.glCtx, compiler.program, 3, transformations); if (RADEON_DEBUG & DEBUG_PIXEL) { _mesa_printf("Fragment Program: After native rewrite:\n"); _mesa_print_program(compiler.program); } struct radeon_nqssadce_descr nqssadce = { .Init = &nqssadce_init, .IsNativeSwizzle = &r300FPIsNativeSwizzle, .BuildSwizzle = &r300FPBuildSwizzle, .RewriteDepthOut = GL_TRUE }; radeonNqssaDce(r300->radeon.glCtx, compiler.program, &nqssadce); if (RADEON_DEBUG & DEBUG_PIXEL) { _mesa_printf("Compiler: after NqSSA-DCE:\n"); _mesa_print_program(compiler.program); } if (!r300FragmentProgramEmit(&compiler)) fp->error = GL_TRUE; /* Subtle: Rescue any parameters that have been added during transformations */ _mesa_free_parameter_list(fp->mesa_program.Base.Parameters); fp->mesa_program.Base.Parameters = compiler.program->Parameters; compiler.program->Parameters = 0; _mesa_reference_program(r300->radeon.glCtx, &compiler.program, NULL); if (!fp->error) fp->translated = GL_TRUE; if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) r300FragmentProgramDump(fp, &fp->code); r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM); } update_params(r300, fp); }
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; }
/** * Make fragment shader for glDraw/CopyPixels. This shader is made * by combining the pixel transfer shader with the user-defined shader. */ static struct st_fragment_program * combined_drawpix_fragment_program(GLcontext *ctx) { struct st_context *st = ctx->st; struct st_fragment_program *stfp; if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn && st->fp->serialNo == st->pixel_xfer.user_prog_sn) { /* the pixel tranfer program has not changed and the user-defined * program has not changed, so re-use the combined program. */ stfp = st->pixel_xfer.combined_prog; } else { /* Concatenate the pixel transfer program with the current user- * defined program. */ if (is_passthrough_program(&st->fp->Base)) { stfp = (struct st_fragment_program *) _mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base); } else { #if 0 printf("Base program:\n"); _mesa_print_program(&st->fp->Base.Base); printf("DrawPix program:\n"); _mesa_print_program(&st->pixel_xfer.program->Base.Base); #endif stfp = (struct st_fragment_program *) _mesa_combine_programs(ctx, &st->pixel_xfer.program->Base.Base, &st->fp->Base.Base); } #if 0 { struct gl_program *p = &stfp->Base.Base; printf("Combined DrawPixels program:\n"); _mesa_print_program(p); printf("InputsRead: 0x%x\n", p->InputsRead); printf("OutputsWritten: 0x%x\n", p->OutputsWritten); _mesa_print_parameter_list(p->Parameters); } #endif /* translate to TGSI tokens */ st_translate_fragment_program(st, stfp, NULL); /* save new program, update serial numbers */ st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; st->pixel_xfer.user_prog_sn = st->fp->serialNo; st->pixel_xfer.combined_prog_sn = stfp->serialNo; /* can't reference new program directly, already have a reference on it */ st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); st->pixel_xfer.combined_prog = stfp; } /* Ideally we'd have updated the pipe constants during the normal * st/atom mechanism. But we can't since this is specific to glDrawPixels. */ st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT); return stfp; }