u_vbuf.c revision 5ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9
1710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov/************************************************************************** 26091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * 36091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * Copyright 2011 Marek Olšák <maraeo@gmail.com> 46091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * All Rights Reserved. 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * Permission is hereby granted, free of charge, to any person obtaining a 76091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * copy of this software and associated documentation files (the 86091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * "Software"), to deal in the Software without restriction, including 927107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling * without limitation the rights to use, copy, modify, merge, publish, 1027107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling * distribute, sub license, and/or sell copies of the Software, and to 1127107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling * permit persons to whom the Software is furnished to do so, subject to 1227107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling * the following conditions: 1327107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling * 146091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * The above copyright notice and this permission notice (including the 156091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * next paragraph) shall be included in all copies or substantial portions 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak * of the Software. 17674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak * 186091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19d509d0b532ec2358b3f341d4a4cd1411cb8b5db2Chris Lattner * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 203467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR 223f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2322bd64173981bf1251c4b3bfc684207340534ba3Bill Wendling * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2558d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner * 266091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer **************************************************************************/ 276091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer 28d426a642a23a234547cbc7061f5bfec157673249Bill Wendling#include "util/u_vbuf.h" 29702cc91aa1bd41540e8674921ae7ac89a4ff061fBill Wendling 30f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling#include "util/u_dump.h" 31817abdd8b055059e5930a15704b9f52da4236456Bill Wendling#include "util/u_format.h" 32817abdd8b055059e5930a15704b9f52da4236456Bill Wendling#include "util/u_inlines.h" 336dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling#include "util/u_memory.h" 34c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer#include "util/u_upload_mgr.h" 352c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling#include "translate/translate.h" 36ad9a9e15595bc9d5ba1ed752caf8572957f77a3dDuncan Sands#include "translate/translate_cache.h" 37ad9a9e15595bc9d5ba1ed752caf8572957f77a3dDuncan Sands#include "cso_cache/cso_cache.h" 381d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling#include "cso_cache/cso_hash.h" 3927107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling 4027107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendlingstruct u_vbuf_elements { 411d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling unsigned count; 421d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; 431d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling 44034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling unsigned src_format_size[PIPE_MAX_ATTRIBS]; 456765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 461d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling /* If (velem[i].src_format != native_format[i]), the vertex buffer 4773dee180c836270644dfa7d90f9c5ba877567999Bill Wendling * referenced by the vertex element cannot be used for rendering and 48f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling * its vertex data must be translated to native_format[i]. */ 4973dee180c836270644dfa7d90f9c5ba877567999Bill Wendling enum pipe_format native_format[PIPE_MAX_ATTRIBS]; 5073dee180c836270644dfa7d90f9c5ba877567999Bill Wendling unsigned native_format_size[PIPE_MAX_ATTRIBS]; 5173dee180c836270644dfa7d90f9c5ba877567999Bill Wendling 52f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling /* This might mean two things: 5373dee180c836270644dfa7d90f9c5ba877567999Bill Wendling * - src_format != native_format, as discussed above. 5411d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling * - src_offset % 4 != 0 (if the caps don't allow such an offset). */ 5511d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling boolean incompatible_layout; 56f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling /* Per-element flags. */ 5711d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling boolean incompatible_layout_elem[PIPE_MAX_ATTRIBS]; 5811d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling 5911d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling void *driver_cso; 6011d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling}; 6111d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling 6211d00420e42ba88c3b48cab997965a7be79315e2Bill Wendlingenum { 63629fb82419d9bfff6ae475363bcce66192dfcc8eBill Wendling VB_VERTEX = 0, 645a0eeb5a9d727940b1dbe8dff6e9aa292ada0f6aBill Wendling VB_INSTANCE = 1, 65480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling VB_CONST = 2, 66480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling VB_NUM = 3 676765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling}; 68f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling 69480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendlingstruct u_vbuf_priv { 70480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct u_vbuf b; 71480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct pipe_context *pipe; 72480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct translate_cache *translate_cache; 739a419f656e278b96e9dfe739cd63c7bff9a4e1fdQuentin Colombet struct cso_cache *cso_cache; 74480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling 75480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* Vertex buffers for the driver. 76480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling * There are no user buffers. */ 77143d46476cdcf5b88b9ee18ebd799e5820a2db0eBill Wendling struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS]; 78480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling int nr_real_vertex_buffers; 7967ae13575900e8efd056672987249fd0adbf5e73James Molloy boolean vertex_buffers_dirty; 80480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling 81480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* The index buffer. */ 82480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct pipe_index_buffer index_buffer; 833a106e60366a51b4594ec303ff8dbbc58913227fBill Wendling 84480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* and its associated helper structure for this module. */ 85480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct u_vbuf_elements *ve; 86480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling 87480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* Vertex elements used for the translate fallback. */ 88480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; 89480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* If non-NULL, this is a vertex element state used for the translate 90456ca048af35163b9f52187e92a23ee0a9f059e8Stephen Lin * fallback and therefore used for rendering too. */ 91480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling void *fallback_ve; 92480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* The vertex buffer slot index where translated vertices have been 93480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling * stored in. */ 946765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling unsigned fallback_vbs[VB_NUM]; 956765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 96f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling /* Whether there is any user buffer. */ 97480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling boolean any_user_vbs; 98480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* Whether there is a buffer with a non-native layout. */ 99114baee1fa017daefad2339c77b45b9ca3d79a41Bill Wendling boolean incompatible_vb_layout; 100480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /* Per-buffer flags. */ 1018eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany boolean incompatible_vb[PIPE_MAX_ATTRIBS]; 1028eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany 1038eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany void (*driver_set_index_buffer)(struct pipe_context *pipe, 104480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling const struct pipe_index_buffer *); 1050319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling void (*driver_set_vertex_buffers)(struct pipe_context *, 1060319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling unsigned num_buffers, 107886a7663c72cb04eaee58cb6997c394f5096a8b9Benjamin Kramer const struct pipe_vertex_buffer *); 1086765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling void *(*driver_create_vertex_elements_state)(struct pipe_context *, 1096765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling unsigned num_elements, 11027107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling const struct pipe_vertex_element *); 11127107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling void (*driver_bind_vertex_elements_state)(struct pipe_context *, void *); 112d426a642a23a234547cbc7061f5bfec157673249Bill Wendling void (*driver_delete_vertex_elements_state)(struct pipe_context *, void *); 11327107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling void (*driver_draw_vbo)(struct pipe_context *pipe, 1142c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling const struct pipe_draw_info *info); 115c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}; 116c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 117c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingstatic void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr) 118c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling{ 119c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling struct pipe_screen *screen = mgr->pipe->screen; 1208c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 1218c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->b.caps.format_fixed32 = 1228c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER, 1232c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling 0, PIPE_BIND_VERTEX_BUFFER); 124c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling 125c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling mgr->b.caps.format_float16 = 126c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER, 127c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling 0, PIPE_BIND_VERTEX_BUFFER); 128c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling 129c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling mgr->b.caps.format_float64 = 130c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER, 131c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 0, PIPE_BIND_VERTEX_BUFFER); 132c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 1338c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->b.caps.format_norm32 = 1348c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER, 1358c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 0, PIPE_BIND_VERTEX_BUFFER) && 1368c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER, 1378c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 0, PIPE_BIND_VERTEX_BUFFER); 1388c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 1398c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->b.caps.format_scaled32 = 1408c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER, 1418c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 0, PIPE_BIND_VERTEX_BUFFER) && 1428c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER, 143eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi 0, PIPE_BIND_VERTEX_BUFFER); 144eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi} 145eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi 14664754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendlingstatic void u_vbuf_install(struct u_vbuf_priv *mgr); 14764754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling 14864754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendlingstruct u_vbuf * 1498c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingu_vbuf_create(struct pipe_context *pipe, 1508c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling unsigned upload_buffer_size, 1518c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling unsigned upload_buffer_alignment, 1526dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling unsigned upload_buffer_bind, 1538c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling enum u_fetch_alignment fetch_alignment) 1548c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling{ 1558c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv); 1568c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 1578c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->pipe = pipe; 1588c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->cso_cache = cso_cache_create(); 1598c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->translate_cache = translate_cache_create(); 1608c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs)); 1618c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling 1628c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling mgr->b.uploader = u_upload_create(pipe, upload_buffer_size, 1638c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling upload_buffer_alignment, 1646dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling upload_buffer_bind); 1651d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling 166ef99fe8efaa6cb74c66e570a6ef467debca92911Bill Wendling mgr->b.caps.fetch_dword_unaligned = 167e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED; 168ef99fe8efaa6cb74c66e570a6ef467debca92911Bill Wendling 1691d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling u_vbuf_init_format_caps(mgr); 170943c29135e03e55f9a5dab393786171a4a536482Bill Wendling u_vbuf_install(mgr); 171e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling return &mgr->b; 17230b483c94001927b3593ed200e823104bab51660Bill Wendling} 173c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 174c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/* XXX I had to fork this off of cso_context. */ 175b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendlingstatic void * 176c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingu_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr, 1778c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling unsigned count, 1782d5be6c313c0f9e23e56620fa8f8ae8d9b539bf0Bill Wendling const struct pipe_vertex_element *states) 1792d5be6c313c0f9e23e56620fa8f8ae8d9b539bf0Bill Wendling{ 1802d5be6c313c0f9e23e56620fa8f8ae8d9b539bf0Bill Wendling unsigned key_size, hash_key; 181c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling struct cso_hash_iter iter; 1823467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling void *handle; 1833467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling struct cso_velems_state velems_state; 184bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling 185bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling /* need to include the count into the stored state data too. */ 186bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned); 187827cde1c8319e51463007078a7ce3660ebc93036Duncan Sands velems_state.count = count; 188827cde1c8319e51463007078a7ce3660ebc93036Duncan Sands memcpy(velems_state.velems, states, 189e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling sizeof(struct pipe_vertex_element) * count); 19027107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling hash_key = cso_construct_key((void*)&velems_state, key_size); 191c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling iter = cso_find_state_template(mgr->cso_cache, hash_key, CSO_VELEMENTS, 192c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling (void*)&velems_state, key_size); 193c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling 194c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling if (cso_hash_iter_is_null(iter)) { 195c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling struct cso_velements *cso = MALLOC_STRUCT(cso_velements); 196c3662eeaa4a1a4061fc6d5c81e3eed48c5d9da26Bill Wendling memcpy(&cso->state, &velems_state, key_size); 19799faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling cso->data = 19807aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling mgr->driver_create_vertex_elements_state(mgr->pipe, count, 19907aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling &cso->state.velems[0]); 20007aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling cso->delete_state = 20107aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling (cso_state_callback)mgr->driver_delete_vertex_elements_state; 20207aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling cso->context = mgr->pipe; 20307aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling 204a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso); 2057d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling handle = cso->data; 20616274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling } else { 207a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data; 20873dee180c836270644dfa7d90f9c5ba877567999Bill Wendling } 2090976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling 210ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling mgr->driver_bind_vertex_elements_state(mgr->pipe, handle); 2110976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling return handle; 21273dee180c836270644dfa7d90f9c5ba877567999Bill Wendling} 2138a6a7bb6a601061031cddd77129532a3b467300bBill Wendling 2140976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendlingvoid u_vbuf_destroy(struct u_vbuf *mgrb) 21587e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling{ 21687e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; 2176bdbf061c353295669b6bfc271b948158602d1bcBill Wendling unsigned i; 21887e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling 2196bdbf061c353295669b6bfc271b948158602d1bcBill Wendling assert(mgr->pipe->draw); 22087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling mgr->pipe->draw = NULL; 22187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling 22287e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { 2236bdbf061c353295669b6bfc271b948158602d1bcBill Wendling pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); 22487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling } 22587e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { 2267d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); 227ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling } 22858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 229ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling translate_cache_destroy(mgr->translate_cache); 230710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov u_upload_destroy(mgr->b.uploader); 23158d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner cso_cache_delete(mgr->cso_cache); 232c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling FREE(mgr); 23358d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner} 234710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 23518e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendlingstatic void 2368e47daf2858e980210f3e1f007036b24da342c29Bill Wendlingu_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, 2378a6a7bb6a601061031cddd77129532a3b467300bBill Wendling unsigned vb_mask, unsigned out_vb, 23832a57958226e369f964a034da2ce7083a1a34297Bill Wendling int start_vertex, unsigned num_vertices, 2398a6a7bb6a601061031cddd77129532a3b467300bBill Wendling int start_index, unsigned num_indices, int min_index, 24058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner bool unroll_indices) 241defaca00b8087d452df2b783250a48a32658a910Bill Wendling{ 242defaca00b8087d452df2b783250a48a32658a910Bill Wendling struct translate *tr; 2438a6a7bb6a601061031cddd77129532a3b467300bBill Wendling struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; 244defaca00b8087d452df2b783250a48a32658a910Bill Wendling struct pipe_resource *out_buffer = NULL; 245710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov uint8_t *out_map; 2469106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler unsigned i, out_offset; 2479106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler 2488a6a7bb6a601061031cddd77129532a3b467300bBill Wendling /* Get a translate object. */ 2499106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler tr = translate_cache_find(mgr->translate_cache, key); 2509106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler 251e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling /* Map buffers we want to translate. */ 252e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { 2538a6a7bb6a601061031cddd77129532a3b467300bBill Wendling if (vb_mask & (1 << i)) { 254e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i]; 255e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling unsigned offset = vb->buffer_offset + vb->stride * start_vertex; 25618e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling uint8_t *map; 2578246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling 25818e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling if (u_vbuf_resource(vb->buffer)->user_ptr) { 2598a6a7bb6a601061031cddd77129532a3b467300bBill Wendling map = u_vbuf_resource(vb->buffer)->user_ptr + offset; 2608246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling } else { 2618246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling unsigned size = vb->stride ? num_vertices * vb->stride 2628246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling : sizeof(double)*4; 2638246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling 2648246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling if (offset+size > vb->buffer->width0) { 2658a6a7bb6a601061031cddd77129532a3b467300bBill Wendling size = vb->buffer->width0 - offset; 2668246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling } 267710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 26858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size, 269c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling PIPE_TRANSFER_READ, &vb_transfer[i]); 27058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner } 27118e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 27285b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling /* Subtract min_index so that indexing with the index buffer works. */ 27385b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling if (unroll_indices) { 27485b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling map -= vb->stride * min_index; 27518e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling } 2768a6a7bb6a601061031cddd77129532a3b467300bBill Wendling 27719c874638d9478a5d5028854817a5ee72293bb2bDevang Patel tr->set_buffer(tr, i, map, vb->stride, ~0); 27818e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling } 2793fc4b96b503fa202411317684a2ba02e41e43072Bill Wendling } 28019c874638d9478a5d5028854817a5ee72293bb2bDevang Patel 28118e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /* Translate. */ 282c5f1bc88a2eb7ad9ff924ca90cf88494e5f947b9Bill Wendling if (unroll_indices) { 283710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov struct pipe_index_buffer *ib = &mgr->index_buffer; 284831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling struct pipe_transfer *transfer = NULL; 28519d815c04fde6b7b53c2b542813157edfa213842Bill Wendling unsigned offset = ib->offset + start_index * ib->index_size; 286831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling uint8_t *map; 2870e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling 2880e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling assert(ib->buffer && ib->index_size); 2890e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling 290831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (u_vbuf_resource(ib->buffer)->user_ptr) { 29119d815c04fde6b7b53c2b542813157edfa213842Bill Wendling map = u_vbuf_resource(ib->buffer)->user_ptr + offset; 292831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling } else { 293c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset, 294c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling num_indices * ib->index_size, 295c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling PIPE_TRANSFER_READ, &transfer); 296c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling } 2970e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling 2980e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling /* Create and map the output buffer. */ 2990e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling u_upload_alloc(mgr->b.uploader, 0, 3000e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling key->output_stride * num_indices, 3010e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling &out_offset, &out_buffer, 3020e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling (void**)&out_map); 30349f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling 3048a6a7bb6a601061031cddd77129532a3b467300bBill Wendling switch (ib->index_size) { 3058e47daf2858e980210f3e1f007036b24da342c29Bill Wendling case 4: 306831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling tr->run_elts(tr, (unsigned*)map, num_indices, 0, out_map); 30719d815c04fde6b7b53c2b542813157edfa213842Bill Wendling break; 308831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling case 2: 309831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling tr->run_elts16(tr, (uint16_t*)map, num_indices, 0, out_map); 310a88a016f2d99488f2eff0eb6be256f2f43602afaBill Wendling break; 311b1ac6e617291e2a628bc460933bde97c73466cb0Bill Wendling case 1: 312831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling tr->run_elts8(tr, map, num_indices, 0, out_map); 31316c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling break; 31416c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling } 3158a6a7bb6a601061031cddd77129532a3b467300bBill Wendling 3168a6a7bb6a601061031cddd77129532a3b467300bBill Wendling if (transfer) { 31716c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling pipe_buffer_unmap(mgr->pipe, transfer); 318041221c0972ff575b07f76808c504833d629ae1fChris Lattner } 31918e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling } else { 320ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling /* Create and map the output buffer. */ 32118e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling u_upload_alloc(mgr->b.uploader, 32218e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling key->output_stride * start_vertex, 323ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling key->output_stride * num_vertices, 32418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling &out_offset, &out_buffer, 325710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov (void**)&out_map); 32658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 327c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling out_offset -= key->output_stride * start_vertex; 32858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 329710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov tr->run(tr, 0, num_vertices, 0, out_map); 330c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling } 331c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 332c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling /* Unmap all buffers. */ 33318e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { 33458d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner if (vb_transfer[i]) { 335ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); 33658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner } 337710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov } 33818e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 33958d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /* Setup the new vertex buffer. */ 340aa57893e84ba7a35948fcaa99812ba88e58f4797Bill Wendling mgr->real_vertex_buffer[out_vb].buffer_offset = out_offset; 34158d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner mgr->real_vertex_buffer[out_vb].stride = key->output_stride; 342710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 34318e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /* Move the buffer reference. */ 34418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling pipe_resource_reference( 34518e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling &mgr->real_vertex_buffer[out_vb].buffer, NULL); 34658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner mgr->real_vertex_buffer[out_vb].buffer = out_buffer; 347710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov} 348e1f95db4803a48a30fc2a1d5868281a87a36fb85Bill Wendling 3493e3e789aede6ec38d39c95d88ad4e8634d5a259bBill Wendlingstatic boolean 350e1f95db4803a48a30fc2a1d5868281a87a36fb85Bill Wendlingu_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr, 3518e47daf2858e980210f3e1f007036b24da342c29Bill Wendling unsigned mask[VB_NUM]) 3528e47daf2858e980210f3e1f007036b24da342c29Bill Wendling{ 3538e47daf2858e980210f3e1f007036b24da342c29Bill Wendling unsigned i, type; 354f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling unsigned nr = mgr->ve->count; 35558d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner boolean used_vb[PIPE_MAX_ATTRIBS] = {0}; 3564f859aa532dbf061736f9c23e0d0882b5cdfe566Reid Spencer unsigned fallback_vbs[VB_NUM]; 357a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 358a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling memset(fallback_vbs, ~0, sizeof(fallback_vbs)); 35916274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling 36016274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling /* Mark used vertex buffers as... used. */ 36116274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling for (i = 0; i < nr; i++) { 36216274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling if (!mgr->ve->incompatible_layout_elem[i]) { 36316274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling unsigned index = mgr->ve->ve[i].vertex_buffer_index; 36416274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling 365c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling if (!mgr->incompatible_vb[index]) { 36616274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling used_vb[index] = TRUE; 36716274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling } 36816274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling } 36916274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling } 370c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 37116274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling /* Find free slots for each type if needed. */ 37216274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling i = 0; 37316274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling for (type = 0; type < VB_NUM; type++) { 374c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling if (mask[type]) { 37516274258d16342a2f91aaa3690b78ce74e4105f1Bill Wendling for (; i < PIPE_MAX_ATTRIBS; i++) { 376c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling if (!used_vb[i]) { 377c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling /*printf("found slot=%i for type=%i\n", i, type);*/ 378c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling fallback_vbs[type] = i; 379c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling i++; 380a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling if (i > mgr->nr_real_vertex_buffers) { 381a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling mgr->nr_real_vertex_buffers = i; 382a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 383a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling break; 384a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 3853f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer } 386ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling if (i == PIPE_MAX_ATTRIBS) { 387a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /* fail, reset the number to its original value */ 388a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; 389a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling return FALSE; 390c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer } 391c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer } 392c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer } 393f9271ea159b97e2febedcf095c3c4122cb24d077Bill Wendling 394a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling memcpy(mgr->fallback_vbs, fallback_vbs, sizeof(fallback_vbs)); 395c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer return TRUE; 39639da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling} 397a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 398a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendlingstatic boolean 39985df6b43403d3ebf5d80023a85699c6fb254941aBill Wendlingu_vbuf_translate_begin(struct u_vbuf_priv *mgr, 40085df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling int start_vertex, unsigned num_vertices, 40185df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling int start_instance, unsigned num_instances, 40285df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling int start_index, unsigned num_indices, int min_index, 403a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool unroll_indices) 404a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling{ 405a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned mask[VB_NUM] = {0}; 406a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling struct translate_key key[VB_NUM]; 407a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned elem_index[VB_NUM][PIPE_MAX_ATTRIBS]; /* ... into key.elements */ 408a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned i, type; 40939da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling 41039da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling int start[VB_NUM] = { 41139da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling start_vertex, /* VERTEX */ 412ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling start_instance, /* INSTANCE */ 413ad19d9c4228718b0ac167d0dfa013d14c3c9f135Bill Wendling 0 /* CONST */ 414ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling }; 415a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 416a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned num[VB_NUM] = { 417a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling num_vertices, /* VERTEX */ 41849f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling num_instances, /* INSTANCE */ 419e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendling 1 /* CONST */ 420a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling }; 421ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling 422ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling memset(key, 0, sizeof(key)); 423ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling memset(elem_index, ~0, sizeof(elem_index)); 42485df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling 42585df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling /* See if there are vertex attribs of each type to translate and 42685df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling * which ones. */ 427a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling for (i = 0; i < mgr->ve->count; i++) { 428c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index; 4293f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer 4303f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer if (!mgr->b.vertex_buffer[vb_index].stride) { 431c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer if (!mgr->ve->incompatible_layout_elem[i] && 432a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling !mgr->incompatible_vb[vb_index]) { 433c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling continue; 434c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling } 435c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling mask[VB_CONST] |= 1 << vb_index; 436c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling } else if (mgr->ve->ve[i].instance_divisor) { 437a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling if (!mgr->ve->incompatible_layout_elem[i] && 438a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling !mgr->incompatible_vb[vb_index]) { 439a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling continue; 440a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 441a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling mask[VB_INSTANCE] |= 1 << vb_index; 442e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendling } else { 443a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling if (!unroll_indices && 444a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling !mgr->ve->incompatible_layout_elem[i] && 445a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling !mgr->incompatible_vb[vb_index]) { 446a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling continue; 447a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 448a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling mask[VB_VERTEX] |= 1 << vb_index; 449a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 450a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 451a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 452a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]); 453a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 454a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /* Find free vertex buffer slots. */ 455a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) { 456a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling return FALSE; 457a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 458a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 459a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /* Initialize the translate keys. */ 460a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling for (i = 0; i < mgr->ve->count; i++) { 461c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer struct translate_key *k; 462c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer struct translate_element *te; 4633f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer unsigned bit, vb_index = mgr->ve->ve[i].vertex_buffer_index; 46487de71cb9f12d874e88d4f314ab245985c1b36bcBill Wendling bit = 1 << vb_index; 46564754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling 46664754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling if (!mgr->ve->incompatible_layout_elem[i] && 46764754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling !mgr->incompatible_vb[vb_index] && 46864754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling (!unroll_indices || !(mask[VB_VERTEX] & bit))) { 46964754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling continue; 47064754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling } 47164754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling 47264754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling /* Set type to what we will translate. 47364754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling * Whether vertex, instance, or constant attribs. */ 47464754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling for (type = 0; type < VB_NUM; type++) { 47564754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling if (mask[type] & bit) { 47687de71cb9f12d874e88d4f314ab245985c1b36bcBill Wendling break; 47787de71cb9f12d874e88d4f314ab245985c1b36bcBill Wendling } 478a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 479a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling assert(type < VB_NUM); 480a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling assert(translate_is_output_format_supported(mgr->ve->native_format[i])); 481a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /*printf("velem=%i type=%i\n", i, type);*/ 482c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 483f9271ea159b97e2febedcf095c3c4122cb24d077Bill Wendling /* Add the vertex element. */ 484c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling k = &key[type]; 485c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling elem_index[type][i] = k->nr_elements; 486c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling 487a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling te = &k->element[k->nr_elements]; 488a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling te->type = TRANSLATE_ELEMENT_NORMAL; 4898e47daf2858e980210f3e1f007036b24da342c29Bill Wendling te->instance_divisor = 0; 4908e47daf2858e980210f3e1f007036b24da342c29Bill Wendling te->input_buffer = vb_index; 4918e47daf2858e980210f3e1f007036b24da342c29Bill Wendling te->input_format = mgr->ve->ve[i].src_format; 492e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendling te->input_offset = mgr->ve->ve[i].src_offset; 4938e47daf2858e980210f3e1f007036b24da342c29Bill Wendling te->output_format = mgr->ve->native_format[i]; 4948e47daf2858e980210f3e1f007036b24da342c29Bill Wendling te->output_offset = k->output_stride; 4958e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 49627107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling k->output_stride += mgr->ve->native_format_size[i]; 4976091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer k->nr_elements++; 4986091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer } 499 500 /* Translate buffers. */ 501 for (type = 0; type < VB_NUM; type++) { 502 if (key[type].nr_elements) { 503 u_vbuf_translate_buffers(mgr, &key[type], mask[type], 504 mgr->fallback_vbs[type], 505 start[type], num[type], 506 start_index, num_indices, min_index, 507 unroll_indices && type == VB_VERTEX); 508 509 /* Fixup the stride for constant attribs. */ 510 if (type == VB_CONST) { 511 mgr->real_vertex_buffer[mgr->fallback_vbs[VB_CONST]].stride = 0; 512 } 513 } 514 } 515 516 /* Setup new vertex elements. */ 517 for (i = 0; i < mgr->ve->count; i++) { 518 for (type = 0; type < VB_NUM; type++) { 519 if (elem_index[type][i] < key[type].nr_elements) { 520 struct translate_element *te = &key[type].element[elem_index[type][i]]; 521 mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor; 522 mgr->fallback_velems[i].src_format = te->output_format; 523 mgr->fallback_velems[i].src_offset = te->output_offset; 524 mgr->fallback_velems[i].vertex_buffer_index = mgr->fallback_vbs[type]; 525 526 /* elem_index[type][i] can only be set for one type. */ 527 assert(type > VB_INSTANCE || elem_index[type+1][i] == ~0); 528 assert(type > VB_VERTEX || elem_index[type+2][i] == ~0); 529 break; 530 } 531 } 532 /* No translating, just copy the original vertex element over. */ 533 if (type == VB_NUM) { 534 memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i], 535 sizeof(struct pipe_vertex_element)); 536 } 537 } 538 539 mgr->fallback_ve = u_vbuf_cache_set_vertex_elements(mgr, mgr->ve->count, 540 mgr->fallback_velems); 541 return TRUE; 542} 543 544static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) 545{ 546 unsigned i; 547 548 /* Restore vertex elements. */ 549 mgr->driver_bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso); 550 mgr->fallback_ve = NULL; 551 552 /* Unreference the now-unused VBOs. */ 553 for (i = 0; i < VB_NUM; i++) { 554 unsigned vb = mgr->fallback_vbs[i]; 555 if (vb != ~0) { 556 pipe_resource_reference(&mgr->real_vertex_buffer[vb].buffer, NULL); 557 mgr->fallback_vbs[i] = ~0; 558 } 559 } 560 mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; 561} 562 563#define FORMAT_REPLACE(what, withwhat) \ 564 case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break 565 566static void * 567u_vbuf_create_vertex_elements(struct pipe_context *pipe, 568 unsigned count, 569 const struct pipe_vertex_element *attribs) 570{ 571 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; 572 unsigned i; 573 struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS]; 574 struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); 575 576 ve->count = count; 577 578 memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); 579 memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count); 580 581 /* Set the best native format in case the original format is not 582 * supported. */ 583 for (i = 0; i < count; i++) { 584 enum pipe_format format = ve->ve[i].src_format; 585 586 ve->src_format_size[i] = util_format_get_blocksize(format); 587 588 /* Choose a native format. 589 * For now we don't care about the alignment, that's going to 590 * be sorted out later. */ 591 if (!mgr->b.caps.format_fixed32) { 592 switch (format) { 593 FORMAT_REPLACE(R32_FIXED, R32_FLOAT); 594 FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT); 595 FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT); 596 FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT); 597 default:; 598 } 599 } 600 if (!mgr->b.caps.format_float16) { 601 switch (format) { 602 FORMAT_REPLACE(R16_FLOAT, R32_FLOAT); 603 FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT); 604 FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT); 605 FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT); 606 default:; 607 } 608 } 609 if (!mgr->b.caps.format_float64) { 610 switch (format) { 611 FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); 612 FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); 613 FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); 614 FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); 615 default:; 616 } 617 } 618 if (!mgr->b.caps.format_norm32) { 619 switch (format) { 620 FORMAT_REPLACE(R32_UNORM, R32_FLOAT); 621 FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); 622 FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); 623 FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); 624 FORMAT_REPLACE(R32_SNORM, R32_FLOAT); 625 FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); 626 FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); 627 FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); 628 default:; 629 } 630 } 631 if (!mgr->b.caps.format_scaled32) { 632 switch (format) { 633 FORMAT_REPLACE(R32_USCALED, R32_FLOAT); 634 FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); 635 FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); 636 FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); 637 FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); 638 FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); 639 FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); 640 FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); 641 default:; 642 } 643 } 644 645 native_attribs[i].src_format = format; 646 ve->native_format[i] = format; 647 ve->native_format_size[i] = 648 util_format_get_blocksize(ve->native_format[i]); 649 650 ve->incompatible_layout_elem[i] = 651 ve->ve[i].src_format != ve->native_format[i] || 652 (!mgr->b.caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0); 653 ve->incompatible_layout = 654 ve->incompatible_layout || 655 ve->incompatible_layout_elem[i]; 656 } 657 658 /* Align the formats to the size of DWORD if needed. */ 659 if (!mgr->b.caps.fetch_dword_unaligned) { 660 for (i = 0; i < count; i++) { 661 ve->native_format_size[i] = align(ve->native_format_size[i], 4); 662 } 663 } 664 665 ve->driver_cso = 666 mgr->driver_create_vertex_elements_state(pipe, count, native_attribs); 667 return ve; 668} 669 670static void u_vbuf_bind_vertex_elements(struct pipe_context *pipe, 671 void *cso) 672{ 673 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; 674 struct u_vbuf_elements *ve = cso; 675 676 mgr->ve = ve; 677 mgr->b.vertex_elements = ve; 678 mgr->driver_bind_vertex_elements_state(pipe, ve ? ve->driver_cso : NULL); 679} 680 681static void u_vbuf_delete_vertex_elements(struct pipe_context *pipe, 682 void *cso) 683{ 684 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; 685 struct u_vbuf_elements *ve = cso; 686 687 mgr->driver_delete_vertex_elements_state(pipe, ve->driver_cso); 688 FREE(ve); 689} 690 691static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe, 692 unsigned count, 693 const struct pipe_vertex_buffer *bufs) 694{ 695 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; 696 unsigned i; 697 698 mgr->any_user_vbs = FALSE; 699 mgr->incompatible_vb_layout = FALSE; 700 memset(mgr->incompatible_vb, 0, sizeof(mgr->incompatible_vb)); 701 702 if (!mgr->b.caps.fetch_dword_unaligned) { 703 /* Check if the strides and offsets are aligned to the size of DWORD. */ 704 for (i = 0; i < count; i++) { 705 if (bufs[i].buffer) { 706 if (bufs[i].stride % 4 != 0 || 707 bufs[i].buffer_offset % 4 != 0) { 708 mgr->incompatible_vb_layout = TRUE; 709 mgr->incompatible_vb[i] = TRUE; 710 } 711 } 712 } 713 } 714 715 for (i = 0; i < count; i++) { 716 const struct pipe_vertex_buffer *vb = &bufs[i]; 717 718 pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer); 719 720 mgr->real_vertex_buffer[i].buffer_offset = 721 mgr->b.vertex_buffer[i].buffer_offset = vb->buffer_offset; 722 723 mgr->real_vertex_buffer[i].stride = 724 mgr->b.vertex_buffer[i].stride = vb->stride; 725 726 if (!vb->buffer || 727 mgr->incompatible_vb[i]) { 728 pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); 729 continue; 730 } 731 732 if (u_vbuf_resource(vb->buffer)->user_ptr) { 733 pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); 734 mgr->any_user_vbs = TRUE; 735 continue; 736 } 737 738 pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, vb->buffer); 739 } 740 741 for (i = count; i < mgr->b.nr_vertex_buffers; i++) { 742 pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); 743 } 744 for (i = count; i < mgr->nr_real_vertex_buffers; i++) { 745 pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); 746 } 747 748 mgr->b.nr_vertex_buffers = count; 749 mgr->nr_real_vertex_buffers = count; 750 mgr->vertex_buffers_dirty = TRUE; 751} 752 753static void u_vbuf_set_index_buffer(struct pipe_context *pipe, 754 const struct pipe_index_buffer *ib) 755{ 756 struct u_vbuf_priv *mgr = pipe->draw; 757 758 if (ib && ib->buffer) { 759 assert(ib->offset % ib->index_size == 0); 760 pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); 761 mgr->index_buffer.offset = ib->offset; 762 mgr->index_buffer.index_size = ib->index_size; 763 } else { 764 pipe_resource_reference(&mgr->index_buffer.buffer, NULL); 765 } 766 767 mgr->driver_set_index_buffer(pipe, ib); 768} 769 770static void 771u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, 772 int start_vertex, unsigned num_vertices, 773 int start_instance, unsigned num_instances) 774{ 775 unsigned i; 776 unsigned nr_velems = mgr->ve->count; 777 unsigned nr_vbufs = mgr->b.nr_vertex_buffers; 778 struct pipe_vertex_element *velems = 779 mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; 780 unsigned start_offset[PIPE_MAX_ATTRIBS]; 781 unsigned end_offset[PIPE_MAX_ATTRIBS] = {0}; 782 783 /* Determine how much data needs to be uploaded. */ 784 for (i = 0; i < nr_velems; i++) { 785 struct pipe_vertex_element *velem = &velems[i]; 786 unsigned index = velem->vertex_buffer_index; 787 struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index]; 788 unsigned instance_div, first, size; 789 790 /* Skip the buffers generated by translate. */ 791 if (index == mgr->fallback_vbs[VB_VERTEX] || 792 index == mgr->fallback_vbs[VB_INSTANCE] || 793 index == mgr->fallback_vbs[VB_CONST]) { 794 continue; 795 } 796 797 assert(vb->buffer); 798 799 if (!u_vbuf_resource(vb->buffer)->user_ptr) { 800 continue; 801 } 802 803 instance_div = velem->instance_divisor; 804 first = vb->buffer_offset + velem->src_offset; 805 806 if (!vb->stride) { 807 /* Constant attrib. */ 808 size = mgr->ve->src_format_size[i]; 809 } else if (instance_div) { 810 /* Per-instance attrib. */ 811 unsigned count = (num_instances + instance_div - 1) / instance_div; 812 first += vb->stride * start_instance; 813 size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; 814 } else { 815 /* Per-vertex attrib. */ 816 first += vb->stride * start_vertex; 817 size = vb->stride * (num_vertices - 1) + mgr->ve->src_format_size[i]; 818 } 819 820 /* Update offsets. */ 821 if (!end_offset[index]) { 822 start_offset[index] = first; 823 end_offset[index] = first + size; 824 } else { 825 if (first < start_offset[index]) 826 start_offset[index] = first; 827 if (first + size > end_offset[index]) 828 end_offset[index] = first + size; 829 } 830 } 831 832 /* Upload buffers. */ 833 for (i = 0; i < nr_vbufs; i++) { 834 unsigned start, end = end_offset[i]; 835 struct pipe_vertex_buffer *real_vb; 836 uint8_t *ptr; 837 838 if (!end) { 839 continue; 840 } 841 842 start = start_offset[i]; 843 assert(start < end); 844 845 real_vb = &mgr->real_vertex_buffer[i]; 846 ptr = u_vbuf_resource(mgr->b.vertex_buffer[i].buffer)->user_ptr; 847 848 u_upload_data(mgr->b.uploader, start, end - start, ptr + start, 849 &real_vb->buffer_offset, &real_vb->buffer); 850 851 real_vb->buffer_offset -= start; 852 } 853} 854 855unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf *mgrb) 856{ 857 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; 858 unsigned i, nr = mgr->ve->count; 859 struct pipe_vertex_element *velems = 860 mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; 861 unsigned result = ~0; 862 863 for (i = 0; i < nr; i++) { 864 struct pipe_vertex_buffer *vb = 865 &mgr->real_vertex_buffer[velems[i].vertex_buffer_index]; 866 unsigned size, max_count, value; 867 868 /* We're not interested in constant and per-instance attribs. */ 869 if (!vb->buffer || 870 !vb->stride || 871 velems[i].instance_divisor) { 872 continue; 873 } 874 875 size = vb->buffer->width0; 876 877 /* Subtract buffer_offset. */ 878 value = vb->buffer_offset; 879 if (value >= size) { 880 return 0; 881 } 882 size -= value; 883 884 /* Subtract src_offset. */ 885 value = velems[i].src_offset; 886 if (value >= size) { 887 return 0; 888 } 889 size -= value; 890 891 /* Subtract format_size. */ 892 value = mgr->ve->native_format_size[i]; 893 if (value >= size) { 894 return 0; 895 } 896 size -= value; 897 898 /* Compute the max count. */ 899 max_count = 1 + size / vb->stride; 900 result = MIN2(result, max_count); 901 } 902 return result; 903} 904 905static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) 906{ 907 unsigned i, nr = mgr->ve->count; 908 909 for (i = 0; i < nr; i++) { 910 struct pipe_vertex_buffer *vb; 911 unsigned index; 912 913 /* Per-instance attribs don't need min/max_index. */ 914 if (mgr->ve->ve[i].instance_divisor) { 915 continue; 916 } 917 918 index = mgr->ve->ve[i].vertex_buffer_index; 919 vb = &mgr->b.vertex_buffer[index]; 920 921 /* Constant attribs don't need min/max_index. */ 922 if (!vb->stride) { 923 continue; 924 } 925 926 /* Per-vertex attribs need min/max_index. */ 927 if (u_vbuf_resource(vb->buffer)->user_ptr || 928 mgr->ve->incompatible_layout_elem[i] || 929 mgr->incompatible_vb[index]) { 930 return TRUE; 931 } 932 } 933 934 return FALSE; 935} 936 937static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf_priv *mgr) 938{ 939 unsigned i, nr = mgr->ve->count; 940 941 for (i = 0; i < nr; i++) { 942 struct pipe_vertex_buffer *vb; 943 unsigned index; 944 945 /* Per-instance attribs are not per-vertex data. */ 946 if (mgr->ve->ve[i].instance_divisor) { 947 continue; 948 } 949 950 index = mgr->ve->ve[i].vertex_buffer_index; 951 vb = &mgr->b.vertex_buffer[index]; 952 953 /* Constant attribs are not per-vertex data. */ 954 if (!vb->stride) { 955 continue; 956 } 957 958 /* Return true for the hw buffers which don't need to be translated. */ 959 /* XXX we could use some kind of a is-busy query. */ 960 if (!u_vbuf_resource(vb->buffer)->user_ptr && 961 !mgr->ve->incompatible_layout_elem[i] && 962 !mgr->incompatible_vb[index]) { 963 return TRUE; 964 } 965 } 966 967 return FALSE; 968} 969 970static void u_vbuf_get_minmax_index(struct pipe_context *pipe, 971 struct pipe_index_buffer *ib, 972 const struct pipe_draw_info *info, 973 int *out_min_index, 974 int *out_max_index) 975{ 976 struct pipe_transfer *transfer = NULL; 977 const void *indices; 978 unsigned i; 979 unsigned restart_index = info->restart_index; 980 981 if (u_vbuf_resource(ib->buffer)->user_ptr) { 982 indices = u_vbuf_resource(ib->buffer)->user_ptr + 983 ib->offset + info->start * ib->index_size; 984 } else { 985 indices = pipe_buffer_map_range(pipe, ib->buffer, 986 ib->offset + info->start * ib->index_size, 987 info->count * ib->index_size, 988 PIPE_TRANSFER_READ, &transfer); 989 } 990 991 switch (ib->index_size) { 992 case 4: { 993 const unsigned *ui_indices = (const unsigned*)indices; 994 unsigned max_ui = 0; 995 unsigned min_ui = ~0U; 996 if (info->primitive_restart) { 997 for (i = 0; i < info->count; i++) { 998 if (ui_indices[i] != restart_index) { 999 if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 1000 if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 1001 } 1002 } 1003 } 1004 else { 1005 for (i = 0; i < info->count; i++) { 1006 if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 1007 if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 1008 } 1009 } 1010 *out_min_index = min_ui; 1011 *out_max_index = max_ui; 1012 break; 1013 } 1014 case 2: { 1015 const unsigned short *us_indices = (const unsigned short*)indices; 1016 unsigned max_us = 0; 1017 unsigned min_us = ~0U; 1018 if (info->primitive_restart) { 1019 for (i = 0; i < info->count; i++) { 1020 if (us_indices[i] != restart_index) { 1021 if (us_indices[i] > max_us) max_us = us_indices[i]; 1022 if (us_indices[i] < min_us) min_us = us_indices[i]; 1023 } 1024 } 1025 } 1026 else { 1027 for (i = 0; i < info->count; i++) { 1028 if (us_indices[i] > max_us) max_us = us_indices[i]; 1029 if (us_indices[i] < min_us) min_us = us_indices[i]; 1030 } 1031 } 1032 *out_min_index = min_us; 1033 *out_max_index = max_us; 1034 break; 1035 } 1036 case 1: { 1037 const unsigned char *ub_indices = (const unsigned char*)indices; 1038 unsigned max_ub = 0; 1039 unsigned min_ub = ~0U; 1040 if (info->primitive_restart) { 1041 for (i = 0; i < info->count; i++) { 1042 if (ub_indices[i] != restart_index) { 1043 if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 1044 if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 1045 } 1046 } 1047 } 1048 else { 1049 for (i = 0; i < info->count; i++) { 1050 if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 1051 if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 1052 } 1053 } 1054 *out_min_index = min_ub; 1055 *out_max_index = max_ub; 1056 break; 1057 } 1058 default: 1059 assert(0); 1060 *out_min_index = 0; 1061 *out_max_index = 0; 1062 } 1063 1064 if (transfer) { 1065 pipe_buffer_unmap(pipe, transfer); 1066 } 1067} 1068 1069static void u_vbuf_draw_vbo(struct pipe_context *pipe, 1070 const struct pipe_draw_info *info) 1071{ 1072 struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; 1073 int start_vertex, min_index; 1074 unsigned num_vertices; 1075 bool unroll_indices = false; 1076 1077 /* Normal draw. No fallback and no user buffers. */ 1078 if (!mgr->incompatible_vb_layout && 1079 !mgr->ve->incompatible_layout && 1080 !mgr->any_user_vbs) { 1081 /* Set vertex buffers if needed. */ 1082 if (mgr->vertex_buffers_dirty) { 1083 mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers, 1084 mgr->real_vertex_buffer); 1085 mgr->vertex_buffers_dirty = FALSE; 1086 } 1087 1088 mgr->driver_draw_vbo(pipe, info); 1089 return; 1090 } 1091 1092 if (info->indexed) { 1093 int max_index; 1094 bool index_bounds_valid = false; 1095 1096 if (info->max_index != ~0) { 1097 min_index = info->min_index; 1098 max_index = info->max_index; 1099 index_bounds_valid = true; 1100 } else if (u_vbuf_need_minmax_index(mgr)) { 1101 u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info, 1102 &min_index, &max_index); 1103 index_bounds_valid = true; 1104 } 1105 1106 /* If the index bounds are valid, it means some upload or translation 1107 * of per-vertex attribs will be performed. */ 1108 if (index_bounds_valid) { 1109 assert(min_index <= max_index); 1110 1111 start_vertex = min_index + info->index_bias; 1112 num_vertices = max_index + 1 - min_index; 1113 1114 /* Primitive restart doesn't work when unrolling indices. 1115 * We would have to break this drawing operation into several ones. */ 1116 /* Use some heuristic to see if unrolling indices improves 1117 * performance. */ 1118 if (!info->primitive_restart && 1119 num_vertices > info->count*2 && 1120 num_vertices-info->count > 32 && 1121 !u_vbuf_mapping_vertex_buffer_blocks(mgr)) { 1122 /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/ 1123 unroll_indices = true; 1124 } 1125 } else { 1126 /* Nothing to do for per-vertex attribs. */ 1127 start_vertex = 0; 1128 num_vertices = 0; 1129 min_index = 0; 1130 } 1131 } else { 1132 start_vertex = info->start; 1133 num_vertices = info->count; 1134 min_index = 0; 1135 } 1136 1137 /* Translate vertices with non-native layouts or formats. */ 1138 if (unroll_indices || 1139 mgr->incompatible_vb_layout || 1140 mgr->ve->incompatible_layout) { 1141 /* XXX check the return value */ 1142 u_vbuf_translate_begin(mgr, start_vertex, num_vertices, 1143 info->start_instance, info->instance_count, 1144 info->start, info->count, min_index, 1145 unroll_indices); 1146 } 1147 1148 /* Upload user buffers. */ 1149 if (mgr->any_user_vbs) { 1150 u_vbuf_upload_buffers(mgr, start_vertex, num_vertices, 1151 info->start_instance, info->instance_count); 1152 } 1153 1154 /* 1155 if (unroll_indices) { 1156 printf("unrolling indices: start_vertex = %i, num_vertices = %i\n", 1157 start_vertex, num_vertices); 1158 util_dump_draw_info(stdout, info); 1159 printf("\n"); 1160 } 1161 1162 unsigned i; 1163 for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { 1164 printf("input %i: ", i); 1165 util_dump_vertex_buffer(stdout, mgr->b.vertex_buffer+i); 1166 printf("\n"); 1167 } 1168 for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { 1169 printf("real %i: ", i); 1170 util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i); 1171 printf("\n"); 1172 } 1173 */ 1174 1175 mgr->driver_set_vertex_buffers(mgr->pipe, mgr->nr_real_vertex_buffers, 1176 mgr->real_vertex_buffer); 1177 1178 if (unlikely(unroll_indices)) { 1179 struct pipe_draw_info new_info = *info; 1180 new_info.indexed = FALSE; 1181 new_info.index_bias = 0; 1182 new_info.min_index = 0; 1183 new_info.max_index = info->count - 1; 1184 new_info.start = 0; 1185 1186 mgr->driver_draw_vbo(pipe, &new_info); 1187 } else { 1188 mgr->driver_draw_vbo(pipe, info); 1189 } 1190 1191 if (mgr->fallback_ve) { 1192 u_vbuf_translate_end(mgr); 1193 } 1194 mgr->vertex_buffers_dirty = TRUE; 1195} 1196 1197static void u_vbuf_install(struct u_vbuf_priv *mgr) 1198{ 1199 struct pipe_context *pipe = mgr->pipe; 1200 assert(!pipe->draw); 1201 1202 pipe->draw = mgr; 1203 mgr->driver_set_index_buffer = pipe->set_index_buffer; 1204 mgr->driver_set_vertex_buffers = pipe->set_vertex_buffers; 1205 mgr->driver_create_vertex_elements_state = 1206 pipe->create_vertex_elements_state; 1207 mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state; 1208 mgr->driver_delete_vertex_elements_state = 1209 pipe->delete_vertex_elements_state; 1210 mgr->driver_draw_vbo = pipe->draw_vbo; 1211 1212 pipe->set_index_buffer = u_vbuf_set_index_buffer; 1213 pipe->set_vertex_buffers = u_vbuf_set_vertex_buffers; 1214 pipe->create_vertex_elements_state = u_vbuf_create_vertex_elements; 1215 pipe->bind_vertex_elements_state = u_vbuf_bind_vertex_elements; 1216 pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements; 1217 pipe->draw_vbo = u_vbuf_draw_vbo; 1218} 1219