]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
some cleanup of glDelete calls to guard against bugs caused by GL
[xonotic/darkplaces.git] / gl_rmain.c
index a1530a6fdc5f79207131175e05430d1799086a13..bccc104bad9fcfaf51f86033fd7394759d3cbe63 100644 (file)
@@ -238,12 +238,12 @@ cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompe
 cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
 
 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
-cvar_t r_bufferdatasize[R_BUFFERDATA_COUNT] =
+cvar_t r_buffermegs[R_BUFFERDATA_COUNT] =
 {
-       {CVAR_SAVE, "r_bufferdatasize_vertex", "4", "vertex buffer size for one frame"},
-       {CVAR_SAVE, "r_bufferdatasize_index16", "1", "index buffer size for one frame (16bit indices)"},
-       {CVAR_SAVE, "r_bufferdatasize_index32", "1", "index buffer size for one frame (32bit indices)"},
-       {CVAR_SAVE, "r_bufferdatasize_uniform", "0.25", "uniform buffer size for one frame"},
+       {CVAR_SAVE, "r_buffermegs_vertex", "4", "vertex buffer size for one frame"},
+       {CVAR_SAVE, "r_buffermegs_index16", "1", "index buffer size for one frame (16bit indices)"},
+       {CVAR_SAVE, "r_buffermegs_index32", "1", "index buffer size for one frame (32bit indices)"},
+       {CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
 };
 
 extern cvar_t v_glslgamma;
@@ -1311,7 +1311,10 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                if (p->loc_Texture_ReflectCube     >= 0) {p->tex_Texture_ReflectCube      = sampler;qglUniform1i(p->loc_Texture_ReflectCube     , sampler);sampler++;}
                if (p->loc_Texture_BounceGrid      >= 0) {p->tex_Texture_BounceGrid       = sampler;qglUniform1i(p->loc_Texture_BounceGrid      , sampler);sampler++;}
                // get the uniform block indices so we can bind them
-               p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
+               if (vid.support.arb_uniform_buffer_object)
+                       p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
+               else
+                       p->ubiloc_Skeletal_Transform12_UniformBlock = -1;
                // clear the uniform block bindings
                p->ubibind_Skeletal_Transform12_UniformBlock = -1;
                // bind the uniform blocks in use
@@ -4353,7 +4356,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_glsl_vertextextureblend_usebothalphas);
        Cvar_RegisterVariable(&r_framedatasize);
        for (i = 0;i < R_BUFFERDATA_COUNT;i++)
-               Cvar_RegisterVariable(&r_bufferdatasize[i]);
+               Cvar_RegisterVariable(&r_buffermegs[i]);
        Cvar_RegisterVariable(&r_batch_dynamicbuffer);
        if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
                Cvar_SetValue("r_fullbrights", 0);
@@ -4628,8 +4631,8 @@ void R_FrameData_ReturnToMark(void)
 
 //==================================================================================
 
