| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2016 by Mike Erwin. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  |  * GPU vertex buffer | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-09-13 02:41:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 16:54:58 +02:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "GPU_vertex_buffer.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "gpu_context_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "gpu_vertex_format_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-13 02:41:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:51:10 +02:00
										 |  |  | #define KEEP_SINGLE_COPY 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | static uint vbo_memory_usage; | 
					
						
							| 
									
										
										
										
											2017-05-04 21:22:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | static GLenum convert_usage_type_to_gl(GPUUsageType type) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   static const GLenum table[] = { | 
					
						
							|  |  |  |       [GPU_USAGE_STREAM] = GL_STREAM_DRAW, | 
					
						
							|  |  |  |       [GPU_USAGE_STATIC] = GL_STATIC_DRAW, | 
					
						
							|  |  |  |       [GPU_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   return table[type]; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertBuf *verts = MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf"); | 
					
						
							|  |  |  |   GPU_vertbuf_init(verts, usage); | 
					
						
							|  |  |  |   return verts; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *format, GPUUsageType usage) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertBuf *verts = GPU_vertbuf_create(usage); | 
					
						
							|  |  |  |   GPU_vertformat_copy(&verts->format, format); | 
					
						
							|  |  |  |   if (!format->packed) { | 
					
						
							|  |  |  |     VertexFormat_pack(&verts->format); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return verts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* this function might seem redundant, but there is potential for memory savings here... */ | 
					
						
							|  |  |  |   /* TODO: implement those memory savings */ | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_init(GPUVertBuf *verts, GPUUsageType usage) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   memset(verts, 0, sizeof(GPUVertBuf)); | 
					
						
							|  |  |  |   verts->usage = usage; | 
					
						
							|  |  |  |   verts->dirty = true; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, | 
					
						
							|  |  |  |                                      const GPUVertFormat *format, | 
					
						
							|  |  |  |                                      GPUUsageType usage) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPU_vertbuf_init(verts, usage); | 
					
						
							|  |  |  |   GPU_vertformat_copy(&verts->format, format); | 
					
						
							|  |  |  |   if (!format->packed) { | 
					
						
							|  |  |  |     VertexFormat_pack(&verts->format); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 17:27:35 +02:00
										 |  |  | /** Same as discard but does not free. */ | 
					
						
							|  |  |  | void GPU_vertbuf_clear(GPUVertBuf *verts) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (verts->vbo_id) { | 
					
						
							|  |  |  |     GPU_buf_free(verts->vbo_id); | 
					
						
							| 
									
										
										
										
											2019-05-13 17:27:35 +02:00
										 |  |  |     verts->vbo_id = 0; | 
					
						
							| 
									
										
										
										
											2018-02-14 17:59:48 +01:00
										 |  |  | #if VRAM_USAGE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     vbo_memory_usage -= GPU_vertbuf_size_get(verts); | 
					
						
							| 
									
										
										
										
											2016-11-29 00:12:50 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (verts->data) { | 
					
						
							| 
									
										
										
										
											2019-05-13 17:27:35 +02:00
										 |  |  |     MEM_SAFE_FREE(verts->data); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-05-13 17:27:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_vertbuf_discard(GPUVertBuf *verts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GPU_vertbuf_clear(verts); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   MEM_freeN(verts); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-23 23:16:54 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | uint GPU_vertbuf_size_get(const GPUVertBuf *verts) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return vertex_buffer_size(&verts->format, verts->vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /* create a new allocation, discarding any existing data */ | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertFormat *format = &verts->format; | 
					
						
							|  |  |  |   if (!format->packed) { | 
					
						
							|  |  |  |     VertexFormat_pack(format); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* catch any unnecessary use */ | 
					
						
							|  |  |  |   assert(verts->vertex_alloc != v_len || verts->data == NULL); | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* discard previous data if any */ | 
					
						
							|  |  |  |   if (verts->data) { | 
					
						
							|  |  |  |     MEM_freeN(verts->data); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #if VRAM_USAGE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint new_size = vertex_buffer_size(&verts->format, v_len); | 
					
						
							|  |  |  |   vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->dirty = true; | 
					
						
							|  |  |  |   verts->vertex_len = verts->vertex_alloc = v_len; | 
					
						
							|  |  |  |   verts->data = MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), "GPUVertBuf data"); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /* resize buffer keeping existing data */ | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(verts->data != NULL); | 
					
						
							|  |  |  |   assert(verts->vertex_alloc != v_len); | 
					
						
							| 
									
										
										
										
											2016-09-15 21:45:10 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #if VRAM_USAGE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint new_size = vertex_buffer_size(&verts->format, v_len); | 
					
						
							|  |  |  |   vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->dirty = true; | 
					
						
							|  |  |  |   verts->vertex_len = verts->vertex_alloc = v_len; | 
					
						
							|  |  |  |   verts->data = MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-30 18:10:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /* Set vertex count but does not change allocation.
 | 
					
						
							|  |  |  |  * Only this many verts will be uploaded to the GPU and rendered. | 
					
						
							| 
									
										
										
										
											2018-09-24 18:46:51 +02:00
										 |  |  |  * This is useful for streaming data. */ | 
					
						
							| 
									
										
										
										
											2019-01-21 11:28:41 +11:00
										 |  |  | void GPU_vertbuf_data_len_set(GPUVertBuf *verts, uint v_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-30 18:10:08 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(verts->data != NULL); /* only for dynamic data */ | 
					
						
							|  |  |  |   assert(v_len <= verts->vertex_alloc); | 
					
						
							| 
									
										
										
										
											2018-03-30 18:10:08 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 16:13:00 +01:00
										 |  |  | #if VRAM_USAGE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint new_size = vertex_buffer_size(&verts->format, v_len); | 
					
						
							|  |  |  |   vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); | 
					
						
							| 
									
										
										
										
											2018-03-19 16:13:00 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->vertex_len = v_len; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_attr_set(GPUVertBuf *verts, uint a_idx, uint v_idx, const void *data) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const GPUVertFormat *format = &verts->format; | 
					
						
							|  |  |  |   const GPUVertAttr *a = &format->attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(a_idx < format->attr_len); | 
					
						
							|  |  |  |   assert(v_idx < verts->vertex_alloc); | 
					
						
							|  |  |  |   assert(verts->data != NULL); | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->dirty = true; | 
					
						
							|  |  |  |   memcpy((GLubyte *)verts->data + a->offset + v_idx * format->stride, data, a->sz); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_attr_fill(GPUVertBuf *verts, uint a_idx, const void *data) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const GPUVertFormat *format = &verts->format; | 
					
						
							|  |  |  |   const GPUVertAttr *a = &format->attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(a_idx < format->attr_len); | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const uint stride = a->sz; /* tightly packed input data */ | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPU_vertbuf_attr_fill_stride(verts, a_idx, stride, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts, uint a_idx, uint stride, const void *data) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const GPUVertFormat *format = &verts->format; | 
					
						
							|  |  |  |   const GPUVertAttr *a = &format->attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(a_idx < format->attr_len); | 
					
						
							|  |  |  |   assert(verts->data != NULL); | 
					
						
							| 
									
										
										
										
											2016-09-14 16:28:16 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->dirty = true; | 
					
						
							|  |  |  |   const uint vertex_len = verts->vertex_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (format->attr_len == 1 && stride == format->stride) { | 
					
						
							|  |  |  |     /* we can copy it all at once */ | 
					
						
							|  |  |  |     memcpy(verts->data, data, vertex_len * a->sz); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* we must copy it per vertex */ | 
					
						
							|  |  |  |     for (uint v = 0; v < vertex_len; ++v) { | 
					
						
							|  |  |  |       memcpy((GLubyte *)verts->data + a->offset + v * format->stride, | 
					
						
							|  |  |  |              (const GLubyte *)data + v * stride, | 
					
						
							|  |  |  |              a->sz); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 16:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts, uint a_idx, GPUVertBufRaw *access) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const GPUVertFormat *format = &verts->format; | 
					
						
							|  |  |  |   const GPUVertAttr *a = &format->attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2017-06-29 20:09:05 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(a_idx < format->attr_len); | 
					
						
							|  |  |  |   assert(verts->data != NULL); | 
					
						
							| 
									
										
										
										
											2017-06-29 20:09:05 +10:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   verts->dirty = true; | 
					
						
							| 
									
										
										
										
											2018-03-17 16:58:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   access->size = a->sz; | 
					
						
							|  |  |  |   access->stride = format->stride; | 
					
						
							|  |  |  |   access->data = (GLubyte *)verts->data + a->offset; | 
					
						
							|  |  |  |   access->data_init = access->data; | 
					
						
							| 
									
										
										
										
											2017-06-29 20:09:05 +10:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride); | 
					
						
							| 
									
										
										
										
											2017-06-29 20:09:05 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-29 20:09:05 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | static void VertBuffer_upload_data(GPUVertBuf *verts) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint buffer_sz = GPU_vertbuf_size_get(verts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* orphan the vbo to avoid sync */ | 
					
						
							|  |  |  |   glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); | 
					
						
							|  |  |  |   /* upload data */ | 
					
						
							|  |  |  |   glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (verts->usage == GPU_USAGE_STATIC) { | 
					
						
							|  |  |  |     MEM_freeN(verts->data); | 
					
						
							|  |  |  |     verts->data = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   verts->dirty = false; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-19 16:13:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void GPU_vertbuf_use(GPUVertBuf *verts) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* only create the buffer the 1st time */ | 
					
						
							|  |  |  |   if (verts->vbo_id == 0) { | 
					
						
							|  |  |  |     verts->vbo_id = GPU_buf_alloc(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); | 
					
						
							|  |  |  |   if (verts->dirty) { | 
					
						
							|  |  |  |     VertBuffer_upload_data(verts); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-04 21:22:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | uint GPU_vertbuf_get_memory_usage(void) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return vbo_memory_usage; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } |