1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Keith Whitwell <keithw@vmware.com> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <stdbool.h> 29bf215546Sopenharmony_ci#include <stdio.h> 30bf215546Sopenharmony_ci#include "main/arrayobj.h" 31bf215546Sopenharmony_ci#include "main/glheader.h" 32bf215546Sopenharmony_ci#include "main/bufferobj.h" 33bf215546Sopenharmony_ci#include "main/context.h" 34bf215546Sopenharmony_ci#include "main/enums.h" 35bf215546Sopenharmony_ci#include "main/state.h" 36bf215546Sopenharmony_ci#include "main/varray.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "vbo_private.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic void 41bf215546Sopenharmony_civbo_exec_debug_verts(struct vbo_exec_context *exec) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci GLuint count = exec->vtx.vert_count; 44bf215546Sopenharmony_ci GLuint i; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci printf("%s: %u vertices %d primitives, %d vertsize\n", 47bf215546Sopenharmony_ci __func__, 48bf215546Sopenharmony_ci count, 49bf215546Sopenharmony_ci exec->vtx.prim_count, 50bf215546Sopenharmony_ci exec->vtx.vertex_size); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci for (i = 0 ; i < exec->vtx.prim_count ; i++) { 53bf215546Sopenharmony_ci printf(" prim %d: %s %d..%d %s %s\n", 54bf215546Sopenharmony_ci i, 55bf215546Sopenharmony_ci _mesa_lookup_prim_by_nr(exec->vtx.mode[i]), 56bf215546Sopenharmony_ci exec->vtx.draw[i].start, 57bf215546Sopenharmony_ci exec->vtx.draw[i].start + exec->vtx.draw[i].count, 58bf215546Sopenharmony_ci exec->vtx.markers[i].begin ? "BEGIN" : "(wrap)", 59bf215546Sopenharmony_ci exec->vtx.markers[i].end ? "END" : "(wrap)"); 60bf215546Sopenharmony_ci } 61bf215546Sopenharmony_ci} 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_cistatic GLuint 65bf215546Sopenharmony_civbo_exec_copy_vertices(struct vbo_exec_context *exec) 66bf215546Sopenharmony_ci{ 67bf215546Sopenharmony_ci struct gl_context *ctx = gl_context_from_vbo_exec(exec); 68bf215546Sopenharmony_ci const GLuint sz = exec->vtx.vertex_size; 69bf215546Sopenharmony_ci fi_type *dst = exec->vtx.copied.buffer; 70bf215546Sopenharmony_ci unsigned last = exec->vtx.prim_count - 1; 71bf215546Sopenharmony_ci unsigned start = exec->vtx.draw[last].start; 72bf215546Sopenharmony_ci const fi_type *src = exec->vtx.buffer_map + start * sz; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci return vbo_copy_vertices(ctx, ctx->Driver.CurrentExecPrimitive, 75bf215546Sopenharmony_ci start, 76bf215546Sopenharmony_ci &exec->vtx.draw[last].count, 77bf215546Sopenharmony_ci exec->vtx.markers[last].begin, 78bf215546Sopenharmony_ci sz, false, dst, src); 79bf215546Sopenharmony_ci} 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci/* TODO: populate these as the vertex is defined: 84bf215546Sopenharmony_ci */ 85bf215546Sopenharmony_cistatic void 86bf215546Sopenharmony_civbo_exec_bind_arrays(struct gl_context *ctx) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci struct vbo_context *vbo = vbo_context(ctx); 89bf215546Sopenharmony_ci struct gl_vertex_array_object *vao = vbo->VAO; 90bf215546Sopenharmony_ci struct vbo_exec_context *exec = &vbo->exec; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci GLintptr buffer_offset; 93bf215546Sopenharmony_ci if (exec->vtx.bufferobj) { 94bf215546Sopenharmony_ci assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer); 95bf215546Sopenharmony_ci buffer_offset = exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + 96bf215546Sopenharmony_ci exec->vtx.buffer_offset; 97bf215546Sopenharmony_ci } else { 98bf215546Sopenharmony_ci /* Ptr into ordinary app memory */ 99bf215546Sopenharmony_ci buffer_offset = (GLbyte *)exec->vtx.buffer_map - (GLbyte *)NULL; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci GLbitfield vao_enabled, vao_filter; 105bf215546Sopenharmony_ci if (_mesa_hw_select_enabled(ctx)) { 106bf215546Sopenharmony_ci /* HW GL_SELECT has fixed input */ 107bf215546Sopenharmony_ci vao_enabled = vao_filter = VERT_BIT_POS | VERT_BIT_SELECT_RESULT_OFFSET; 108bf215546Sopenharmony_ci } else { 109bf215546Sopenharmony_ci vao_enabled = _vbo_get_vao_enabled_from_vbo(mode, exec->vtx.enabled); 110bf215546Sopenharmony_ci vao_filter = _vbo_get_vao_filter(mode); 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci /* At first disable arrays no longer needed */ 114bf215546Sopenharmony_ci _mesa_disable_vertex_array_attribs(ctx, vao, VERT_BIT_ALL & ~vao_enabled); 115bf215546Sopenharmony_ci assert((~vao_enabled & vao->Enabled) == 0); 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci /* Bind the buffer object */ 118bf215546Sopenharmony_ci const GLuint stride = exec->vtx.vertex_size*sizeof(GLfloat); 119bf215546Sopenharmony_ci _mesa_bind_vertex_buffer(ctx, vao, 0, exec->vtx.bufferobj, buffer_offset, 120bf215546Sopenharmony_ci stride, false, false); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci /* Retrieve the mapping from VBO_ATTRIB to VERT_ATTRIB space 123bf215546Sopenharmony_ci * Note that the position/generic0 aliasing is done in the VAO. 124bf215546Sopenharmony_ci */ 125bf215546Sopenharmony_ci const GLubyte *const vao_to_vbo_map = _vbo_attribute_alias_map[mode]; 126bf215546Sopenharmony_ci /* Now set the enabled arrays */ 127bf215546Sopenharmony_ci GLbitfield mask = vao_enabled; 128bf215546Sopenharmony_ci while (mask) { 129bf215546Sopenharmony_ci const int vao_attr = u_bit_scan(&mask); 130bf215546Sopenharmony_ci const GLubyte vbo_attr = vao_to_vbo_map[vao_attr]; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci const GLubyte size = exec->vtx.attr[vbo_attr].size; 133bf215546Sopenharmony_ci const GLenum16 type = exec->vtx.attr[vbo_attr].type; 134bf215546Sopenharmony_ci const GLuint offset = (GLuint)((GLbyte *)exec->vtx.attrptr[vbo_attr] - 135bf215546Sopenharmony_ci (GLbyte *)exec->vtx.vertex); 136bf215546Sopenharmony_ci assert(offset <= ctx->Const.MaxVertexAttribRelativeOffset); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci /* Set and enable */ 139bf215546Sopenharmony_ci _vbo_set_attrib_format(ctx, vao, vao_attr, buffer_offset, 140bf215546Sopenharmony_ci size, type, offset); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci /* The vao is initially created with all bindings set to 0. */ 143bf215546Sopenharmony_ci assert(vao->VertexAttrib[vao_attr].BufferBindingIndex == 0); 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci _mesa_enable_vertex_array_attribs(ctx, vao, vao_enabled); 146bf215546Sopenharmony_ci assert(vao_enabled == vao->Enabled); 147bf215546Sopenharmony_ci assert(!exec->vtx.bufferobj || 148bf215546Sopenharmony_ci (vao_enabled & ~vao->VertexAttribBufferMask) == 0); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci _mesa_set_draw_vao(ctx, vao, vao_filter); 151bf215546Sopenharmony_ci} 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci/** 155bf215546Sopenharmony_ci * Unmap the VBO. This is called before drawing. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_cistatic void 158bf215546Sopenharmony_civbo_exec_vtx_unmap(struct vbo_exec_context *exec) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci if (exec->vtx.bufferobj) { 161bf215546Sopenharmony_ci struct gl_context *ctx = gl_context_from_vbo_exec(exec); 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_buffer_storage) { 164bf215546Sopenharmony_ci GLintptr offset = exec->vtx.buffer_used - 165bf215546Sopenharmony_ci exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset; 166bf215546Sopenharmony_ci GLsizeiptr length = (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * 167bf215546Sopenharmony_ci sizeof(float); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (length) 170bf215546Sopenharmony_ci _mesa_bufferobj_flush_mapped_range(ctx, offset, length, 171bf215546Sopenharmony_ci exec->vtx.bufferobj, 172bf215546Sopenharmony_ci MAP_INTERNAL); 173bf215546Sopenharmony_ci } 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci exec->vtx.buffer_used += (exec->vtx.buffer_ptr - 176bf215546Sopenharmony_ci exec->vtx.buffer_map) * sizeof(float); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci assert(exec->vtx.buffer_used <= ctx->Const.glBeginEndBufferSize); 179bf215546Sopenharmony_ci assert(exec->vtx.buffer_ptr != NULL); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci _mesa_bufferobj_unmap(ctx, exec->vtx.bufferobj, MAP_INTERNAL); 182bf215546Sopenharmony_ci exec->vtx.buffer_map = NULL; 183bf215546Sopenharmony_ci exec->vtx.buffer_ptr = NULL; 184bf215546Sopenharmony_ci exec->vtx.max_vert = 0; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cistatic bool 189bf215546Sopenharmony_civbo_exec_buffer_has_space(struct vbo_exec_context *exec) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci struct gl_context *ctx = gl_context_from_vbo_exec(exec); 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci return ctx->Const.glBeginEndBufferSize > exec->vtx.buffer_used + 1024; 194bf215546Sopenharmony_ci} 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci/** 198bf215546Sopenharmony_ci * Map the vertex buffer to begin storing glVertex, glColor, etc data. 199bf215546Sopenharmony_ci */ 200bf215546Sopenharmony_civoid 201bf215546Sopenharmony_civbo_exec_vtx_map(struct vbo_exec_context *exec) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci struct gl_context *ctx = gl_context_from_vbo_exec(exec); 204bf215546Sopenharmony_ci const GLenum usage = GL_STREAM_DRAW_ARB; 205bf215546Sopenharmony_ci GLenum accessRange = GL_MAP_WRITE_BIT | /* for MapBufferRange */ 206bf215546Sopenharmony_ci GL_MAP_UNSYNCHRONIZED_BIT; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci if (ctx->Extensions.ARB_buffer_storage) { 209bf215546Sopenharmony_ci /* We sometimes read from the buffer, so map it for read too. 210bf215546Sopenharmony_ci * Only the persistent mapping can do that, because the non-persistent 211bf215546Sopenharmony_ci * mapping uses flags that are incompatible with GL_MAP_READ_BIT. 212bf215546Sopenharmony_ci */ 213bf215546Sopenharmony_ci accessRange |= GL_MAP_PERSISTENT_BIT | 214bf215546Sopenharmony_ci GL_MAP_COHERENT_BIT | 215bf215546Sopenharmony_ci GL_MAP_READ_BIT; 216bf215546Sopenharmony_ci } else { 217bf215546Sopenharmony_ci accessRange |= GL_MAP_INVALIDATE_RANGE_BIT | 218bf215546Sopenharmony_ci GL_MAP_FLUSH_EXPLICIT_BIT | 219bf215546Sopenharmony_ci MESA_MAP_NOWAIT_BIT; 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci if (!exec->vtx.bufferobj) 223bf215546Sopenharmony_ci return; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci assert(!exec->vtx.buffer_map); 226bf215546Sopenharmony_ci assert(!exec->vtx.buffer_ptr); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci if (vbo_exec_buffer_has_space(exec)) { 229bf215546Sopenharmony_ci /* The VBO exists and there's room for more */ 230bf215546Sopenharmony_ci if (exec->vtx.bufferobj->Size > 0) { 231bf215546Sopenharmony_ci exec->vtx.buffer_map = (fi_type *) 232bf215546Sopenharmony_ci _mesa_bufferobj_map_range(ctx, 233bf215546Sopenharmony_ci exec->vtx.buffer_used, 234bf215546Sopenharmony_ci ctx->Const.glBeginEndBufferSize 235bf215546Sopenharmony_ci - exec->vtx.buffer_used, 236bf215546Sopenharmony_ci accessRange, 237bf215546Sopenharmony_ci exec->vtx.bufferobj, 238bf215546Sopenharmony_ci MAP_INTERNAL); 239bf215546Sopenharmony_ci exec->vtx.buffer_ptr = exec->vtx.buffer_map; 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci else { 242bf215546Sopenharmony_ci exec->vtx.buffer_ptr = exec->vtx.buffer_map = NULL; 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci if (!exec->vtx.buffer_map) { 247bf215546Sopenharmony_ci /* Need to allocate a new VBO */ 248bf215546Sopenharmony_ci exec->vtx.buffer_used = 0; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci if (_mesa_bufferobj_data(ctx, GL_ARRAY_BUFFER_ARB, 251bf215546Sopenharmony_ci ctx->Const.glBeginEndBufferSize, 252bf215546Sopenharmony_ci NULL, usage, 253bf215546Sopenharmony_ci GL_MAP_WRITE_BIT | 254bf215546Sopenharmony_ci (ctx->Extensions.ARB_buffer_storage ? 255bf215546Sopenharmony_ci GL_MAP_PERSISTENT_BIT | 256bf215546Sopenharmony_ci GL_MAP_COHERENT_BIT | 257bf215546Sopenharmony_ci GL_MAP_READ_BIT : 0) | 258bf215546Sopenharmony_ci GL_DYNAMIC_STORAGE_BIT | 259bf215546Sopenharmony_ci GL_CLIENT_STORAGE_BIT, 260bf215546Sopenharmony_ci exec->vtx.bufferobj)) { 261bf215546Sopenharmony_ci /* buffer allocation worked, now map the buffer */ 262bf215546Sopenharmony_ci exec->vtx.buffer_map = 263bf215546Sopenharmony_ci (fi_type *)_mesa_bufferobj_map_range(ctx, 264bf215546Sopenharmony_ci 0, ctx->Const.glBeginEndBufferSize, 265bf215546Sopenharmony_ci accessRange, 266bf215546Sopenharmony_ci exec->vtx.bufferobj, 267bf215546Sopenharmony_ci MAP_INTERNAL); 268bf215546Sopenharmony_ci } 269bf215546Sopenharmony_ci else { 270bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "VBO allocation"); 271bf215546Sopenharmony_ci exec->vtx.buffer_map = NULL; 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci exec->vtx.buffer_ptr = exec->vtx.buffer_map; 276bf215546Sopenharmony_ci exec->vtx.buffer_offset = 0; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci if (!exec->vtx.buffer_map) { 279bf215546Sopenharmony_ci /* out of memory */ 280bf215546Sopenharmony_ci vbo_install_exec_vtxfmt_noop(ctx); 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci else { 283bf215546Sopenharmony_ci if (_mesa_using_noop_vtxfmt(ctx->Exec)) { 284bf215546Sopenharmony_ci /* The no-op functions are installed so switch back to regular 285bf215546Sopenharmony_ci * functions. We do this test just to avoid frequent and needless 286bf215546Sopenharmony_ci * calls to vbo_install_exec_vtxfmt(). 287bf215546Sopenharmony_ci */ 288bf215546Sopenharmony_ci vbo_install_exec_vtxfmt(ctx); 289bf215546Sopenharmony_ci } 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci if (0) 293bf215546Sopenharmony_ci printf("map %d..\n", exec->vtx.buffer_used); 294bf215546Sopenharmony_ci} 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci/** 299bf215546Sopenharmony_ci * Execute the buffer and save copied verts. 300bf215546Sopenharmony_ci */ 301bf215546Sopenharmony_civoid 302bf215546Sopenharmony_civbo_exec_vtx_flush(struct vbo_exec_context *exec) 303bf215546Sopenharmony_ci{ 304bf215546Sopenharmony_ci struct gl_context *ctx = gl_context_from_vbo_exec(exec); 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci /* Only unmap if persistent mappings are unsupported. */ 307bf215546Sopenharmony_ci bool persistent_mapping = ctx->Extensions.ARB_buffer_storage && 308bf215546Sopenharmony_ci exec->vtx.bufferobj && 309bf215546Sopenharmony_ci exec->vtx.buffer_map; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci if (0) 312bf215546Sopenharmony_ci vbo_exec_debug_verts(exec); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci if (exec->vtx.prim_count && 315bf215546Sopenharmony_ci exec->vtx.vert_count) { 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci exec->vtx.copied.nr = vbo_exec_copy_vertices(exec); 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if (exec->vtx.copied.nr != exec->vtx.vert_count) { 320bf215546Sopenharmony_ci /* Prepare and set the exec draws internal VAO for drawing. */ 321bf215546Sopenharmony_ci vbo_exec_bind_arrays(ctx); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (ctx->NewState) 324bf215546Sopenharmony_ci _mesa_update_state(ctx); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (!persistent_mapping) 327bf215546Sopenharmony_ci vbo_exec_vtx_unmap(exec); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci assert(ctx->NewState == 0); 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci if (0) 332bf215546Sopenharmony_ci printf("%s %d %d\n", __func__, exec->vtx.prim_count, 333bf215546Sopenharmony_ci exec->vtx.vert_count); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci ctx->Driver.DrawGalliumMultiMode(ctx, &exec->vtx.info, 336bf215546Sopenharmony_ci exec->vtx.draw, 337bf215546Sopenharmony_ci exec->vtx.mode, 338bf215546Sopenharmony_ci exec->vtx.prim_count); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci /* Get new storage -- unless asked not to. */ 341bf215546Sopenharmony_ci if (!persistent_mapping) 342bf215546Sopenharmony_ci vbo_exec_vtx_map(exec); 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci if (persistent_mapping) { 347bf215546Sopenharmony_ci exec->vtx.buffer_used += (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * 348bf215546Sopenharmony_ci sizeof(float); 349bf215546Sopenharmony_ci exec->vtx.buffer_map = exec->vtx.buffer_ptr; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci /* Set the buffer offset for the next draw. */ 352bf215546Sopenharmony_ci exec->vtx.buffer_offset = exec->vtx.buffer_used; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci if (!vbo_exec_buffer_has_space(exec)) { 355bf215546Sopenharmony_ci /* This will allocate a new buffer. */ 356bf215546Sopenharmony_ci vbo_exec_vtx_unmap(exec); 357bf215546Sopenharmony_ci vbo_exec_vtx_map(exec); 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci if (exec->vtx.vertex_size == 0) 362bf215546Sopenharmony_ci exec->vtx.max_vert = 0; 363bf215546Sopenharmony_ci else 364bf215546Sopenharmony_ci exec->vtx.max_vert = vbo_compute_max_verts(exec); 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci exec->vtx.buffer_ptr = exec->vtx.buffer_map; 367bf215546Sopenharmony_ci exec->vtx.prim_count = 0; 368bf215546Sopenharmony_ci exec->vtx.vert_count = 0; 369bf215546Sopenharmony_ci} 370