-// avoid reusing the same buffer objects on consecutive buffers
-#define R_BUFFERDATA_CYCLE 2
+// avoid reusing the same buffer objects on consecutive frames
+#define R_BUFFERDATA_CYCLE 3
 
 typedef struct r_bufferdata_buffer_s
 {
@@ -4653,7 +4656,7 @@ void R_BufferData_Reset(void)
                for (type = 0;type < R_BUFFERDATA_COUNT;type++)
                {
                        // free all buffers
-                       p = &r_bufferdata_buffer[r_bufferdata_cycle][type];
+                       p = &r_bufferdata_buffer[cycle][type];
                        while (*p)
                        {
                                mem = *p;
@@ -4667,12 +4670,30 @@ void R_BufferData_Reset(void)
 }
 
 // resize buffer as needed (this actually makes a new one, the old one will be recycled next frame)
-static void R_BufferData_Resize(r_bufferdata_type_t type, qboolean mustgrow)
+static void R_BufferData_Resize(r_bufferdata_type_t type, qboolean mustgrow, size_t minsize)
 {
        r_bufferdata_buffer_t *mem = r_bufferdata_buffer[r_bufferdata_cycle][type];
        size_t size;
-       size = (size_t)(r_bufferdatasize[type].value * 1024*1024);
-       size = bound(65536, size, 512*1024*1024);
+       float newvalue = r_buffermegs[type].value;
+
+       // increase the cvar if we have to (but only if we already have a mem)
+       if (mustgrow && mem)
+               newvalue *= 2.0f;
+       newvalue = bound(0.25f, newvalue, 256.0f);
+       while (newvalue * 1024*1024 < minsize)
+               newvalue *= 2.0f;
+
+       // clamp the cvar to valid range
+       newvalue = bound(0.25f, newvalue, 256.0f);
+       if (r_buffermegs[type].value != newvalue)
+               Cvar_SetValueQuick(&r_buffermegs[type], newvalue);
+
+       // calculate size in bytes
+       size = (size_t)(newvalue * 1024*1024);
+       size = bound(131072, size, 256*1024*1024);
+
+       // allocate a new buffer if the size is different (purge old one later)
+       // or if we were told we must grow the buffer
        if (!mem || mem->size != size || mustgrow)
        {
                mem = (r_bufferdata_buffer_t *)Mem_Alloc(r_main_mempool, sizeof(*mem));
@@ -4702,7 +4723,7 @@ void R_BufferData_NewFrame(void)
        {
                if (r_bufferdata_buffer[r_bufferdata_cycle][type])
                {
-                       R_BufferData_Resize(type, false);
+                       R_BufferData_Resize((r_bufferdata_type_t)type, false, 131072);
                        // free all but the head buffer, this is how we recycle obsolete
                        // buffers after they are no longer in use
                        p = &r_bufferdata_buffer[r_bufferdata_cycle][type]->purge;
@@ -4720,12 +4741,11 @@ void R_BufferData_NewFrame(void)
        }
 }
 
-r_meshbuffer_t *R_BufferData_Store(size_t datasize, void *data, r_bufferdata_type_t type, int *returnbufferoffset, qboolean allowfail)
+r_meshbuffer_t *R_BufferData_Store(size_t datasize, void *data, r_bufferdata_type_t type, int *returnbufferoffset)
 {
        r_bufferdata_buffer_t *mem;
        int offset = 0;
        int padsize;
-       float newvalue;
 
        *returnbufferoffset = 0;
 
@@ -4736,16 +4756,13 @@ r_meshbuffer_t *R_BufferData_Store(size_t datasize, void *data, r_bufferdata_typ
        else
                padsize = (datasize + 15) & ~15;
 
-       while (!r_bufferdata_buffer[r_bufferdata_cycle][type] || r_bufferdata_buffer[r_bufferdata_cycle][type]->current + padsize > r_bufferdata_buffer[r_bufferdata_cycle][type]->size)
-       {
-               // emergency - we ran out of space, allocate more memory
-               newvalue = bound(0.25f, r_bufferdatasize[type].value * 2.0f, 256.0f);
-               // if we're already at the limit, just fail (if allowfail is false we might run out of video ram)
-               if (newvalue == r_bufferdatasize[type].value && allowfail)
-                       return NULL;
-               Cvar_SetValueQuick(&r_bufferdatasize[type], newvalue);
-               R_BufferData_Resize(type, true);
-       }
+       // if we ran out of space in this buffer we must allocate a new one
+       if (!r_bufferdata_buffer[r_bufferdata_cycle][type] || r_bufferdata_buffer[r_bufferdata_cycle][type]->current + padsize > r_bufferdata_buffer[r_bufferdata_cycle][type]->size)
+               R_BufferData_Resize(type, true, padsize);
+
+       // if the resize did not give us enough memory, fail
+       if (!r_bufferdata_buffer[r_bufferdata_cycle][type] || r_bufferdata_buffer[r_bufferdata_cycle][type]->current + padsize > r_bufferdata_buffer[r_bufferdata_cycle][type]->size)
+               Sys_Error("R_BufferData_Store: failed to create a new buffer of sufficient size\n");
 
        mem = r_bufferdata_buffer[r_bufferdata_cycle][type];
        offset = mem->current;
@@ -4870,106 +4887,14 @@ qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qbool
        if (r_gpuskeletal && model->num_bones > 0 && model->surfmesh.data_skeletalindex4ub)
        {
                // cache the skeleton so the vertex shader can use it
-               int i;
-               int blends;
-               const skeleton_t *skeleton = ent->skeleton;
-               const frameblend_t *frameblend = ent->frameblend;
-               float *boneposerelative;
-               float m[12];
-               static float bonepose[256][12];
                r_refdef.stats[r_stat_animcache_skeletal_count] += 1;
                r_refdef.stats[r_stat_animcache_skeletal_bones] += model->num_bones;
                r_refdef.stats[r_stat_animcache_skeletal_maxbones] = max(r_refdef.stats[r_stat_animcache_skeletal_maxbones], model->num_bones);
                ent->animcache_skeletaltransform3x4 = (float *)R_FrameData_Alloc(sizeof(float[3][4]) * model->num_bones);
-               boneposerelative = ent->animcache_skeletaltransform3x4;
-               if (skeleton && !skeleton->relativetransforms)
-                       skeleton = NULL;
-               // resolve hierarchy and make relative transforms (deforms) which the shader wants
-               if (skeleton)
-               {
-                       for (i = 0;i < model->num_bones;i++)
-                       {
-                               Matrix4x4_ToArray12FloatD3D(&skeleton->relativetransforms[i], m);
-                               if (model->data_bones[i].parent >= 0)
-                                       R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
-                               else
-                                       memcpy(bonepose[i], m, sizeof(m));
-
-                               // create a relative deformation matrix to describe displacement
-                               // from the base mesh, which is used by the actual weighting
-                               R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative + i * 12);
-                       }
-               }
-               else
-               {
-                       for (i = 0;i < model->num_bones;i++)
-                       {
-                               const short * RESTRICT pose7s = model->data_poses7s + 7 * (frameblend[0].subframe * model->num_bones + i);
-                               float lerp = frameblend[0].lerp,
-                                       tx = pose7s[0], ty = pose7s[1], tz = pose7s[2],
-                                       rx = pose7s[3] * lerp,
-                                       ry = pose7s[4] * lerp,
-                                       rz = pose7s[5] * lerp,
-                                       rw = pose7s[6] * lerp,
-                                       dx = tx*rw + ty*rz - tz*ry,
-                                       dy = -tx*rz + ty*rw + tz*rx,
-                                       dz = tx*ry - ty*rx + tz*rw,
-                                       dw = -tx*rx - ty*ry - tz*rz,
-                                       scale, sx, sy, sz, sw;
-                               for (blends = 1;blends < MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
-                               {
-                                       const short * RESTRICT pose7s = model->data_poses7s + 7 * (frameblend[blends].subframe * model->num_bones + i);
-                                       float lerp = frameblend[blends].lerp,
-                                               tx = pose7s[0], ty = pose7s[1], tz = pose7s[2],
-                                               qx = pose7s[3], qy = pose7s[4], qz = pose7s[5], qw = pose7s[6];
-                                       if(rx*qx + ry*qy + rz*qz + rw*qw < 0) lerp = -lerp;
-                                       qx *= lerp;
-                                       qy *= lerp;
-                                       qz *= lerp;
-                                       qw *= lerp;
-                                       rx += qx;
-                                       ry += qy;
-                                       rz += qz;
-                                       rw += qw;
-                                       dx += tx*qw + ty*qz - tz*qy;
-                                       dy += -tx*qz + ty*qw + tz*qx;
-                                       dz += tx*qy - ty*qx + tz*qw;
-                                       dw += -tx*qx - ty*qy - tz*qz;
-                               }
-                               scale = 1.0f / (rx*rx + ry*ry + rz*rz + rw*rw);
-                               sx = rx * scale;
-                               sy = ry * scale;
-                               sz = rz * scale;
-                               sw = rw * scale;
-                               m[0] = sw*rw + sx*rx - sy*ry - sz*rz;
-                               m[1] = 2*(sx*ry - sw*rz);
-                               m[2] = 2*(sx*rz + sw*ry);
-                               m[3] = model->num_posescale*(dx*sw - dy*sz + dz*sy - dw*sx);
-                               m[4] = 2*(sx*ry + sw*rz);
-                               m[5] = sw*rw + sy*ry - sx*rx - sz*rz;
-                               m[6] = 2*(sy*rz - sw*rx);
-                               m[7] = model->num_posescale*(dx*sz + dy*sw - dz*sx - dw*sy);
-                               m[8] = 2*(sx*rz - sw*ry);
-                               m[9] = 2*(sy*rz + sw*rx);
-                               m[10] = sw*rw + sz*rz - sx*rx - sy*ry;
-                               m[11] = model->num_posescale*(dy*sx + dz*sw - dx*sy - dw*sz);
-                               if (i == r_skeletal_debugbone.integer)
-                                       m[r_skeletal_debugbonecomponent.integer % 12] += r_skeletal_debugbonevalue.value;
-                               m[3] *= r_skeletal_debugtranslatex.value;
-                               m[7] *= r_skeletal_debugtranslatey.value;
-                               m[11] *= r_skeletal_debugtranslatez.value;
-                               if (model->data_bones[i].parent >= 0)
-                                       R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
-                               else
-                                       memcpy(bonepose[i], m, sizeof(m));
-                               // create a relative deformation matrix to describe displacement
-                               // from the base mesh, which is used by the actual weighting
-                               R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative + i * 12);
-                       }
-               }
+               Mod_Skeletal_BuildTransforms(model, ent->frameblend, ent->skeleton, NULL, ent->animcache_skeletaltransform3x4); 
                // note: this can fail if the buffer is at the grow limit
                ent->animcache_skeletaltransform3x4size = sizeof(float[3][4]) * model->num_bones;
-               ent->animcache_skeletaltransform3x4buffer = R_BufferData_Store(ent->animcache_skeletaltransform3x4size, ent->animcache_skeletaltransform3x4, R_BUFFERDATA_UNIFORM, &ent->animcache_skeletaltransform3x4offset, true);
+               ent->animcache_skeletaltransform3x4buffer = R_BufferData_Store(ent->animcache_skeletaltransform3x4size, ent->animcache_skeletaltransform3x4, R_BUFFERDATA_UNIFORM, &ent->animcache_skeletaltransform3x4offset);
        }
        else if (ent->animcache_vertex3f)
        {
@@ -5873,10 +5798,10 @@ static void R_Water_StartFrame(void)
        }
        else
        {
-               for (texturewidth   = 1;texturewidth   < waterwidth ;texturewidth   *= 2);
-               for (textureheight  = 1;textureheight  < waterheight;textureheight  *= 2);
-               for (camerawidth    = 1;camerawidth   <= waterwidth; camerawidth    *= 2); camerawidth  /= 2;
-               for (cameraheight   = 1;cameraheight  <= waterheight;cameraheight   *= 2); cameraheight /= 2;
+               for (texturewidth   = 1;texturewidth     <  waterwidth ;texturewidth   *= 2);
+               for (textureheight  = 1;textureheight    <  waterheight;textureheight  *= 2);
+               for (camerawidth    = 1;camerawidth  * 2 <= waterwidth ;camerawidth    *= 2);
+               for (cameraheight   = 1;cameraheight * 2 <= waterheight;cameraheight   *= 2);
        }
 
        // allocate textures as needed
@@ -7201,8 +7126,6 @@ void R_RenderView(void)
                R_SortEntities();
 
        R_AnimCache_ClearCache();
-       R_FrameData_NewFrame();
-       R_BufferData_NewFrame();
 
        /* adjust for stereo display */
        if(R_Stereo_Active())
@@ -9425,12 +9348,12 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                        rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
                        }
                        // upload buffer data for the copytriangles batch
-                       if (vid.forcevbo || (r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object))
+                       if ((r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
                        {
                                if (rsurface.batchelement3s)
-                                       rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset, !vid.forcevbo);
+                                       rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
                                else if (rsurface.batchelement3i)
-                                       rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset, !vid.forcevbo);
+                                       rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
                        }
                }
                else
@@ -10200,35 +10123,35 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
        }
 
        // upload buffer data for the dynamic batch
-       if (vid.forcevbo || (r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object))
+       if ((r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo)
        {
                if (rsurface.batchvertexmesh)
-                       rsurface.batchvertexmesh_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(r_vertexmesh_t), rsurface.batchvertexmesh, R_BUFFERDATA_VERTEX, &rsurface.batchvertexmesh_bufferoffset, !vid.forcevbo);
+                       rsurface.batchvertexmesh_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(r_vertexmesh_t), rsurface.batchvertexmesh, R_BUFFERDATA_VERTEX, &rsurface.batchvertexmesh_bufferoffset);
                else
                {
                        if (rsurface.batchvertex3f)
-                               rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset, !vid.forcevbo);
+                               rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset);
                        if (rsurface.batchsvector3f)
-                               rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset, !vid.forcevbo);
+                               rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset);
                        if (rsurface.batchtvector3f)
-                               rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset, !vid.forcevbo);
+                               rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
                        if (rsurface.batchnormal3f)
-                               rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset, !vid.forcevbo);
-                       if (rsurface.batchlightmapcolor4f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
-                               rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset, !vid.forcevbo);
-                       if (rsurface.batchtexcoordtexture2f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
-                               rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset, !vid.forcevbo);
-                       if (rsurface.batchtexcoordlightmap2f && r_batch_dynamicbuffer.integer && vid.support.arb_vertex_buffer_object)
-                               rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset, !vid.forcevbo);
+                               rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
+                       if (rsurface.batchlightmapcolor4f)
+                               rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
+                       if (rsurface.batchtexcoordtexture2f)
+                               rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
+                       if (rsurface.batchtexcoordlightmap2f)
+                               rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
                        if (rsurface.batchskeletalindex4ub)
-                               rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset, !vid.forcevbo);
+                               rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);
                        if (rsurface.batchskeletalweight4ub)
-                               rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset, !vid.forcevbo);
+                               rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset);
                }
                if (rsurface.batchelement3s)
-                       rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset, !vid.forcevbo);
+                       rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
                else if (rsurface.batchelement3i)
-                       rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset, !vid.forcevbo);
+                       rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
        }
 }