vbo_exec_array.c revision 9881bf6e69b52efc1eb57a4027d9a8817ef8cbcb
14b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis/************************************************************************** 24b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * 34b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 44b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * Copyright 2009 VMware, Inc. 54b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * All Rights Reserved. 64b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * 74b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * Permission is hereby granted, free of charge, to any person obtaining a 84b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * copy of this software and associated documentation files (the 94b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * "Software"), to deal in the Software without restriction, including 104b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * without limitation the rights to use, copy, modify, merge, publish, 114b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * distribute, sub license, and/or sell copies of the Software, and to 124b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * permit persons to whom the Software is furnished to do so, subject to 134b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis * the following conditions: 140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * 150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * The above copyright notice and this permission notice (including the 160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * next paragraph) shall be included in all copies or substantial portions 17eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * of the Software. 1805a07605322dfef2b017781042043a261c5a89cdSebastian Redl * 19914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 200a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 214ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2628019772db70d4547be05a042eb950bc910f134fDouglas Gregor * 270853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis **************************************************************************/ 28a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 29cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include "main/glheader.h" 3003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "main/context.h" 31788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor#include "main/state.h" 320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "main/api_validate.h" 33f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar#include "main/varray.h" 34f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar#include "main/bufferobj.h" 354db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "main/enums.h" 36cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include "main/macros.h" 374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "main/transformfeedback.h" 384db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 394db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "vbo_context.h" 404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/** 43521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar * All vertex buffers should be in an unmapped state when we're about 441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor * to draw. This debug function checks that. 45521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar */ 46521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarstatic void 47521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarcheck_buffers_are_unmapped(const struct gl_client_array **inputs) 48521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar{ 49521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#ifdef DEBUG 50521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar GLuint i; 51521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 52521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar for (i = 0; i < VERT_ATTRIB_MAX; i++) { 53521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar if (inputs[i]) { 540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis struct gl_buffer_object *obj = inputs[i]->BufferObj; 55f96b524306ccfa623235d375deee79637bd38f29Steve Naroff assert(!_mesa_bufferobj_mapped(obj)); 5644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor (void) obj; 5748601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor } 5848601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor } 5948601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor#endif 6048601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor} 6148601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor 6248601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor 6348601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor/** 6448601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor * A debug function that may be called from other parts of Mesa as 653c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl * needed during debugging. 660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis */ 670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisvoid 68788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregorvbo_check_buffers_are_unmapped(struct gl_context *ctx) 69788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor{ 70788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor struct vbo_context *vbo = vbo_context(ctx); 71bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor struct vbo_exec_context *exec = &vbo->exec; 72788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor /* check the current vertex arrays */ 7328019772db70d4547be05a042eb950bc910f134fDouglas Gregor check_buffers_are_unmapped(exec->array.inputs); 74405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor /* check the current glBegin/glVertex/glEnd-style VBO */ 75405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj)); 760853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 80389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis/** 81389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis * Compute min and max elements by scanning the index buffer for 82389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis * glDraw[Range]Elements() calls. 83914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor * If primitive restart is enabled, we need to ignore restart 84914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor * indexes when computing min/max. 85914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor */ 86914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregorstatic void 87914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregorvbo_get_minmax_index(struct gl_context *ctx, 88914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor const struct _mesa_prim *prim, 89914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor const struct _mesa_index_buffer *ib, 90914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor GLuint *min_index, GLuint *max_index, 91807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar const GLuint count) 92807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar{ 93807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar const GLboolean restart = ctx->Array.PrimitiveRestart; 94914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor const GLuint restartIndex = ctx->Array.RestartIndex; 951aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor const int index_size = vbo_sizeof_ib_type(ib->type); 961aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor const char *indices; 971aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor GLuint i; 981aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor 991aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor indices = (char *) ib->ptr + prim->start * index_size; 1001aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor if (_mesa_is_bufferobj(ib->obj)) { 1011aa27307c462baaa9e5fda14ff6797dd39fe8b84Douglas Gregor GLsizeiptr size = MIN2(count * index_size, ib->obj->Size); 1027d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size, 1037d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor GL_MAP_READ_BIT, ib->obj); 1047d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor } 1057d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor 106c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar switch (ib->type) { 107abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor case GL_UNSIGNED_INT: { 108abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor const GLuint *ui_indices = (const GLuint *)indices; 109e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor GLuint max_ui = 0; 110df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor GLuint min_ui = ~0U; 111c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar if (restart) { 112c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar for (i = 0; i < count; i++) { 113df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (ui_indices[i] != restartIndex) { 114df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 115df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 116213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 117213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 11815727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis } 11915727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis else { 12015727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis for (i = 0; i < count; i++) { 121213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 122f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 123f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 124f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 125f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar *min_index = min_ui; 126f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar *max_index = max_ui; 127f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar break; 128f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 129f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar case GL_UNSIGNED_SHORT: { 130f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar const GLushort *us_indices = (const GLushort *)indices; 13189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor GLuint max_us = 0; 13289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor GLuint min_us = ~0U; 13389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (restart) { 13489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor for (i = 0; i < count; i++) { 13589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (us_indices[i] != restartIndex) { 13689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (us_indices[i] > max_us) max_us = us_indices[i]; 13789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (us_indices[i] < min_us) min_us = us_indices[i]; 13889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 13968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar } 14068d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar } 14168d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar else { 142f96b524306ccfa623235d375deee79637bd38f29Steve Naroff for (i = 0; i < count; i++) { 143f96b524306ccfa623235d375deee79637bd38f29Steve Naroff if (us_indices[i] > max_us) max_us = us_indices[i]; 144f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (us_indices[i] < min_us) min_us = us_indices[i]; 145a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 146a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 147405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor *min_index = min_us; 148a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor *max_index = max_us; 1494cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor break; 1504cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } 1514cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor case GL_UNSIGNED_BYTE: { 1524cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor const GLubyte *ub_indices = (const GLubyte *)indices; 1534cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor GLuint max_ub = 0; 1544cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor GLuint min_ub = ~0U; 1554cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if (restart) { 156313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (i = 0; i < count; i++) { 157313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor if (ub_indices[i] != restartIndex) { 158313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 159bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 160788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 161788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 162788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 163788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor else { 164788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (i = 0; i < count; i++) { 165788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 166788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 167788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 168788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 169bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor *min_index = min_ub; 170bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor *max_index = max_ub; 171bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor break; 172bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor } 173bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor default: 174bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor assert(0); 175bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor break; 176bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor } 177bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 178175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (_mesa_is_bufferobj(ib->obj)) { 179eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor ctx->Driver.UnmapBuffer(ctx, ib->obj); 180eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 181eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor} 182eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 183eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/** 184eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor * Compute min and max elements for nr_prims 185eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor */ 186eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorvoid 187eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorvbo_get_minmax_indices(struct gl_context *ctx, 188eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor const struct _mesa_prim *prims, 189eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor const struct _mesa_index_buffer *ib, 190175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor GLuint *min_index, 191385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor GLuint *max_index, 192175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor GLuint nr_prims) 193175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor{ 194175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor GLuint tmp_min, tmp_max; 195175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor GLuint i; 196175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor GLuint count; 197f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 198f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor *min_index = ~0; 199f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor *max_index = 0; 200f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 201f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (i = 0; i < nr_prims; i++) { 202f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const struct _mesa_prim *start_prim; 203175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 204175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor start_prim = &prims[i]; 205175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor count = start_prim->count; 206cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor /* Do combination if possible to reduce map/unmap count */ 207cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor while ((i + 1 < nr_prims) && 208cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor (prims[i].start + prims[i].count == prims[i+1].start)) { 209cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor count += prims[i+1].count; 210cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor i++; 211cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 212cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count); 213cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor *min_index = MIN2(*min_index, tmp_min); 21428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor *max_index = MAX2(*max_index, tmp_max); 21528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor } 21628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor} 21728233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 218c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 219671947b18dba342f9aba022ee992babef325a833Douglas Gregor/** 220671947b18dba342f9aba022ee992babef325a833Douglas Gregor * Check that element 'j' of the array has reasonable data. 221671947b18dba342f9aba022ee992babef325a833Douglas Gregor * Map VBO if needed. 222671947b18dba342f9aba022ee992babef325a833Douglas Gregor * For debugging purposes; not normally used. 223671947b18dba342f9aba022ee992babef325a833Douglas Gregor */ 224c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregorstatic void 225c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregorcheck_array_data(struct gl_context *ctx, struct gl_client_array *array, 226c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor GLuint attrib, GLuint j) 227c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor{ 228c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (array->Enabled) { 229c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor const void *data = array->Ptr; 230c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (_mesa_is_bufferobj(array->BufferObj)) { 231c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (!array->BufferObj->Pointer) { 232c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor /* need to map now */ 233c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor array->BufferObj->Pointer = 234c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size, 235c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor GL_MAP_READ_BIT, array->BufferObj); 236c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 237c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor data = ADD_POINTERS(data, array->BufferObj->Pointer); 238c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 239c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor switch (array->Type) { 2403c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl case GL_FLOAT: 241eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor { 2428538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j); 243eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor GLint k; 24489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor for (k = 0; k < array->Size; k++) { 24589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (IS_INF_OR_NAN(f[k]) || 24689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor f[k] >= 1.0e20 || f[k] <= -1.0e10) { 24789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor printf("Bad array data:\n"); 24887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor printf(" Element[%u].%u = %f\n", j, k, f[k]); 24987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor printf(" Array %u at %p\n", attrib, (void* ) array); 25087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor printf(" Type 0x%x, Size %d, Stride %d\n", 251e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor array->Type, array->Size, array->Stride); 2520b53cf834346d78985aaa9e7300445a39c245614Douglas Gregor printf(" Address/offset %p in Buffer Object %u\n", 253e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor array->Ptr, array->BufferObj->Name); 254e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor f[k] = 1.0; /* XXX replace the bad value! */ 25587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 25687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /*assert(!IS_INF_OR_NAN(f[k]));*/ 25787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 25887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 25987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 26087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor default: 26187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ; 26287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 26387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 26487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 26587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 26687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 26787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor/** 26887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * Unmap the buffer object referenced by given array, if mapped. 26987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor */ 27087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorstatic void 27187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorunmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array) 27287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor{ 27387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (array->Enabled && 27487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor _mesa_is_bufferobj(array->BufferObj) && 27587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor _mesa_bufferobj_mapped(array->BufferObj)) { 27687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor ctx->Driver.UnmapBuffer(ctx, array->BufferObj); 27787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor } 27887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} 2791827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor 28058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 28158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor/** 28258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor * Examine the array's data for NaNs, etc. 2831827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor * For debug purposes; not normally used. 2841827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor */ 285f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregorstatic void 286f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregorcheck_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType, 287f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor const void *elements, GLint basevertex) 288f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor{ 289f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 290f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor const void *elemMap; 291f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor GLint i, k; 292f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 29387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) { 29487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor elemMap = ctx->Driver.MapBufferRange(ctx, 0, 295f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor ctx->Array.ArrayObj->ElementArrayBufferObj->Size, 296f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor GL_MAP_READ_BIT, 297f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor ctx->Array.ArrayObj->ElementArrayBufferObj); 298f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor elements = ADD_POINTERS(elements, elemMap); 299f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 300f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 30148601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor for (i = 0; i < count; i++) { 30248601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor GLuint j; 30348601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor 30448601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor /* j = element[i] */ 30548601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor switch (elemType) { 30648601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor case GL_UNSIGNED_BYTE: 30787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor j = ((const GLubyte *) elements)[i]; 308218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor break; 30948601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor case GL_UNSIGNED_SHORT: 31048601b32321496b07a18fb6631f8563275d8c5fbDouglas Gregor j = ((const GLushort *) elements)[i]; 311218937c13ef5b0625a70aad41ca7a92da9278bd2Douglas Gregor break; 31287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor case GL_UNSIGNED_INT: 31387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor j = ((const GLuint *) elements)[i]; 31487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor break; 315f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor default: 316f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor assert(0); 317f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor } 318f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor 3199b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor /* check element j of each enabled array */ 3209b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { 321727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j); 3229b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 3239b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 3249b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 325727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) { 3269b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); 3279b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 328727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor 3299b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { 3309b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]); 3319b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor } 332ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar} 3339b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 3349b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor 3359b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor/** 3369b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor * Check array data, looking for NaNs, etc. 337ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar */ 338ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarstatic void 339ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarcheck_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) 340ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar{ 341c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor /* TO DO */ 342c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor} 34387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 34487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 34587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor/** 34687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * Print info/data for glDrawArrays(), for debugging. 34787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor */ 34831b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbarstatic void 34931b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbarprint_draw_arrays(struct gl_context *ctx, 350bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor GLenum mode, GLint start, GLsizei count) 3513687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor{ 3528b96253907c47141af0b7b2a44a368748d006a87Douglas Gregor struct vbo_context *vbo = vbo_context(ctx); 353abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor struct vbo_exec_context *exec = &vbo->exec; 354754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 355175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor int i; 356f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 357df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", 358df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor mode, start, count); 359175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 360df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor for (i = 0; i < 32; i++) { 3612283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; 362df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor GLuint bufName = bufObj->Name; 363df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor GLint stride = exec->array.inputs[i]->Stride; 364eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor printf("attr %2d: size %d stride %d enabled %d " 36589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor "ptr %p Bufobj %u\n", 36689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor i, 3670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis exec->array.inputs[i]->Size, 368bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor stride, 369bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor /*exec->array.inputs[i]->Enabled,*/ 370bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled, 371bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor exec->array.inputs[i]->Ptr, 372bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor bufName); 373bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 374bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor if (bufName) { 375bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, 376bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor GL_MAP_READ_BIT, bufObj); 377bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; 378bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor float *f = (float *) (p + offset); 379bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor int *k = (int *) f; 380bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor int i; 381bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor int n = (count * stride) / 4; 382bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor if (n > 32) 383bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor n = 32; 384bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor printf(" Data at offset %d:\n", offset); 385bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor for (i = 0; i < n; i++) { 3860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); 3870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 388c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar ctx->Driver.UnmapBuffer(ctx, bufObj); 389c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar } 390ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 391ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar} 392ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 3933687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 3943687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor/** 3953687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor * Set the vbo->exec->inputs[] pointers to point to the enabled 396405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor * vertex arrays. This depends on the current vertex program/shader 397405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor * being executed because of whether or not generic vertex arrays 3980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * alias the conventional vertex arrays. 3990853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * For arrays that aren't enabled, we set the input[attrib] pointer 4000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * to point at a zero-stride current value "array". 4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump */ 4020853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisstatic void 4030853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisrecalculate_input_bindings(struct gl_context *ctx) 4040853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis{ 405914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor struct vbo_context *vbo = vbo_context(ctx); 406914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor struct vbo_exec_context *exec = &vbo->exec; 407914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib; 408914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor const struct gl_client_array **inputs = &exec->array.inputs[0]; 409914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor GLbitfield64 const_inputs = 0x0; 410914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor GLuint i; 411405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor 412405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor switch (get_program_mode(ctx)) { 413f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar case VP_NONE: 414389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /* When no vertex program is active (or the vertex program is generated 415389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis * from fixed-function state). We put the material values into the 41677accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff * generic slots. This is the only situation where material values 4173c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl * are available as per-vertex attributes. 418b85bca2676b433ae555db09de4dd2823ff13b856Zhongxing Xu */ 419313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 420313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 421313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 422313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor else { 423313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 424313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor const_inputs |= VERT_BIT(i); 425313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor } 4267d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor } 427f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 42815727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis for (i = 0; i < MAT_ATTRIB_MAX; i++) { 42915727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis inputs[VERT_ATTRIB_GENERIC(i)] = 43015727ddb11405c45372150b5bfb07dbfa4c9960bArgyrios Kyrtzidis &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i]; 431eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor const_inputs |= VERT_BIT_GENERIC(i); 432eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 433eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 434eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor /* Could use just about anything, just to fill in the empty 435f96b524306ccfa623235d375deee79637bd38f29Steve Naroff * slots: 436f96b524306ccfa623235d375deee79637bd38f29Steve Naroff */ 437f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { 438213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 439213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor const_inputs |= VERT_BIT_GENERIC(i); 440213f18b3d654de7d1c7cf4a329ea9d3db1c50b6aDouglas Gregor } 441eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor break; 442eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 443eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor case VP_NV: 444f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar /* NV_vertex_program - attribute arrays alias and override 445eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * conventional, legacy arrays. No materials, and the generic 446eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * slots are vacant. 447eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor */ 448f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 449eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (i < VERT_ATTRIB_GENERIC_MAX 450eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor && vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) 451f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar inputs[i] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 452eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor else if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 453eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 454eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor else { 455eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 456eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor const_inputs |= VERT_BIT_FF(i); 457eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 458eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 459eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 460eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor /* Could use just about anything, just to fill in the empty 461eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * slots: 462eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor */ 463eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 464eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 465eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor const_inputs |= VERT_BIT_GENERIC(i); 466eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 467eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor break; 468eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 469eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor case VP_ARB: 470eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0] 471eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * attribute array aliases and overrides the legacy position array. 472eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * 473eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * Otherwise, legacy attributes available in the legacy slots, 4748538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl * generic attributes in the generic slots and materials are not 475eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor * available as per-vertex attributes. 476f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar */ 477f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) 4789b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; 4799b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) 4809b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; 4819b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor else { 4829b7db6200d366e4964d63ae1f33c7b9d7b9831cbDouglas Gregor inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; 48389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor const_inputs |= VERT_BIT_POS; 48489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 48589d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 48689d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { 48789d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 48889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 48989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor else { 49089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 49189d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor const_inputs |= VERT_BIT_FF(i); 49289d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 49389d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor } 494788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 495788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { 496788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) 497788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 498788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor else { 499788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 500a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const_inputs |= VERT_BIT_GENERIC(i); 501405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor } 502405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor } 503405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor 504405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; 505405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor break; 506405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor } 507405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor 508405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) ); 509405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor ctx->NewDriverState |= ctx->DriverFlags.NewArray; 510405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor} 511405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor 512a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 513a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/** 51487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * Examine the enabled vertex arrays to set the exec->array.inputs[] values. 51587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * These will point to the arrays to actually use for drawing. Some will 51687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * be user-provided arrays, other will be zero-stride const-valued arrays. 51787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state 51887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor * validation must be done after this call. 51987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor */ 52087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvoid 52187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorvbo_bind_arrays(struct gl_context *ctx) 52287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor{ 52387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor struct vbo_context *vbo = vbo_context(ctx); 52487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor struct vbo_exec_context *exec = &vbo->exec; 52587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 52687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor vbo_draw_method(vbo, DRAW_ARRAYS); 52787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 528389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis if (exec->array.recalculate_inputs) { 529389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis recalculate_input_bindings(ctx); 53075dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner 531389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /* Again... because we may have changed the bitmask of per-vertex varying 532df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor * attributes. If we regenerate the fixed-function vertex program now 533df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor * we may be able to prune down the number of vertex attributes which we 534df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor * need in the shader. 535df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor */ 536df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (ctx->NewState) { 537df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor _mesa_update_state(ctx); 5384db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5394db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 5404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor exec->array.recalculate_inputs = GL_FALSE; 5414db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 5423c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl} 5430853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 5443c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl 5450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/** 5465262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar * Handle a draw case that potentially has primitive restart enabled. 5475262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar * 54831b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar * If primitive restart is enabled, and PrimitiveRestartInSoftware is 5493c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl * set, then vbo_sw_primitive_restart is used to handle the primitive 5503c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl * restart case in software. 55128019772db70d4547be05a042eb950bc910f134fDouglas Gregor */ 552389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidisstatic void 5535cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenekvbo_handle_primitive_restart(struct gl_context *ctx, 5544db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor const struct _mesa_prim *prim, 555a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor GLuint nr_prims, 556a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const struct _mesa_index_buffer *ib, 557521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar GLboolean index_bounds_valid, 5584cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor GLuint min_index, 5594cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor GLuint max_index) 5604cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor{ 5614cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor struct vbo_context *vbo = vbo_context(ctx); 5624cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor 5634cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor if ((ib != NULL) && 5644cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor ctx->Const.PrimitiveRestartInSoftware && 5654cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor ctx->Array.PrimitiveRestart) { 5664cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor /* Handle primitive restart in software */ 5674cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); 5684cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor } else { 5694cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor /* Call driver directly for draw_prims */ 5704cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor vbo->draw_prims(ctx, prim, nr_prims, ib, 571521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar index_bounds_valid, min_index, max_index, NULL); 572521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 573521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 574521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 575f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar 576521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar/** 5775262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar * Helper function called by the other DrawArrays() functions below. 5785262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar * This is where we handle primitive restart for drawing non-indexed 579521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar * arrays. If primitive restart is enabled, it typically means 580521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar * splitting one DrawArrays() into two. 581521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar */ 582f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbarstatic void 58328019772db70d4547be05a042eb950bc910f134fDouglas Gregorvbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, 584a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor GLsizei count, GLuint numInstances, GLuint baseInstance) 58544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor{ 586df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor struct vbo_context *vbo = vbo_context(ctx); 58787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor struct vbo_exec_context *exec = &vbo->exec; 58887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor struct _mesa_prim prim[2]; 589521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 5907b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar vbo_bind_arrays(ctx); 5917b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 5927b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar /* init most fields to zero */ 5937b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar memset(prim, 0, sizeof(prim)); 5947b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar prim[0].begin = 1; 5957b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar prim[0].end = 1; 5967b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar prim[0].mode = mode; 5975262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar prim[0].num_instances = numInstances; 5985262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar prim[0].base_instance = baseInstance; 5997b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 600869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar /* Implement the primitive restart index */ 6017b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) { 6027b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar GLuint primCount = 0; 6037b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 6047b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (ctx->Array.RestartIndex == start) { 6057b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar /* special case: RestartIndex at beginning */ 60628019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (count > 1) { 607869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar prim[0].start = start + 1; 6087b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar prim[0].count = count - 1; 609e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor primCount = 1; 6104db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 611a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 612df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor else if (ctx->Array.RestartIndex == start + count - 1) { 61387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor /* special case: RestartIndex at end */ 61499ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor if (count > 1) { 61599ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor prim[0].start = start; 61699ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor prim[0].count = count - 1; 617abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor primCount = 1; 618abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 619abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 620abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor else { 621abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor /* general case: RestartIndex in middle, split into two prims */ 622abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor prim[0].start = start; 623abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor prim[0].count = ctx->Array.RestartIndex - start; 624abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 6251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor prim[1] = prim[0]; 6261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor prim[1].start = ctx->Array.RestartIndex + 1; 6271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor prim[1].count = count - prim[1].start; 6281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 629cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor primCount = 2; 630cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor } 631cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 632cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor if (primCount > 0) { 633cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor /* draw one or two prims */ 634cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor check_buffers_are_unmapped(exec->array.inputs); 635cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor vbo->draw_prims(ctx, prim, primCount, NULL, 636cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor GL_TRUE, start, start + count - 1, NULL); 637cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor } 638cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor } 639cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor else { 6401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor /* no prim restart */ 6412283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor prim[0].start = start; 6422283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor prim[0].count = count; 6431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 6441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor check_buffers_are_unmapped(exec->array.inputs); 645cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor vbo->draw_prims(ctx, prim, 1, NULL, 6461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor GL_TRUE, start, start + count - 1, 6471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor NULL); 6481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 6492283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor 6502283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 6517ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor _mesa_flush(ctx); 6527ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor } 6537ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 6547ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 6557ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 6560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 6570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/** 6580853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis * Called from glDrawArrays when in immediate mode (not display list mode). 6590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis */ 6600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisstatic void GLAPIENTRY 661vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) 662{ 663 GET_CURRENT_CONTEXT(ctx); 664 665 if (MESA_VERBOSE & VERBOSE_DRAW) 666 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", 667 _mesa_lookup_enum_by_nr(mode), start, count); 668 669 FLUSH_CURRENT(ctx, 0); 670 671 if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) 672 return; 673 674 if (0) 675 check_draw_arrays_data(ctx, start, count); 676 677 vbo_draw_arrays(ctx, mode, start, count, 1, 0); 678 679 if (0) 680 print_draw_arrays(ctx, mode, start, count); 681} 682 683 684/** 685 * Called from glDrawArraysInstanced when in immediate mode (not 686 * display list mode). 687 */ 688static void GLAPIENTRY 689vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, 690 GLsizei numInstances) 691{ 692 GET_CURRENT_CONTEXT(ctx); 693 694 if (MESA_VERBOSE & VERBOSE_DRAW) 695 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n", 696 _mesa_lookup_enum_by_nr(mode), start, count, numInstances); 697 698 FLUSH_CURRENT(ctx, 0); 699 700 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances)) 701 return; 702 703 if (0) 704 check_draw_arrays_data(ctx, start, count); 705 706 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0); 707 708 if (0) 709 print_draw_arrays(ctx, mode, start, count); 710} 711 712 713/** 714 * Called from glDrawArraysInstancedBaseInstance when in immediate mode. 715 */ 716static void GLAPIENTRY 717vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, 718 GLsizei numInstances, GLuint baseInstance) 719{ 720 GET_CURRENT_CONTEXT(ctx); 721 722 if (MESA_VERBOSE & VERBOSE_DRAW) 723 _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n", 724 _mesa_lookup_enum_by_nr(mode), first, count, 725 numInstances, baseInstance); 726 727 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, 728 numInstances)) 729 return; 730 731 FLUSH_CURRENT(ctx, 0); 732 733 if (!_mesa_valid_to_render(ctx, "glDrawArraysInstancedBaseInstance")) 734 return; 735 736 if (0) 737 check_draw_arrays_data(ctx, first, count); 738 739 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance); 740 741 if (0) 742 print_draw_arrays(ctx, mode, first, count); 743} 744 745 746 747/** 748 * Map GL_ELEMENT_ARRAY_BUFFER and print contents. 749 * For debugging. 750 */ 751#if 0 752static void 753dump_element_buffer(struct gl_context *ctx, GLenum type) 754{ 755 const GLvoid *map = 756 ctx->Driver.MapBufferRange(ctx, 0, 757 ctx->Array.ArrayObj->ElementArrayBufferObj->Size, 758 GL_MAP_READ_BIT, 759 ctx->Array.ArrayObj->ElementArrayBufferObj); 760 switch (type) { 761 case GL_UNSIGNED_BYTE: 762 { 763 const GLubyte *us = (const GLubyte *) map; 764 GLint i; 765 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) { 766 printf("%02x ", us[i]); 767 if (i % 32 == 31) 768 printf("\n"); 769 } 770 printf("\n"); 771 } 772 break; 773 case GL_UNSIGNED_SHORT: 774 { 775 const GLushort *us = (const GLushort *) map; 776 GLint i; 777 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) { 778 printf("%04x ", us[i]); 779 if (i % 16 == 15) 780 printf("\n"); 781 } 782 printf("\n"); 783 } 784 break; 785 case GL_UNSIGNED_INT: 786 { 787 const GLuint *us = (const GLuint *) map; 788 GLint i; 789 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) { 790 printf("%08x ", us[i]); 791 if (i % 8 == 7) 792 printf("\n"); 793 } 794 printf("\n"); 795 } 796 break; 797 default: 798 ; 799 } 800 801 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); 802} 803#endif 804 805 806/** 807 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. 808 * Do the rendering for a glDrawElements or glDrawRangeElements call after 809 * we've validated buffer bounds, etc. 810 */ 811static void 812vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, 813 GLboolean index_bounds_valid, 814 GLuint start, GLuint end, 815 GLsizei count, GLenum type, 816 const GLvoid *indices, 817 GLint basevertex, GLint numInstances, 818 GLuint baseInstance) 819{ 820 struct vbo_context *vbo = vbo_context(ctx); 821 struct vbo_exec_context *exec = &vbo->exec; 822 struct _mesa_index_buffer ib; 823 struct _mesa_prim prim[1]; 824 825 vbo_bind_arrays(ctx); 826 827 ib.count = count; 828 ib.type = type; 829 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 830 ib.ptr = indices; 831 832 prim[0].begin = 1; 833 prim[0].end = 1; 834 prim[0].weak = 0; 835 prim[0].pad = 0; 836 prim[0].mode = mode; 837 prim[0].start = 0; 838 prim[0].count = count; 839 prim[0].indexed = 1; 840 prim[0].basevertex = basevertex; 841 prim[0].num_instances = numInstances; 842 prim[0].base_instance = baseInstance; 843 844 /* Need to give special consideration to rendering a range of 845 * indices starting somewhere above zero. Typically the 846 * application is issuing multiple DrawRangeElements() to draw 847 * successive primitives layed out linearly in the vertex arrays. 848 * Unless the vertex arrays are all in a VBO (or locked as with 849 * CVA), the OpenGL semantics imply that we need to re-read or 850 * re-upload the vertex data on each draw call. 851 * 852 * In the case of hardware tnl, we want to avoid starting the 853 * upload at zero, as it will mean every draw call uploads an 854 * increasing amount of not-used vertex data. Worse - in the 855 * software tnl module, all those vertices might be transformed and 856 * lit but never rendered. 857 * 858 * If we just upload or transform the vertices in start..end, 859 * however, the indices will be incorrect. 860 * 861 * At this level, we don't know exactly what the requirements of 862 * the backend are going to be, though it will likely boil down to 863 * either: 864 * 865 * 1) Do nothing, everything is in a VBO and is processed once 866 * only. 867 * 868 * 2) Adjust the indices and vertex arrays so that start becomes 869 * zero. 870 * 871 * Rather than doing anything here, I'll provide a helper function 872 * for the latter case elsewhere. 873 */ 874 875 check_buffers_are_unmapped(exec->array.inputs); 876 vbo_handle_primitive_restart(ctx, prim, 1, &ib, 877 index_bounds_valid, start, end); 878 879 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 880 _mesa_flush(ctx); 881 } 882} 883 884 885/** 886 * Called by glDrawRangeElementsBaseVertex() in immediate mode. 887 */ 888static void GLAPIENTRY 889vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, 890 GLuint start, GLuint end, 891 GLsizei count, GLenum type, 892 const GLvoid *indices, 893 GLint basevertex) 894{ 895 static GLuint warnCount = 0; 896 GLboolean index_bounds_valid = GL_TRUE; 897 GET_CURRENT_CONTEXT(ctx); 898 899 if (MESA_VERBOSE & VERBOSE_DRAW) 900 _mesa_debug(ctx, 901 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", 902 _mesa_lookup_enum_by_nr(mode), start, end, count, 903 _mesa_lookup_enum_by_nr(type), indices, basevertex); 904 905 FLUSH_CURRENT(ctx, 0); 906 907 if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, 908 type, indices, basevertex )) 909 return; 910 911 if ((int) end + basevertex < 0 || 912 start + basevertex >= ctx->Array.ArrayObj->_MaxElement) { 913 /* The application requested we draw using a range of indices that's 914 * outside the bounds of the current VBO. This is invalid and appears 915 * to give undefined results. The safest thing to do is to simply 916 * ignore the range, in case the application botched their range tracking 917 * but did provide valid indices. Also issue a warning indicating that 918 * the application is broken. 919 */ 920 if (warnCount++ < 10) { 921 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " 922 "basevertex %d, count %d, type 0x%x, indices=%p):\n" 923 "\trange is outside VBO bounds (max=%u); ignoring.\n" 924 "\tThis should be fixed in the application.", 925 start, end, basevertex, count, type, indices, 926 ctx->Array.ArrayObj->_MaxElement - 1); 927 } 928 index_bounds_valid = GL_FALSE; 929 } 930 931 /* NOTE: It's important that 'end' is a reasonable value. 932 * in _tnl_draw_prims(), we use end to determine how many vertices 933 * to transform. If it's too large, we can unnecessarily split prims 934 * or we can read/write out of memory in several different places! 935 */ 936 937 /* Catch/fix some potential user errors */ 938 if (type == GL_UNSIGNED_BYTE) { 939 start = MIN2(start, 0xff); 940 end = MIN2(end, 0xff); 941 } 942 else if (type == GL_UNSIGNED_SHORT) { 943 start = MIN2(start, 0xffff); 944 end = MIN2(end, 0xffff); 945 } 946 947 if (0) { 948 printf("glDraw[Range]Elements{,BaseVertex}" 949 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " 950 "base %d\n", 951 start, end, type, count, 952 ctx->Array.ArrayObj->ElementArrayBufferObj->Name, 953 basevertex); 954 } 955 956 if ((int) start + basevertex < 0 || 957 end + basevertex >= ctx->Array.ArrayObj->_MaxElement) 958 index_bounds_valid = GL_FALSE; 959 960#if 0 961 check_draw_elements_data(ctx, count, type, indices); 962#else 963 (void) check_draw_elements_data; 964#endif 965 966 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, 967 count, type, indices, basevertex, 1, 0); 968} 969 970 971/** 972 * Called by glDrawRangeElements() in immediate mode. 973 */ 974static void GLAPIENTRY 975vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, 976 GLsizei count, GLenum type, const GLvoid *indices) 977{ 978 if (MESA_VERBOSE & VERBOSE_DRAW) { 979 GET_CURRENT_CONTEXT(ctx); 980 _mesa_debug(ctx, 981 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", 982 _mesa_lookup_enum_by_nr(mode), start, end, count, 983 _mesa_lookup_enum_by_nr(type), indices); 984 } 985 986 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 987 indices, 0); 988} 989 990 991/** 992 * Called by glDrawElements() in immediate mode. 993 */ 994static void GLAPIENTRY 995vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, 996 const GLvoid *indices) 997{ 998 GET_CURRENT_CONTEXT(ctx); 999 1000 if (MESA_VERBOSE & VERBOSE_DRAW) 1001 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 1002 _mesa_lookup_enum_by_nr(mode), count, 1003 _mesa_lookup_enum_by_nr(type), indices); 1004 1005 FLUSH_CURRENT(ctx, 0); 1006 1007 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 )) 1008 return; 1009 1010 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1011 count, type, indices, 0, 1, 0); 1012} 1013 1014 1015/** 1016 * Called by glDrawElementsBaseVertex() in immediate mode. 1017 */ 1018static void GLAPIENTRY 1019vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1020 const GLvoid *indices, GLint basevertex) 1021{ 1022 GET_CURRENT_CONTEXT(ctx); 1023 1024 if (MESA_VERBOSE & VERBOSE_DRAW) 1025 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n", 1026 _mesa_lookup_enum_by_nr(mode), count, 1027 _mesa_lookup_enum_by_nr(type), indices, basevertex); 1028 1029 FLUSH_CURRENT(ctx, 0); 1030 1031 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 1032 basevertex )) 1033 return; 1034 1035 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1036 count, type, indices, basevertex, 1, 0); 1037} 1038 1039 1040/** 1041 * Called by glDrawElementsInstanced() in immediate mode. 1042 */ 1043static void GLAPIENTRY 1044vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, 1045 const GLvoid *indices, GLsizei numInstances) 1046{ 1047 GET_CURRENT_CONTEXT(ctx); 1048 1049 if (MESA_VERBOSE & VERBOSE_DRAW) 1050 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n", 1051 _mesa_lookup_enum_by_nr(mode), count, 1052 _mesa_lookup_enum_by_nr(type), indices, numInstances); 1053 1054 FLUSH_CURRENT(ctx, 0); 1055 1056 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1057 numInstances, 0)) 1058 return; 1059 1060 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1061 count, type, indices, 0, numInstances, 0); 1062} 1063 1064 1065/** 1066 * Called by glDrawElementsInstancedBaseVertex() in immediate mode. 1067 */ 1068static void GLAPIENTRY 1069vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, 1070 const GLvoid *indices, GLsizei numInstances, 1071 GLint basevertex) 1072{ 1073 GET_CURRENT_CONTEXT(ctx); 1074 1075 if (MESA_VERBOSE & VERBOSE_DRAW) 1076 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n", 1077 _mesa_lookup_enum_by_nr(mode), count, 1078 _mesa_lookup_enum_by_nr(type), indices, 1079 numInstances, basevertex); 1080 1081 FLUSH_CURRENT(ctx, 0); 1082 1083 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1084 numInstances, basevertex)) 1085 return; 1086 1087 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1088 count, type, indices, basevertex, numInstances, 0); 1089} 1090 1091 1092/** 1093 * Called by glDrawElementsInstancedBaseInstance() in immediate mode. 1094 */ 1095static void GLAPIENTRY 1096vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, 1097 const GLvoid *indices, GLsizei numInstances, 1098 GLuint baseInstance) 1099{ 1100 GET_CURRENT_CONTEXT(ctx); 1101 1102 if (MESA_VERBOSE & VERBOSE_DRAW) 1103 _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n", 1104 _mesa_lookup_enum_by_nr(mode), count, 1105 _mesa_lookup_enum_by_nr(type), indices, 1106 numInstances, baseInstance); 1107 1108 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1109 numInstances, 0)) 1110 return; 1111 1112 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1113 count, type, indices, 0, numInstances, 1114 baseInstance); 1115} 1116 1117 1118/** 1119 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. 1120 */ 1121static void GLAPIENTRY 1122vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, 1123 const GLvoid *indices, GLsizei numInstances, 1124 GLint basevertex, GLuint baseInstance) 1125{ 1126 GET_CURRENT_CONTEXT(ctx); 1127 1128 if (MESA_VERBOSE & VERBOSE_DRAW) 1129 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n", 1130 _mesa_lookup_enum_by_nr(mode), count, 1131 _mesa_lookup_enum_by_nr(type), indices, 1132 numInstances, basevertex, baseInstance); 1133 1134 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1135 numInstances, basevertex)) 1136 return; 1137 1138 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1139 count, type, indices, basevertex, numInstances, 1140 baseInstance); 1141} 1142 1143 1144/** 1145 * Inner support for both _mesa_MultiDrawElements() and 1146 * _mesa_MultiDrawRangeElements(). 1147 * This does the actual rendering after we've checked array indexes, etc. 1148 */ 1149static void 1150vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, 1151 const GLsizei *count, GLenum type, 1152 const GLvoid * const *indices, 1153 GLsizei primcount, 1154 const GLint *basevertex) 1155{ 1156 struct vbo_context *vbo = vbo_context(ctx); 1157 struct vbo_exec_context *exec = &vbo->exec; 1158 struct _mesa_index_buffer ib; 1159 struct _mesa_prim *prim; 1160 unsigned int index_type_size = vbo_sizeof_ib_type(type); 1161 uintptr_t min_index_ptr, max_index_ptr; 1162 GLboolean fallback = GL_FALSE; 1163 int i; 1164 1165 if (primcount == 0) 1166 return; 1167 1168 prim = calloc(1, primcount * sizeof(*prim)); 1169 if (prim == NULL) { 1170 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); 1171 return; 1172 } 1173 1174 vbo_bind_arrays(ctx); 1175 1176 min_index_ptr = (uintptr_t)indices[0]; 1177 max_index_ptr = 0; 1178 for (i = 0; i < primcount; i++) { 1179 min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]); 1180 max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] + 1181 index_type_size * count[i]); 1182 } 1183 1184 /* Check if we can handle this thing as a bunch of index offsets from the 1185 * same index pointer. If we can't, then we have to fall back to doing 1186 * a draw_prims per primitive. 1187 * Check that the difference between each prim's indexes is a multiple of 1188 * the index/element size. 1189 */ 1190 if (index_type_size != 1) { 1191 for (i = 0; i < primcount; i++) { 1192 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) { 1193 fallback = GL_TRUE; 1194 break; 1195 } 1196 } 1197 } 1198 1199 /* If the index buffer isn't in a VBO, then treating the application's 1200 * subranges of the index buffer as one large index buffer may lead to 1201 * us reading unmapped memory. 1202 */ 1203 if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) 1204 fallback = GL_TRUE; 1205 1206 if (!fallback) { 1207 ib.count = (max_index_ptr - min_index_ptr) / index_type_size; 1208 ib.type = type; 1209 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 1210 ib.ptr = (void *)min_index_ptr; 1211 1212 for (i = 0; i < primcount; i++) { 1213 prim[i].begin = (i == 0); 1214 prim[i].end = (i == primcount - 1); 1215 prim[i].weak = 0; 1216 prim[i].pad = 0; 1217 prim[i].mode = mode; 1218 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size; 1219 prim[i].count = count[i]; 1220 prim[i].indexed = 1; 1221 prim[i].num_instances = 1; 1222 prim[i].base_instance = 0; 1223 if (basevertex != NULL) 1224 prim[i].basevertex = basevertex[i]; 1225 else 1226 prim[i].basevertex = 0; 1227 } 1228 1229 check_buffers_are_unmapped(exec->array.inputs); 1230 vbo_handle_primitive_restart(ctx, prim, primcount, &ib, 1231 GL_FALSE, ~0, ~0); 1232 } else { 1233 /* render one prim at a time */ 1234 for (i = 0; i < primcount; i++) { 1235 ib.count = count[i]; 1236 ib.type = type; 1237 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 1238 ib.ptr = indices[i]; 1239 1240 prim[0].begin = 1; 1241 prim[0].end = 1; 1242 prim[0].weak = 0; 1243 prim[0].pad = 0; 1244 prim[0].mode = mode; 1245 prim[0].start = 0; 1246 prim[0].count = count[i]; 1247 prim[0].indexed = 1; 1248 prim[0].num_instances = 1; 1249 prim[0].base_instance = 0; 1250 if (basevertex != NULL) 1251 prim[0].basevertex = basevertex[i]; 1252 else 1253 prim[0].basevertex = 0; 1254 1255 check_buffers_are_unmapped(exec->array.inputs); 1256 vbo_handle_primitive_restart(ctx, prim, 1, &ib, 1257 GL_FALSE, ~0, ~0); 1258 } 1259 } 1260 1261 free(prim); 1262 1263 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1264 _mesa_flush(ctx); 1265 } 1266} 1267 1268 1269static void GLAPIENTRY 1270vbo_exec_MultiDrawElements(GLenum mode, 1271 const GLsizei *count, GLenum type, 1272 const GLvoid **indices, 1273 GLsizei primcount) 1274{ 1275 GET_CURRENT_CONTEXT(ctx); 1276 GLint i; 1277 1278 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1279 1280 for (i = 0; i < primcount; i++) { 1281 if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i], 1282 0)) 1283 return; 1284 } 1285 1286 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1287 NULL); 1288} 1289 1290 1291static void GLAPIENTRY 1292vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, 1293 const GLsizei *count, GLenum type, 1294 const GLvoid * const *indices, 1295 GLsizei primcount, 1296 const GLsizei *basevertex) 1297{ 1298 GET_CURRENT_CONTEXT(ctx); 1299 GLint i; 1300 1301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1302 1303 for (i = 0; i < primcount; i++) { 1304 if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i], 1305 basevertex[i])) 1306 return; 1307 } 1308 1309 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1310 basevertex); 1311} 1312 1313#if FEATURE_EXT_transform_feedback 1314 1315static void 1316vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, 1317 struct gl_transform_feedback_object *obj, 1318 GLuint numInstances) 1319{ 1320 struct vbo_context *vbo = vbo_context(ctx); 1321 struct vbo_exec_context *exec = &vbo->exec; 1322 struct _mesa_prim prim[2]; 1323 1324 vbo_bind_arrays(ctx); 1325 1326 /* init most fields to zero */ 1327 memset(prim, 0, sizeof(prim)); 1328 prim[0].begin = 1; 1329 prim[0].end = 1; 1330 prim[0].mode = mode; 1331 prim[0].num_instances = numInstances; 1332 prim[0].base_instance = 0; 1333 1334 /* Maybe we should do some primitive splitting for primitive restart 1335 * (like in DrawArrays), but we have no way to know how many vertices 1336 * will be rendered. */ 1337 1338 check_buffers_are_unmapped(exec->array.inputs); 1339 vbo->draw_prims(ctx, prim, 1, NULL, 1340 GL_TRUE, 0, 0, obj); 1341 1342 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1343 _mesa_flush(ctx); 1344 } 1345} 1346 1347/** 1348 * Like DrawArrays, but take the count from a transform feedback object. 1349 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 1350 * \param name the transform feedback object 1351 * User still has to setup of the vertex attribute info with 1352 * glVertexPointer, glColorPointer, etc. 1353 * Part of GL_ARB_transform_feedback2. 1354 */ 1355static void GLAPIENTRY 1356vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) 1357{ 1358 GET_CURRENT_CONTEXT(ctx); 1359 struct gl_transform_feedback_object *obj = 1360 _mesa_lookup_transform_feedback_object(ctx, name); 1361 1362 if (MESA_VERBOSE & VERBOSE_DRAW) 1363 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", 1364 _mesa_lookup_enum_by_nr(mode), name); 1365 1366 FLUSH_CURRENT(ctx, 0); 1367 1368 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) { 1369 return; 1370 } 1371 1372 vbo_draw_transform_feedback(ctx, mode, obj, 1); 1373} 1374 1375#endif 1376 1377/** 1378 * Plug in the immediate-mode vertex array drawing commands into the 1379 * givven vbo_exec_context object. 1380 */ 1381void 1382vbo_exec_array_init( struct vbo_exec_context *exec ) 1383{ 1384 exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays; 1385 exec->vtxfmt.DrawElements = vbo_exec_DrawElements; 1386 exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements; 1387 exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements; 1388 exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex; 1389 exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex; 1390 exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex; 1391 exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced; 1392 exec->vtxfmt.DrawArraysInstancedBaseInstance = vbo_exec_DrawArraysInstancedBaseInstance; 1393 exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced; 1394 exec->vtxfmt.DrawElementsInstancedBaseInstance = vbo_exec_DrawElementsInstancedBaseInstance; 1395 exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex; 1396 exec->vtxfmt.DrawElementsInstancedBaseVertexBaseInstance = vbo_exec_DrawElementsInstancedBaseVertexBaseInstance; 1397#if FEATURE_EXT_transform_feedback 1398 exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback; 1399#endif 1400} 1401 1402 1403void 1404vbo_exec_array_destroy( struct vbo_exec_context *exec ) 1405{ 1406 /* nothing to do */ 1407} 1408 1409 1410 1411/** 1412 * The following functions are only used for OpenGL ES 1/2 support. 1413 * And some aren't even supported (yet) in ES 1/2. 1414 */ 1415 1416 1417void GLAPIENTRY 1418_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) 1419{ 1420 vbo_exec_DrawArrays(mode, first, count); 1421} 1422 1423 1424void GLAPIENTRY 1425_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, 1426 const GLvoid *indices) 1427{ 1428 vbo_exec_DrawElements(mode, count, type, indices); 1429} 1430 1431 1432void GLAPIENTRY 1433_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1434 const GLvoid *indices, GLint basevertex) 1435{ 1436 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); 1437} 1438 1439 1440void GLAPIENTRY 1441_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, 1442 GLenum type, const GLvoid *indices) 1443{ 1444 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices); 1445} 1446 1447 1448void GLAPIENTRY 1449_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 1450 GLsizei count, GLenum type, 1451 const GLvoid *indices, GLint basevertex) 1452{ 1453 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 1454 indices, basevertex); 1455} 1456 1457 1458void GLAPIENTRY 1459_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, 1460 const GLvoid **indices, GLsizei primcount) 1461{ 1462 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount); 1463} 1464 1465 1466void GLAPIENTRY 1467_mesa_MultiDrawElementsBaseVertex(GLenum mode, 1468 const GLsizei *count, GLenum type, 1469 const GLvoid **indices, GLsizei primcount, 1470 const GLint *basevertex) 1471{ 1472 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, 1473 primcount, basevertex); 1474} 1475 1476#if FEATURE_EXT_transform_feedback 1477 1478void GLAPIENTRY 1479_mesa_DrawTransformFeedback(GLenum mode, GLuint name) 1480{ 1481 vbo_exec_DrawTransformFeedback(mode, name); 1482} 1483 1484#endif 1485