📄 t_vb_program.c
字号:
* Unmap the texture images which were used by the vertex program (if any). */static voidunmap_textures(GLcontext *ctx, const struct gl_vertex_program *vp){ GLuint u; if (!ctx->Driver.MapTexture) return; for (u = 0; u < ctx->Const.MaxVertexTextureImageUnits; u++) { if (vp->Base.TexturesUsed[u]) { /* Note: _Current *should* correspond to the target indicated * in TexturesUsed[u]. */ ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[u]._Current); } }}/** * This function executes vertex programs */static GLbooleanrun_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ TNLcontext *tnl = TNL_CONTEXT(ctx); struct vp_stage_data *store = VP_STAGE_DATA(stage); struct vertex_buffer *VB = &tnl->vb; struct gl_vertex_program *program = ctx->VertexProgram._Current; struct gl_program_machine machine; GLuint outputs[VERT_RESULT_MAX], numOutputs; GLuint i, j; if (!program) return GL_TRUE; if (program->IsNVProgram) { _mesa_load_tracked_matrices(ctx); } else { /* ARB program or vertex shader */ _mesa_load_state_parameters(ctx, program->Base.Parameters); } /* make list of outputs to save some time below */ numOutputs = 0; for (i = 0; i < VERT_RESULT_MAX; i++) { if (program->Base.OutputsWritten & (1 << i)) { outputs[numOutputs++] = i; } } map_textures(ctx, program); for (i = 0; i < VB->Count; i++) { GLuint attr; init_machine(ctx, &machine);#if 0 printf("Input %d: %f, %f, %f, %f\n", i, VB->AttribPtr[0]->data[i][0], VB->AttribPtr[0]->data[i][1], VB->AttribPtr[0]->data[i][2], VB->AttribPtr[0]->data[i][3]); printf(" color: %f, %f, %f, %f\n", VB->AttribPtr[3]->data[i][0], VB->AttribPtr[3]->data[i][1], VB->AttribPtr[3]->data[i][2], VB->AttribPtr[3]->data[i][3]); printf(" normal: %f, %f, %f, %f\n", VB->AttribPtr[2]->data[i][0], VB->AttribPtr[2]->data[i][1], VB->AttribPtr[2]->data[i][2], VB->AttribPtr[2]->data[i][3]);#endif /* the vertex array case */ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { if (program->Base.InputsRead & (1 << attr)) { const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data; const GLuint size = VB->AttribPtr[attr]->size; const GLuint stride = VB->AttribPtr[attr]->stride; const GLfloat *data = (GLfloat *) (ptr + stride * i); COPY_CLEAN_4V(machine.VertAttribs[attr], size, data); } } /* execute the program */ _mesa_execute_program(ctx, &program->Base, &machine); /* copy the output registers into the VB->attribs arrays */ for (j = 0; j < numOutputs; j++) { const GLuint attr = outputs[j]; COPY_4V(store->results[attr].data[i], machine.Outputs[attr]); }#if 0 printf("HPOS: %f %f %f %f\n", machine.Outputs[0][0], machine.Outputs[0][1], machine.Outputs[0][2], machine.Outputs[0][3]);#endif } unmap_textures(ctx, program); /* Fixup fog and point size results if needed */ if (program->IsNVProgram) { if (ctx->Fog.Enabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) { for (i = 0; i < VB->Count; i++) { store->results[VERT_RESULT_FOGC].data[i][0] = 1.0; } } if (ctx->VertexProgram.PointSizeEnabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) { for (i = 0; i < VB->Count; i++) { store->results[VERT_RESULT_PSIZ].data[i][0] = ctx->Point.Size; } } } if (program->IsPositionInvariant) { /* We need the exact same transform as in the fixed function path here * to guarantee invariance, depending on compiler optimization flags * results could be different otherwise. */ VB->ClipPtr = TransformRaw( &store->results[0], &ctx->_ModelProjectMatrix, VB->AttribPtr[0] ); /* Drivers expect this to be clean to element 4... */ switch (VB->ClipPtr->size) { case 1: /* impossible */ case 2: _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); /* fall-through */ case 3: _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); /* fall-through */ case 4: break; } } else { /* Setup the VB pointers so that the next pipeline stages get * their data from the right place (the program output arrays). */ VB->ClipPtr = &store->results[VERT_RESULT_HPOS]; VB->ClipPtr->size = 4; VB->ClipPtr->count = VB->Count; } VB->ColorPtr[0] = &store->results[VERT_RESULT_COL0]; VB->ColorPtr[1] = &store->results[VERT_RESULT_BFC0]; VB->SecondaryColorPtr[0] = &store->results[VERT_RESULT_COL1]; VB->SecondaryColorPtr[1] = &store->results[VERT_RESULT_BFC1]; VB->FogCoordPtr = &store->results[VERT_RESULT_FOGC]; VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->results[VERT_RESULT_COL0]; VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->results[VERT_RESULT_COL1]; VB->AttribPtr[VERT_ATTRIB_FOG] = &store->results[VERT_RESULT_FOGC]; VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->results[VERT_RESULT_PSIZ]; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &store->results[VERT_RESULT_TEX0 + i]; } for (i = 0; i < ctx->Const.MaxVarying; i++) { if (program->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) { /* Note: varying results get put into the generic attributes */ VB->AttribPtr[VERT_ATTRIB_GENERIC0+i] = &store->results[VERT_RESULT_VAR0 + i]; } } /* Perform NDC and cliptest operations: */ return do_ndc_cliptest(ctx, store);}/** * Called the first time stage->run is called. In effect, don't * allocate data until the first time the stage is run. */static GLbooleaninit_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage){ TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &(tnl->vb); struct vp_stage_data *store; const GLuint size = VB->Size; GLuint i; stage->privatePtr = MALLOC(sizeof(*store)); store = VP_STAGE_DATA(stage); if (!store) return GL_FALSE; /* Allocate arrays of vertex output values */ for (i = 0; i < VERT_RESULT_MAX; i++) { _mesa_vector4f_alloc( &store->results[i], 0, size, 32 ); store->results[i].size = 4; } /* a few other misc allocations */ _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 ); store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 ); return GL_TRUE;}/** * Destructor for this pipeline stage. */static voiddtr(struct tnl_pipeline_stage *stage){ struct vp_stage_data *store = VP_STAGE_DATA(stage); if (store) { GLuint i; /* free the vertex program result arrays */ for (i = 0; i < VERT_RESULT_MAX; i++) _mesa_vector4f_free( &store->results[i] ); /* free misc arrays */ _mesa_vector4f_free( &store->ndcCoords ); ALIGN_FREE( store->clipmask ); FREE( store ); stage->privatePtr = NULL; }}static voidvalidate_vp_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage){ if (ctx->VertexProgram._Current) { _swrast_update_texture_samplers(ctx); }}/** * Public description of this pipeline stage. */const struct tnl_pipeline_stage _tnl_vertex_program_stage ={ "vertex-program", NULL, /* private_data */ init_vp, /* create */ dtr, /* destroy */ validate_vp_stage, /* validate */ run_vp /* run -- initially set to ctr */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -