Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvbo_exec_api.c
Go to the documentation of this file.
00001 /************************************************************************** 00002 00003 Copyright 2002-2008 Tungsten Graphics Inc., Cedar Park, Texas. 00004 00005 All Rights Reserved. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 on the rights to use, copy, modify, merge, publish, distribute, sub 00011 license, and/or sell copies of the Software, and to permit persons to whom 00012 the Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice (including the next 00015 paragraph) shall be included in all copies or substantial portions of the 00016 Software. 00017 00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00019 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 00021 TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 00022 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 00023 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 00024 USE OR OTHER DEALINGS IN THE SOFTWARE. 00025 00026 **************************************************************************/ 00027 00028 /* 00029 * Authors: 00030 * Keith Whitwell <keith@tungstengraphics.com> 00031 */ 00032 00033 #include "main/glheader.h" 00034 #include "main/bufferobj.h" 00035 #include "main/context.h" 00036 #include "main/macros.h" 00037 #include "main/vtxfmt.h" 00038 #if FEATURE_dlist 00039 #include "main/dlist.h" 00040 #endif 00041 #include "main/state.h" 00042 #include "main/light.h" 00043 #include "main/api_arrayelt.h" 00044 #include "main/api_noop.h" 00045 #include "glapi/dispatch.h" 00046 00047 #include "vbo_context.h" 00048 00049 #ifdef ERROR 00050 #undef ERROR 00051 #endif 00052 00053 00054 static void reset_attrfv( struct vbo_exec_context *exec ); 00055 00056 00057 /* Close off the last primitive, execute the buffer, restart the 00058 * primitive. 00059 */ 00060 static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec ) 00061 { 00062 if (exec->vtx.prim_count == 0) { 00063 exec->vtx.copied.nr = 0; 00064 exec->vtx.vert_count = 0; 00065 exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; 00066 } 00067 else { 00068 GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; 00069 GLuint last_count; 00070 00071 if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { 00072 GLint i = exec->vtx.prim_count - 1; 00073 assert(i >= 0); 00074 exec->vtx.prim[i].count = (exec->vtx.vert_count - 00075 exec->vtx.prim[i].start); 00076 } 00077 00078 last_count = exec->vtx.prim[exec->vtx.prim_count-1].count; 00079 00080 /* Execute the buffer and save copied vertices. 00081 */ 00082 if (exec->vtx.vert_count) 00083 vbo_exec_vtx_flush( exec ); 00084 else { 00085 exec->vtx.prim_count = 0; 00086 exec->vtx.copied.nr = 0; 00087 } 00088 00089 /* Emit a glBegin to start the new list. 00090 */ 00091 assert(exec->vtx.prim_count == 0); 00092 00093 if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { 00094 exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive; 00095 exec->vtx.prim[0].start = 0; 00096 exec->vtx.prim[0].count = 0; 00097 exec->vtx.prim_count++; 00098 00099 if (exec->vtx.copied.nr == last_count) 00100 exec->vtx.prim[0].begin = last_begin; 00101 } 00102 } 00103 } 00104 00105 00106 /* Deal with buffer wrapping where provoked by the vertex buffer 00107 * filling up, as opposed to upgrade_vertex(). 00108 */ 00109 void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) 00110 { 00111 GLfloat *data = exec->vtx.copied.buffer; 00112 GLuint i; 00113 00114 /* Run pipeline on current vertices, copy wrapped vertices 00115 * to exec->vtx.copied. 00116 */ 00117 vbo_exec_wrap_buffers( exec ); 00118 00119 /* Copy stored stored vertices to start of new list. 00120 */ 00121 assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); 00122 00123 for (i = 0 ; i < exec->vtx.copied.nr ; i++) { 00124 _mesa_memcpy( exec->vtx.vbptr, data, 00125 exec->vtx.vertex_size * sizeof(GLfloat)); 00126 exec->vtx.vbptr += exec->vtx.vertex_size; 00127 data += exec->vtx.vertex_size; 00128 exec->vtx.vert_count++; 00129 } 00130 00131 exec->vtx.copied.nr = 0; 00132 } 00133 00134 00135 /* 00136 * Copy the active vertex's values to the ctx->Current fields. 00137 */ 00138 static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) 00139 { 00140 GLcontext *ctx = exec->ctx; 00141 struct vbo_context *vbo = vbo_context(ctx); 00142 GLuint i; 00143 00144 for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { 00145 if (exec->vtx.attrsz[i]) { 00146 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; 00147 00148 /* Note: the exec->vtx.current[i] pointers point into the 00149 * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. 00150 */ 00151 if (exec->vtx.attrptr[i]) { 00152 00153 COPY_CLEAN_4V(current, 00154 exec->vtx.attrsz[i], 00155 exec->vtx.attrptr[i]); 00156 00157 } 00158 00159 /* Given that we explicitly state size here, there is no need 00160 * for the COPY_CLEAN above, could just copy 16 bytes and be 00161 * done. The only problem is when Mesa accesses ctx->Current 00162 * directly. 00163 */ 00164 vbo->currval[i].Size = exec->vtx.attrsz[i]; 00165 00166 /* This triggers rather too much recalculation of Mesa state 00167 * that doesn't get used (eg light positions). 00168 */ 00169 if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && 00170 i <= VBO_ATTRIB_MAT_BACK_INDEXES) 00171 ctx->NewState |= _NEW_LIGHT; 00172 } 00173 } 00174 00175 /* Colormaterial -- this kindof sucks. 00176 */ 00177 if (ctx->Light.ColorMaterialEnabled && 00178 exec->vtx.attrsz[VBO_ATTRIB_COLOR0]) { 00179 _mesa_update_color_material(ctx, 00180 ctx->Current.Attrib[VBO_ATTRIB_COLOR0]); 00181 } 00182 00183 ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; 00184 } 00185 00186 00187 static void vbo_exec_copy_from_current( struct vbo_exec_context *exec ) 00188 { 00189 GLcontext *ctx = exec->ctx; 00190 struct vbo_context *vbo = vbo_context(ctx); 00191 GLint i; 00192 00193 for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { 00194 const GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; 00195 switch (exec->vtx.attrsz[i]) { 00196 case 4: exec->vtx.attrptr[i][3] = current[3]; 00197 case 3: exec->vtx.attrptr[i][2] = current[2]; 00198 case 2: exec->vtx.attrptr[i][1] = current[1]; 00199 case 1: exec->vtx.attrptr[i][0] = current[0]; 00200 break; 00201 } 00202 } 00203 00204 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; 00205 } 00206 00207 00208 /* Flush existing data, set new attrib size, replay copied vertices. 00209 */ 00210 static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, 00211 GLuint attr, 00212 GLuint newsz ) 00213 { 00214 GLcontext *ctx = exec->ctx; 00215 struct vbo_context *vbo = vbo_context(ctx); 00216 GLint lastcount = exec->vtx.vert_count; 00217 GLfloat *tmp; 00218 GLuint oldsz; 00219 GLuint i; 00220 00221 /* Run pipeline on current vertices, copy wrapped vertices 00222 * to exec->vtx.copied. 00223 */ 00224 vbo_exec_wrap_buffers( exec ); 00225 00226 00227 /* Do a COPY_TO_CURRENT to ensure back-copying works for the case 00228 * when the attribute already exists in the vertex and is having 00229 * its size increased. 00230 */ 00231 vbo_exec_copy_to_current( exec ); 00232 00233 00234 /* Heuristic: Attempt to isolate attributes received outside 00235 * begin/end so that they don't bloat the vertices. 00236 */ 00237 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && 00238 exec->vtx.attrsz[attr] == 0 && 00239 lastcount > 8 && 00240 exec->vtx.vertex_size) { 00241 reset_attrfv( exec ); 00242 } 00243 00244 /* Fix up sizes: 00245 */ 00246 oldsz = exec->vtx.attrsz[attr]; 00247 exec->vtx.attrsz[attr] = newsz; 00248 00249 exec->vtx.vertex_size += newsz - oldsz; 00250 exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size; 00251 exec->vtx.vert_count = 0; 00252 exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; 00253 00254 00255 /* Recalculate all the attrptr[] values 00256 */ 00257 for (i = 0, tmp = exec->vtx.vertex ; i < VBO_ATTRIB_MAX ; i++) { 00258 if (exec->vtx.attrsz[i]) { 00259 exec->vtx.attrptr[i] = tmp; 00260 tmp += exec->vtx.attrsz[i]; 00261 } 00262 else 00263 exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */ 00264 } 00265 00266 /* Copy from current to repopulate the vertex with correct values. 00267 */ 00268 vbo_exec_copy_from_current( exec ); 00269 00270 /* Replay stored vertices to translate them 00271 * to new format here. 00272 * 00273 * -- No need to replay - just copy piecewise 00274 */ 00275 if (exec->vtx.copied.nr) 00276 { 00277 GLfloat *data = exec->vtx.copied.buffer; 00278 GLfloat *dest = exec->vtx.vbptr; 00279 GLuint j; 00280 00281 assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); 00282 00283 for (i = 0 ; i < exec->vtx.copied.nr ; i++) { 00284 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) { 00285 if (exec->vtx.attrsz[j]) { 00286 if (j == attr) { 00287 if (oldsz) { 00288 COPY_CLEAN_4V( dest, oldsz, data ); 00289 data += oldsz; 00290 dest += newsz; 00291 } else { 00292 const GLfloat *current = (const GLfloat *)vbo->currval[j].Ptr; 00293 COPY_SZ_4V( dest, newsz, current ); 00294 dest += newsz; 00295 } 00296 } 00297 else { 00298 GLuint sz = exec->vtx.attrsz[j]; 00299 COPY_SZ_4V( dest, sz, data ); 00300 dest += sz; 00301 data += sz; 00302 } 00303 } 00304 } 00305 } 00306 00307 exec->vtx.vbptr = dest; 00308 exec->vtx.vert_count += exec->vtx.copied.nr; 00309 exec->vtx.copied.nr = 0; 00310 } 00311 } 00312 00313 00314 static void vbo_exec_fixup_vertex( GLcontext *ctx, 00315 GLuint attr, GLuint sz ) 00316 { 00317 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00318 int i; 00319 00320 if (sz > exec->vtx.attrsz[attr]) { 00321 /* New size is larger. Need to flush existing vertices and get 00322 * an enlarged vertex format. 00323 */ 00324 vbo_exec_wrap_upgrade_vertex( exec, attr, sz ); 00325 } 00326 else if (sz < exec->vtx.active_sz[attr]) { 00327 static const GLfloat id[4] = { 0, 0, 0, 1 }; 00328 00329 /* New size is smaller - just need to fill in some 00330 * zeros. Don't need to flush or wrap. 00331 */ 00332 for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++) 00333 exec->vtx.attrptr[attr][i-1] = id[i-1]; 00334 } 00335 00336 exec->vtx.active_sz[attr] = sz; 00337 00338 /* Does setting NeedFlush belong here? Necessitates resetting 00339 * vtxfmt on each flush (otherwise flags won't get reset 00340 * afterwards). 00341 */ 00342 if (attr == 0) 00343 exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; 00344 else 00345 exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; 00346 } 00347 00348 00349 00350 00351 /* 00352 */ 00353 #define ATTR( A, N, V0, V1, V2, V3 ) \ 00354 do { \ 00355 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \ 00356 \ 00357 if (exec->vtx.active_sz[A] != N) \ 00358 vbo_exec_fixup_vertex(ctx, A, N); \ 00359 \ 00360 { \ 00361 GLfloat *dest = exec->vtx.attrptr[A]; \ 00362 if (N>0) dest[0] = V0; \ 00363 if (N>1) dest[1] = V1; \ 00364 if (N>2) dest[2] = V2; \ 00365 if (N>3) dest[3] = V3; \ 00366 } \ 00367 \ 00368 if ((A) == 0) { \ 00369 GLuint i; \ 00370 \ 00371 for (i = 0; i < exec->vtx.vertex_size; i++) \ 00372 exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ 00373 \ 00374 exec->vtx.vbptr += exec->vtx.vertex_size; \ 00375 exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ 00376 \ 00377 if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ 00378 vbo_exec_vtx_wrap( exec ); \ 00379 } \ 00380 } while (0) 00381 00382 00383 #define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) 00384 #define TAG(x) vbo_##x 00385 00386 #include "vbo_attrib_tmp.h" 00387 00388 00389 00390 00391 00392 /* Eval 00393 */ 00394 static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u ) 00395 { 00396 GET_CURRENT_CONTEXT( ctx ); 00397 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00398 00399 { 00400 GLint i; 00401 if (exec->eval.recalculate_maps) 00402 vbo_exec_eval_update( exec ); 00403 00404 for (i = 0; i <= VBO_ATTRIB_TEX7; i++) { 00405 if (exec->eval.map1[i].map) 00406 if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) 00407 vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); 00408 } 00409 } 00410 00411 00412 _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, 00413 exec->vtx.vertex_size * sizeof(GLfloat)); 00414 00415 vbo_exec_do_EvalCoord1f( exec, u ); 00416 00417 _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, 00418 exec->vtx.vertex_size * sizeof(GLfloat)); 00419 } 00420 00421 static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v ) 00422 { 00423 GET_CURRENT_CONTEXT( ctx ); 00424 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00425 00426 { 00427 GLint i; 00428 if (exec->eval.recalculate_maps) 00429 vbo_exec_eval_update( exec ); 00430 00431 for (i = 0; i <= VBO_ATTRIB_TEX7; i++) { 00432 if (exec->eval.map2[i].map) 00433 if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) 00434 vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); 00435 } 00436 00437 if (ctx->Eval.AutoNormal) 00438 if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3) 00439 vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 ); 00440 } 00441 00442 _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, 00443 exec->vtx.vertex_size * sizeof(GLfloat)); 00444 00445 vbo_exec_do_EvalCoord2f( exec, u, v ); 00446 00447 _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, 00448 exec->vtx.vertex_size * sizeof(GLfloat)); 00449 } 00450 00451 static void GLAPIENTRY vbo_exec_EvalCoord1fv( const GLfloat *u ) 00452 { 00453 vbo_exec_EvalCoord1f( u[0] ); 00454 } 00455 00456 static void GLAPIENTRY vbo_exec_EvalCoord2fv( const GLfloat *u ) 00457 { 00458 vbo_exec_EvalCoord2f( u[0], u[1] ); 00459 } 00460 00461 static void GLAPIENTRY vbo_exec_EvalPoint1( GLint i ) 00462 { 00463 GET_CURRENT_CONTEXT( ctx ); 00464 GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / 00465 (GLfloat) ctx->Eval.MapGrid1un); 00466 GLfloat u = i * du + ctx->Eval.MapGrid1u1; 00467 00468 vbo_exec_EvalCoord1f( u ); 00469 } 00470 00471 00472 static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) 00473 { 00474 GET_CURRENT_CONTEXT( ctx ); 00475 GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / 00476 (GLfloat) ctx->Eval.MapGrid2un); 00477 GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / 00478 (GLfloat) ctx->Eval.MapGrid2vn); 00479 GLfloat u = i * du + ctx->Eval.MapGrid2u1; 00480 GLfloat v = j * dv + ctx->Eval.MapGrid2v1; 00481 00482 vbo_exec_EvalCoord2f( u, v ); 00483 } 00484 00485 00489 GLboolean 00490 vbo_validate_shaders(GLcontext *ctx) 00491 { 00492 if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || 00493 (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { 00494 return GL_FALSE; 00495 } 00496 if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) { 00497 return GL_FALSE; 00498 } 00499 return GL_TRUE; 00500 } 00501 00502 00503 /* Build a list of primitives on the fly. Keep 00504 * ctx->Driver.CurrentExecPrimitive uptodate as well. 00505 */ 00506 static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) 00507 { 00508 GET_CURRENT_CONTEXT( ctx ); 00509 00510 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { 00511 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00512 int i; 00513 00514 if (ctx->NewState) { 00515 _mesa_update_state( ctx ); 00516 00517 CALL_Begin(ctx->Exec, (mode)); 00518 return; 00519 } 00520 00521 if (!vbo_validate_shaders(ctx)) { 00522 _mesa_error(ctx, GL_INVALID_OPERATION, 00523 "glBegin (invalid vertex/fragment program)"); 00524 return; 00525 } 00526 00527 /* Heuristic: attempt to isolate attributes occuring outside 00528 * begin/end pairs. 00529 */ 00530 if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) 00531 vbo_exec_FlushVertices( ctx, ~0 ); 00532 00533 i = exec->vtx.prim_count++; 00534 exec->vtx.prim[i].mode = mode; 00535 exec->vtx.prim[i].begin = 1; 00536 exec->vtx.prim[i].end = 0; 00537 exec->vtx.prim[i].indexed = 0; 00538 exec->vtx.prim[i].weak = 0; 00539 exec->vtx.prim[i].pad = 0; 00540 exec->vtx.prim[i].start = exec->vtx.vert_count; 00541 exec->vtx.prim[i].count = 0; 00542 00543 ctx->Driver.CurrentExecPrimitive = mode; 00544 } 00545 else 00546 _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); 00547 00548 } 00549 00550 static void GLAPIENTRY vbo_exec_End( void ) 00551 { 00552 GET_CURRENT_CONTEXT( ctx ); 00553 00554 if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { 00555 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00556 int idx = exec->vtx.vert_count; 00557 int i = exec->vtx.prim_count - 1; 00558 00559 exec->vtx.prim[i].end = 1; 00560 exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; 00561 00562 ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; 00563 00564 if (exec->vtx.prim_count == VBO_MAX_PRIM) 00565 vbo_exec_vtx_flush( exec ); 00566 } 00567 else 00568 _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); 00569 } 00570 00571 00572 static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec ) 00573 { 00574 GLvertexformat *vfmt = &exec->vtxfmt; 00575 00576 vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ 00577 vfmt->Begin = vbo_exec_Begin; 00578 #if FEATURE_dlist 00579 vfmt->CallList = _mesa_CallList; 00580 vfmt->CallLists = _mesa_CallLists; 00581 #endif 00582 vfmt->End = vbo_exec_End; 00583 vfmt->EvalCoord1f = vbo_exec_EvalCoord1f; 00584 vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv; 00585 vfmt->EvalCoord2f = vbo_exec_EvalCoord2f; 00586 vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv; 00587 vfmt->EvalPoint1 = vbo_exec_EvalPoint1; 00588 vfmt->EvalPoint2 = vbo_exec_EvalPoint2; 00589 00590 vfmt->Rectf = _mesa_noop_Rectf; 00591 vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; 00592 vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; 00593 00594 00595 /* from attrib_tmp.h: 00596 */ 00597 vfmt->Color3f = vbo_Color3f; 00598 vfmt->Color3fv = vbo_Color3fv; 00599 vfmt->Color4f = vbo_Color4f; 00600 vfmt->Color4fv = vbo_Color4fv; 00601 vfmt->FogCoordfEXT = vbo_FogCoordfEXT; 00602 vfmt->FogCoordfvEXT = vbo_FogCoordfvEXT; 00603 vfmt->MultiTexCoord1fARB = vbo_MultiTexCoord1f; 00604 vfmt->MultiTexCoord1fvARB = vbo_MultiTexCoord1fv; 00605 vfmt->MultiTexCoord2fARB = vbo_MultiTexCoord2f; 00606 vfmt->MultiTexCoord2fvARB = vbo_MultiTexCoord2fv; 00607 vfmt->MultiTexCoord3fARB = vbo_MultiTexCoord3f; 00608 vfmt->MultiTexCoord3fvARB = vbo_MultiTexCoord3fv; 00609 vfmt->MultiTexCoord4fARB = vbo_MultiTexCoord4f; 00610 vfmt->MultiTexCoord4fvARB = vbo_MultiTexCoord4fv; 00611 vfmt->Normal3f = vbo_Normal3f; 00612 vfmt->Normal3fv = vbo_Normal3fv; 00613 vfmt->SecondaryColor3fEXT = vbo_SecondaryColor3fEXT; 00614 vfmt->SecondaryColor3fvEXT = vbo_SecondaryColor3fvEXT; 00615 vfmt->TexCoord1f = vbo_TexCoord1f; 00616 vfmt->TexCoord1fv = vbo_TexCoord1fv; 00617 vfmt->TexCoord2f = vbo_TexCoord2f; 00618 vfmt->TexCoord2fv = vbo_TexCoord2fv; 00619 vfmt->TexCoord3f = vbo_TexCoord3f; 00620 vfmt->TexCoord3fv = vbo_TexCoord3fv; 00621 vfmt->TexCoord4f = vbo_TexCoord4f; 00622 vfmt->TexCoord4fv = vbo_TexCoord4fv; 00623 vfmt->Vertex2f = vbo_Vertex2f; 00624 vfmt->Vertex2fv = vbo_Vertex2fv; 00625 vfmt->Vertex3f = vbo_Vertex3f; 00626 vfmt->Vertex3fv = vbo_Vertex3fv; 00627 vfmt->Vertex4f = vbo_Vertex4f; 00628 vfmt->Vertex4fv = vbo_Vertex4fv; 00629 00630 vfmt->VertexAttrib1fARB = vbo_VertexAttrib1fARB; 00631 vfmt->VertexAttrib1fvARB = vbo_VertexAttrib1fvARB; 00632 vfmt->VertexAttrib2fARB = vbo_VertexAttrib2fARB; 00633 vfmt->VertexAttrib2fvARB = vbo_VertexAttrib2fvARB; 00634 vfmt->VertexAttrib3fARB = vbo_VertexAttrib3fARB; 00635 vfmt->VertexAttrib3fvARB = vbo_VertexAttrib3fvARB; 00636 vfmt->VertexAttrib4fARB = vbo_VertexAttrib4fARB; 00637 vfmt->VertexAttrib4fvARB = vbo_VertexAttrib4fvARB; 00638 00639 vfmt->VertexAttrib1fNV = vbo_VertexAttrib1fNV; 00640 vfmt->VertexAttrib1fvNV = vbo_VertexAttrib1fvNV; 00641 vfmt->VertexAttrib2fNV = vbo_VertexAttrib2fNV; 00642 vfmt->VertexAttrib2fvNV = vbo_VertexAttrib2fvNV; 00643 vfmt->VertexAttrib3fNV = vbo_VertexAttrib3fNV; 00644 vfmt->VertexAttrib3fvNV = vbo_VertexAttrib3fvNV; 00645 vfmt->VertexAttrib4fNV = vbo_VertexAttrib4fNV; 00646 vfmt->VertexAttrib4fvNV = vbo_VertexAttrib4fvNV; 00647 00648 vfmt->Materialfv = vbo_Materialfv; 00649 00650 vfmt->EdgeFlag = vbo_EdgeFlag; 00651 vfmt->Indexf = vbo_Indexf; 00652 vfmt->Indexfv = vbo_Indexfv; 00653 00654 } 00655 00656 00663 void vbo_use_buffer_objects(GLcontext *ctx) 00664 { 00665 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00666 /* Any buffer name but 0 can be used here since this bufferobj won't 00667 * go into the bufferobj hashtable. 00668 */ 00669 GLuint bufName = 0xaabbccdd; 00670 GLenum target = GL_ARRAY_BUFFER_ARB; 00671 GLenum access = GL_READ_WRITE_ARB; 00672 GLenum usage = GL_STREAM_DRAW_ARB; 00673 GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat); 00674 00675 /* Make sure this func is only used once */ 00676 assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj); 00677 if (exec->vtx.buffer_map) { 00678 _mesa_align_free(exec->vtx.buffer_map); 00679 } 00680 00681 /* Allocate a real buffer object now */ 00682 exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target); 00683 ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); 00684 00685 /* and map it */ 00686 exec->vtx.buffer_map 00687 = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj); 00688 } 00689 00690 00691 00692 void vbo_exec_vtx_init( struct vbo_exec_context *exec ) 00693 { 00694 GLcontext *ctx = exec->ctx; 00695 struct vbo_context *vbo = vbo_context(ctx); 00696 GLuint i; 00697 00698 /* Allocate a buffer object. Will just reuse this object 00699 * continuously. 00700 */ 00701 _mesa_reference_buffer_object(ctx, 00702 &exec->vtx.bufferobj, 00703 ctx->Array.NullBufferObj); 00704 00705 ASSERT(!exec->vtx.buffer_map); 00706 exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); 00707 vbo_exec_vtxfmt_init( exec ); 00708 00709 /* Hook our functions into the dispatch table. 00710 */ 00711 _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); 00712 00713 for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { 00714 exec->vtx.attrsz[i] = 0; 00715 exec->vtx.active_sz[i] = 0; 00716 exec->vtx.inputs[i] = &exec->vtx.arrays[i]; 00717 } 00718 00719 { 00720 struct gl_client_array *arrays = exec->vtx.arrays; 00721 memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); 00722 memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); 00723 } 00724 00725 exec->vtx.vertex_size = 0; 00726 } 00727 00728 00729 void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ) 00730 { 00731 if (exec->vtx.bufferobj->Name) { 00732 /* using a real VBO for vertex data */ 00733 GLcontext *ctx = exec->ctx; 00734 _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL); 00735 } 00736 else { 00737 /* just using malloc'd space for vertex data */ 00738 if (exec->vtx.buffer_map) { 00739 ALIGN_FREE(exec->vtx.buffer_map); 00740 exec->vtx.buffer_map = NULL; 00741 } 00742 } 00743 } 00744 00745 00746 void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) 00747 { 00748 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 00749 00750 if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) 00751 return; 00752 00753 if (exec->vtx.vert_count) { 00754 vbo_exec_vtx_flush( exec ); 00755 } 00756 00757 if (exec->vtx.vertex_size) { 00758 vbo_exec_copy_to_current( exec ); 00759 reset_attrfv( exec ); 00760 } 00761 00762 exec->ctx->Driver.NeedFlush = 0; 00763 } 00764 00765 00766 static void reset_attrfv( struct vbo_exec_context *exec ) 00767 { 00768 GLuint i; 00769 00770 for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { 00771 exec->vtx.attrsz[i] = 0; 00772 exec->vtx.active_sz[i] = 0; 00773 } 00774 00775 exec->vtx.vertex_size = 0; 00776 } 00777 Generated on Sat May 26 2012 04:19:38 for ReactOS by
1.7.6.1
|