u_vbuf.c revision 96863baa42564ce2daa5f4651f1c52f1d281d9a5
1975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák/**************************************************************************
2975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák *
3975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * Copyright 2011 Marek Olšák <maraeo@gmail.com>
4975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * All Rights Reserved.
5975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák *
6975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining a
7975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * copy of this software and associated documentation files (the
8975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * "Software"), to deal in the Software without restriction, including
9975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * without limitation the rights to use, copy, modify, merge, publish,
10975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * distribute, sub license, and/or sell copies of the Software, and to
11975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * permit persons to whom the Software is furnished to do so, subject to
12975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * the following conditions:
13975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák *
14975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * The above copyright notice and this permission notice (including the
15975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * next paragraph) shall be included in all copies or substantial portions
16975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * of the Software.
17975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák *
18975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
22975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák *
26975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák **************************************************************************/
27975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
28fba685a0995e76f86af5920163297e5c3b32fb4bMarek Olšák#include "util/u_vbuf.h"
29975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
305968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák#include "util/u_dump.h"
31975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "util/u_format.h"
32975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "util/u_inlines.h"
33975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "util/u_memory.h"
34975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "util/u_upload_mgr.h"
35975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "translate/translate.h"
36975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#include "translate/translate_cache.h"
37c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák#include "cso_cache/cso_cache.h"
38c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák#include "cso_cache/cso_hash.h"
39975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
4028fb79891101c23c75982726c81112caa96f9275Marek Olšákstruct u_vbuf_elements {
41975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned count;
42975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
43975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
4451095f74cf92d3cada7366ce898ade7693570b48Marek Olšák   unsigned src_format_size[PIPE_MAX_ATTRIBS];
4551095f74cf92d3cada7366ce898ade7693570b48Marek Olšák
4651095f74cf92d3cada7366ce898ade7693570b48Marek Olšák   /* If (velem[i].src_format != native_format[i]), the vertex buffer
47975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    * referenced by the vertex element cannot be used for rendering and
4851095f74cf92d3cada7366ce898ade7693570b48Marek Olšák    * its vertex data must be translated to native_format[i]. */
49975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   enum pipe_format native_format[PIPE_MAX_ATTRIBS];
50975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned native_format_size[PIPE_MAX_ATTRIBS];
51975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
52975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* This might mean two things:
53975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    * - src_format != native_format, as discussed above.
54975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    * - src_offset % 4 != 0 (if the caps don't allow such an offset). */
55b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t incompatible_elem_mask; /* each bit describes a corresp. attrib  */
56b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has at least one vertex element referencing it
57b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * incompatible. */
58b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t incompatible_vb_mask_any;
59b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has all vertex elements referencing it incompatible. */
60b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t incompatible_vb_mask_all;
61b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has at least one vertex element referencing it
62b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * compatible. */
63b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t compatible_vb_mask_any;
64b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has all vertex elements referencing it compatible. */
65b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t compatible_vb_mask_all;
66b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
67b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has at least one vertex element referencing it
68b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * non-instanced. */
69b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t noninstance_vb_mask_any;
70889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák
71889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák   void *driver_cso;
72975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák};
73975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
745968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákenum {
755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   VB_VERTEX = 0,
765968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   VB_INSTANCE = 1,
775968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   VB_CONST = 2,
785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   VB_NUM = 3
795968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák};
805968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
81e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstruct u_vbuf {
827fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   struct u_vbuf_caps caps;
83e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
84975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   struct pipe_context *pipe;
85975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   struct translate_cache *translate_cache;
86c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   struct cso_cache *cso_cache;
87e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct u_upload_mgr *uploader;
88e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
89e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   /* This is what was set in set_vertex_buffers.
90e0773da1e897164ed7597437070e32b867734ee5Marek Olšák    * May contain user buffers. */
91e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
92e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned nr_vertex_buffers;
93e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
94e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   /* Saved vertex buffers. */
95e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_vertex_buffer vertex_buffer_saved[PIPE_MAX_ATTRIBS];
96e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned nr_vertex_buffers_saved;
97975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
982d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   /* Vertex buffers for the driver.
992d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák    * There are no user buffers. */
1002d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS];
1012d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   int nr_real_vertex_buffers;
1025ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   boolean vertex_buffers_dirty;
1032d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák
10431714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák   /* The index buffer. */
10531714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák   struct pipe_index_buffer index_buffer;
10631714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
107e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   /* Vertex elements. */
108e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct u_vbuf_elements *ve, *ve_saved;
109df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák
110df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák   /* Vertex elements used for the translate fallback. */
111df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák   struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS];
112b5b7cc19d82c8761a6b56268aecdccbc1ed2f911Marek Olšák   /* If non-NULL, this is a vertex element state used for the translate
113b5b7cc19d82c8761a6b56268aecdccbc1ed2f911Marek Olšák    * fallback and therefore used for rendering too. */
114e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   boolean using_translate;
115b5b7cc19d82c8761a6b56268aecdccbc1ed2f911Marek Olšák   /* The vertex buffer slot index where translated vertices have been
116b5b7cc19d82c8761a6b56268aecdccbc1ed2f911Marek Olšák    * stored in. */
1175968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned fallback_vbs[VB_NUM];
118975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
119b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer is a user buffer. */
120b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t user_vb_mask; /* each bit describes a corresp. buffer */
121b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer is incompatible (unaligned). */
122b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t incompatible_vb_mask; /* each bit describes a corresp. buffer */
123b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Which buffer has a non-zero stride. */
124b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t nonzero_stride_vb_mask; /* each bit describes a corresp. buffer */
125975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák};
126975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
127e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void *
128e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
129e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                              const struct pipe_vertex_element *attribs);
130e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso);
131e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
132e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1337fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšákvoid u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
134975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
1357fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->format_fixed32 =
136975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
137e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER);
138975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1397fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->format_float16 =
140975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
141e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER);
142975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1437fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->format_float64 =
144975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
145e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER);
146975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1477fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->format_norm32 =
148975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
149e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER) &&
150975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
151e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER);
152975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1537fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->format_scaled32 =
154975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
155e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER) &&
156975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
157e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                  0, PIPE_BIND_VERTEX_BUFFER);
1587fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák
159eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák   caps->buffer_offset_unaligned =
1607fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      !screen->get_param(screen,
161eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák                        PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY);
162eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák
163eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák   caps->buffer_stride_unaligned =
1647fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      !screen->get_param(screen,
165eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák                        PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY);
166eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák
167eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák   caps->velem_src_offset_unaligned =
1687fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      !screen->get_param(screen,
1697fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák                        PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY);
1707fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák
1717fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   caps->user_vertex_buffers =
1727fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
173975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
174975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
175fba685a0995e76f86af5920163297e5c3b32fb4bMarek Olšákstruct u_vbuf *
17628fb79891101c23c75982726c81112caa96f9275Marek Olšáku_vbuf_create(struct pipe_context *pipe,
177e0773da1e897164ed7597437070e32b867734ee5Marek Olšák              struct u_vbuf_caps *caps)
178975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
179e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf);
180975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1817fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák   mgr->caps = *caps;
182975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   mgr->pipe = pipe;
183c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   mgr->cso_cache = cso_cache_create();
184975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   mgr->translate_cache = translate_cache_create();
1855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
186975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
187e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4,
188e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                   PIPE_BIND_VERTEX_BUFFER);
189975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
190e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   return mgr;
191975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
192975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
193e0773da1e897164ed7597437070e32b867734ee5Marek Olšák/* u_vbuf uses its own caching for vertex elements, because it needs to keep
194e0773da1e897164ed7597437070e32b867734ee5Marek Olšák * its own preprocessed state per vertex element CSO. */
195e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic struct u_vbuf_elements *
196e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count,
197e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                    const struct pipe_vertex_element *states)
198c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák{
199e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
200c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   unsigned key_size, hash_key;
201c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   struct cso_hash_iter iter;
202e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct u_vbuf_elements *ve;
203c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   struct cso_velems_state velems_state;
204c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
205c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   /* need to include the count into the stored state data too. */
206c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
207c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   velems_state.count = count;
208c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   memcpy(velems_state.velems, states,
209c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák          sizeof(struct pipe_vertex_element) * count);
210c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   hash_key = cso_construct_key((void*)&velems_state, key_size);
211c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   iter = cso_find_state_template(mgr->cso_cache, hash_key, CSO_VELEMENTS,
212c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák                                  (void*)&velems_state, key_size);
213c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
214c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   if (cso_hash_iter_is_null(iter)) {
215c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák      struct cso_velements *cso = MALLOC_STRUCT(cso_velements);
216c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák      memcpy(&cso->state, &velems_state, key_size);
217e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      cso->data = u_vbuf_create_vertex_elements(mgr, count, states);
218e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements;
219e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      cso->context = (void*)mgr;
220c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
221c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák      iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso);
222e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      ve = cso->data;
223c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   } else {
224e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      ve = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
225c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   }
226c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
227e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   assert(ve);
228e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->bind_vertex_elements_state(pipe, ve->driver_cso);
229e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   return ve;
230c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák}
231c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
232e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count,
233e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                               const struct pipe_vertex_element *states)
234975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
235e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve = u_vbuf_set_vertex_elements_internal(mgr, count, states);
236e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
237975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
238e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_destroy(struct u_vbuf *mgr)
239e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
240e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned i;
24131714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
24218bcb962bbad451a5e34f0315f03b8fb4533ea73Marek Olšák   mgr->pipe->set_vertex_buffers(mgr->pipe, 0, NULL);
24318bcb962bbad451a5e34f0315f03b8fb4533ea73Marek Olšák
244e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
245e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
2460b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák   }
2472d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
2482d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
249975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
250975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
251975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   translate_cache_destroy(mgr->translate_cache);
252e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_upload_destroy(mgr->uploader);
253c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   cso_cache_delete(mgr->cso_cache);
254975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   FREE(mgr);
255975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
256975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
2575968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákstatic void
258e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
2592b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák                         unsigned vb_mask, unsigned out_vb,
260ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                         int start_vertex, unsigned num_vertices,
261ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                         int start_index, unsigned num_indices, int min_index,
262e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                         boolean unroll_indices)
2635968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák{
2645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct translate *tr;
2655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
2665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct pipe_resource *out_buffer = NULL;
2675968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   uint8_t *out_map;
2685968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned i, out_offset;
2695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2705968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Get a translate object. */
2715968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   tr = translate_cache_find(mgr->translate_cache, key);
2725968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Map buffers we want to translate. */
274e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
2755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb_mask & (1 << i)) {
276e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[i];
2772b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák         unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
2785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         uint8_t *map;
2795968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2804552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák         if (vb->user_buffer) {
2814552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák            map = (uint8_t*)vb->user_buffer + offset;
2825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         } else {
2832b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák            unsigned size = vb->stride ? num_vertices * vb->stride
2845968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                       : sizeof(double)*4;
2855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2865968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            if (offset+size > vb->buffer->width0) {
2875968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák               size = vb->buffer->width0 - offset;
2885968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            }
289975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
2905968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size,
2915968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                        PIPE_TRANSFER_READ, &vb_transfer[i]);
2925968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
2935968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
294ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Subtract min_index so that indexing with the index buffer works. */
295ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (unroll_indices) {
296ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            map -= vb->stride * min_index;
297ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
298ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
2995968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         tr->set_buffer(tr, i, map, vb->stride, ~0);
3005968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
3015968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
3025968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
303ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   /* Translate. */
304ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices) {
30531714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák      struct pipe_index_buffer *ib = &mgr->index_buffer;
306ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      struct pipe_transfer *transfer = NULL;
307ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      unsigned offset = ib->offset + start_index * ib->index_size;
308ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      uint8_t *map;
3095968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
310bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      assert((ib->buffer || ib->user_buffer) && ib->index_size);
3115968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
312bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      if (ib->user_buffer) {
313bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák         map = (uint8_t*)ib->user_buffer + offset;
314ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      } else {
315ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset,
316ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                     num_indices * ib->index_size,
317ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                     PIPE_TRANSFER_READ, &transfer);
318ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
319ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
320ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      /* Create and map the output buffer. */
321e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      u_upload_alloc(mgr->uploader, 0,
322ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     key->output_stride * num_indices,
323ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     &out_offset, &out_buffer,
324ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     (void**)&out_map);
325ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
326ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      switch (ib->index_size) {
327ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 4:
328ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts(tr, (unsigned*)map, num_indices, 0, out_map);
329ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
330ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 2:
331ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts16(tr, (uint16_t*)map, num_indices, 0, out_map);
332ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
333ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 1:
334ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts8(tr, map, num_indices, 0, out_map);
335ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
336ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
337ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
338ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      if (transfer) {
339ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         pipe_buffer_unmap(mgr->pipe, transfer);
340ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
341ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   } else {
342ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      /* Create and map the output buffer. */
343e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      u_upload_alloc(mgr->uploader,
344ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     key->output_stride * start_vertex,
345ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     key->output_stride * num_vertices,
346ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     &out_offset, &out_buffer,
347ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                     (void**)&out_map);
348ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
349ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      out_offset -= key->output_stride * start_vertex;
350ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
351ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      tr->run(tr, 0, num_vertices, 0, out_map);
352ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
3535968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3545968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Unmap all buffers. */
355e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
3565968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb_transfer[i]) {
3575968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
3585968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
3595968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
3605968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3615968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Setup the new vertex buffer. */
3622d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].buffer_offset = out_offset;
3632d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].stride = key->output_stride;
3645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Move the buffer reference. */
3665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   pipe_resource_reference(
3672d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      &mgr->real_vertex_buffer[out_vb].buffer, NULL);
3682d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].buffer = out_buffer;
3695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák}
3705968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3715968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákstatic boolean
372e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
3735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                    unsigned mask[VB_NUM])
374611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák{
3756fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   unsigned type;
3765968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned fallback_vbs[VB_NUM];
3776fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   /* Set the bit for each buffer which is incompatible, or isn't set. */
3786fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   uint32_t unused_vb_mask =
3796fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák      mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
3806fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák      ~((1 << mgr->nr_vertex_buffers) - 1);
3815968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(fallback_vbs, ~0, sizeof(fallback_vbs));
383611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
3845968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Find free slots for each type if needed. */
3855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (type = 0; type < VB_NUM; type++) {
3865968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (mask[type]) {
3876fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         uint32_t index;
3886fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák
3896fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         if (!unused_vb_mask) {
3905968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            /* fail, reset the number to its original value */
391e0773da1e897164ed7597437070e32b867734ee5Marek Olšák            mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
3925968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            return FALSE;
393611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák         }
3946fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák
3956fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         index = ffs(unused_vb_mask) - 1;
3966fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         fallback_vbs[type] = index;
3976fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         if (index >= mgr->nr_real_vertex_buffers) {
3986fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák            mgr->nr_real_vertex_buffers = index + 1;
3996fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         }
4006fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         /*printf("found slot=%i for type=%i\n", index, type);*/
401611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      }
402611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
4035968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4045968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memcpy(mgr->fallback_vbs, fallback_vbs, sizeof(fallback_vbs));
4055968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   return TRUE;
406611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák}
407611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4085968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákstatic boolean
409e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_begin(struct u_vbuf *mgr,
410c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                       int start_vertex, unsigned num_vertices,
411ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                       int start_instance, unsigned num_instances,
412ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                       int start_index, unsigned num_indices, int min_index,
413e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                       boolean unroll_indices)
414975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
4155968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned mask[VB_NUM] = {0};
4165968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct translate_key key[VB_NUM];
4175968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned elem_index[VB_NUM][PIPE_MAX_ATTRIBS]; /* ... into key.elements */
4185968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned i, type;
4195968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
420c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák   int start[VB_NUM] = {
421c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      start_vertex,     /* VERTEX */
4225968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      start_instance,   /* INSTANCE */
4235968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      0                 /* CONST */
4245968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   };
4255968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4262b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák   unsigned num[VB_NUM] = {
427c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      num_vertices,     /* VERTEX */
428c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      num_instances,    /* INSTANCE */
429c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      1                 /* CONST */
4305968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   };
4315968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4325968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(key, 0, sizeof(key));
4335968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(elem_index, ~0, sizeof(elem_index));
4345968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4355968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* See if there are vertex attribs of each type to translate and
4365968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák    * which ones. */
4375968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (i = 0; i < mgr->ve->count; i++) {
4385968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index;
439975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
440e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      if (!mgr->vertex_buffer[vb_index].stride) {
441b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
442b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
443ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
444ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4455968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_CONST] |= 1 << vb_index;
4465968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      } else if (mgr->ve->ve[i].instance_divisor) {
447b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
448b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
449ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
450ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4515968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_INSTANCE] |= 1 << vb_index;
4525968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      } else {
453ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (!unroll_indices &&
454b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->ve->incompatible_elem_mask & (1 << i)) &&
455b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
456ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
457ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4585968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_VERTEX] |= 1 << vb_index;
4595968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
4605968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
461611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4625968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]);
4635968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Find free vertex buffer slots. */
4655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) {
4665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      return FALSE;
467611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
468611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Initialize the translate keys. */
470975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < mgr->ve->count; i++) {
4715968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      struct translate_key *k;
4725968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      struct translate_element *te;
4735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned bit, vb_index = mgr->ve->ve[i].vertex_buffer_index;
474ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      bit = 1 << vb_index;
475975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
476b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
477b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák          !(mgr->incompatible_vb_mask & (1 << vb_index)) &&
478ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          (!unroll_indices || !(mask[VB_VERTEX] & bit))) {
479975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
480975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
481975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
4825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Set type to what we will translate.
4835968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák       * Whether vertex, instance, or constant attribs. */
4845968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      for (type = 0; type < VB_NUM; type++) {
4855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (mask[type] & bit) {
4865968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            break;
4875968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
4885968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
4895968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      assert(type < VB_NUM);
4905968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      assert(translate_is_output_format_supported(mgr->ve->native_format[i]));
4915968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /*printf("velem=%i type=%i\n", i, type);*/
4925968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4935968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Add the vertex element. */
4945968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k = &key[type];
4955968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      elem_index[type][i] = k->nr_elements;
496975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
4975968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te = &k->element[k->nr_elements];
498611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      te->type = TRANSLATE_ELEMENT_NORMAL;
499611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      te->instance_divisor = 0;
5005968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->input_buffer = vb_index;
501975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      te->input_format = mgr->ve->ve[i].src_format;
502975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      te->input_offset = mgr->ve->ve[i].src_offset;
5035968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->output_format = mgr->ve->native_format[i];
5045968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->output_offset = k->output_stride;
505975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5065968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k->output_stride += mgr->ve->native_format_size[i];
5075968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k->nr_elements++;
508975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
509975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5105968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Translate buffers. */
5115968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (type = 0; type < VB_NUM; type++) {
5125968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (key[type].nr_elements) {
5135968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         u_vbuf_translate_buffers(mgr, &key[type], mask[type],
5145968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                  mgr->fallback_vbs[type],
515ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                  start[type], num[type],
516ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                  start_index, num_indices, min_index,
517ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                  unroll_indices && type == VB_VERTEX);
518975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5195968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         /* Fixup the stride for constant attribs. */
5205968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (type == VB_CONST) {
5212d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák            mgr->real_vertex_buffer[mgr->fallback_vbs[VB_CONST]].stride = 0;
522c727cc175bcbf96f12f27c46819667948d5ebbe2Marek Olšák         }
523975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
524975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
525975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
526611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   /* Setup new vertex elements. */
527611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   for (i = 0; i < mgr->ve->count; i++) {
5285968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      for (type = 0; type < VB_NUM; type++) {
5295968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (elem_index[type][i] < key[type].nr_elements) {
5305968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            struct translate_element *te = &key[type].element[elem_index[type][i]];
5315968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor;
5325968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].src_format = te->output_format;
5335968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].src_offset = te->output_offset;
5345968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].vertex_buffer_index = mgr->fallback_vbs[type];
5355968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
5365968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            /* elem_index[type][i] can only be set for one type. */
5375968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            assert(type > VB_INSTANCE || elem_index[type+1][i] == ~0);
5385968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            assert(type > VB_VERTEX   || elem_index[type+2][i] == ~0);
5395968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            break;
5405968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
5415968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
5425968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* No translating, just copy the original vertex element over. */
5435968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (type == VB_NUM) {
544611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák         memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i],
545611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák                sizeof(struct pipe_vertex_element));
546975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
547611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
548975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
549e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count,
550e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                       mgr->fallback_velems);
551e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->using_translate = TRUE;
5525968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   return TRUE;
553975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
554975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
555e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void u_vbuf_translate_end(struct u_vbuf *mgr)
556975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
5575968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned i;
5585968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
559975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Restore vertex elements. */
560e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
561e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->using_translate = FALSE;
562975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5635968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Unreference the now-unused VBOs. */
5645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (i = 0; i < VB_NUM; i++) {
5655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned vb = mgr->fallback_vbs[i];
5665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb != ~0) {
5672d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák         pipe_resource_reference(&mgr->real_vertex_buffer[vb].buffer, NULL);
5685968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mgr->fallback_vbs[i] = ~0;
5695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
5705968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
571e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
572975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
573975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
574975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#define FORMAT_REPLACE(what, withwhat) \
575975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
576975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
577889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšákstatic void *
578e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
579889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák                              const struct pipe_vertex_element *attribs)
580975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
581e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
582975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned i;
583039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák   struct pipe_vertex_element driver_attribs[PIPE_MAX_ATTRIBS];
58428fb79891101c23c75982726c81112caa96f9275Marek Olšák   struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements);
585b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t used_buffers = 0;
586975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
587975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   ve->count = count;
588975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
589975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count);
590039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák   memcpy(driver_attribs, attribs, sizeof(struct pipe_vertex_element) * count);
591975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
592975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Set the best native format in case the original format is not
593975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    * supported. */
594975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < count; i++) {
595975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      enum pipe_format format = ve->ve[i].src_format;
596975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
59751095f74cf92d3cada7366ce898ade7693570b48Marek Olšák      ve->src_format_size[i] = util_format_get_blocksize(format);
59851095f74cf92d3cada7366ce898ade7693570b48Marek Olšák
599b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      used_buffers |= 1 << ve->ve[i].vertex_buffer_index;
600b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
601b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (!ve->ve[i].instance_divisor) {
602b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->noninstance_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
603b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
604b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
605975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      /* Choose a native format.
606975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák       * For now we don't care about the alignment, that's going to
607975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák       * be sorted out later. */
6087fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_fixed32) {
609975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
610975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_FIXED,           R32_FLOAT);
611975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_FIXED,        R32G32_FLOAT);
612975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_FIXED,     R32G32B32_FLOAT);
613975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_FIXED,  R32G32B32A32_FLOAT);
614975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
615975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
616975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6177fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_float16) {
618975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
619975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16_FLOAT,           R32_FLOAT);
620975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16_FLOAT,        R32G32_FLOAT);
621975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16B16_FLOAT,     R32G32B32_FLOAT);
622975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16B16A16_FLOAT,  R32G32B32A32_FLOAT);
623975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
624975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
625975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6267fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_float64) {
627975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
628975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64_FLOAT,           R32_FLOAT);
629975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64_FLOAT,        R32G32_FLOAT);
630975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64B64_FLOAT,     R32G32B32_FLOAT);
631975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64B64A64_FLOAT,  R32G32B32A32_FLOAT);
632975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
633975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
634975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6357fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_norm32) {
636975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
637975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_UNORM,           R32_FLOAT);
638975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_UNORM,        R32G32_FLOAT);
639975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_UNORM,     R32G32B32_FLOAT);
640975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_UNORM,  R32G32B32A32_FLOAT);
641975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_SNORM,           R32_FLOAT);
642975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_SNORM,        R32G32_FLOAT);
643975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_SNORM,     R32G32B32_FLOAT);
644975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_SNORM,  R32G32B32A32_FLOAT);
645975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
646975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
647975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6487fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_scaled32) {
649975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
650975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_USCALED,         R32_FLOAT);
651975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_USCALED,      R32G32_FLOAT);
652975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_USCALED,   R32G32B32_FLOAT);
653975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
654975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_SSCALED,         R32_FLOAT);
655975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_SSCALED,      R32G32_FLOAT);
656975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_SSCALED,   R32G32B32_FLOAT);
657975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
658975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
659975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
660975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
661975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
662039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák      driver_attribs[i].src_format = format;
663975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      ve->native_format[i] = format;
664975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      ve->native_format_size[i] =
665975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            util_format_get_blocksize(ve->native_format[i]);
666975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
667b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (ve->ve[i].src_format != format ||
668b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák          (!mgr->caps.velem_src_offset_unaligned &&
669b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           ve->ve[i].src_offset % 4 != 0)) {
670b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->incompatible_elem_mask |= 1 << i;
671b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->incompatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
672b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      } else {
673b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->compatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
674b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
675975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
676975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
677b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers;
678b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers;
679b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
680975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Align the formats to the size of DWORD if needed. */
681eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák   if (!mgr->caps.velem_src_offset_unaligned) {
682975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      for (i = 0; i < count; i++) {
683975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         ve->native_format_size[i] = align(ve->native_format_size[i], 4);
684975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
685975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
686975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
687889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák   ve->driver_cso =
688039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák      pipe->create_vertex_elements_state(pipe, count, driver_attribs);
689975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   return ve;
690975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
691975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
692e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso)
693975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
694e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
695889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák   struct u_vbuf_elements *ve = cso;
696889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák
697e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->delete_vertex_elements_state(pipe, ve->driver_cso);
698975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   FREE(ve);
699975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
700975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
701e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
702e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                               const struct pipe_vertex_buffer *bufs)
703975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
704975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned i;
705975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
706b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->user_vb_mask = 0;
707b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->incompatible_vb_mask = 0;
708b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->nonzero_stride_vb_mask = 0;
709975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
710975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < count; i++) {
711975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      const struct pipe_vertex_buffer *vb = &bufs[i];
712a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      struct pipe_vertex_buffer *orig_vb = &mgr->vertex_buffer[i];
713a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
714975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
715a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      pipe_resource_reference(&orig_vb->buffer, vb->buffer);
7164552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      orig_vb->user_buffer = vb->user_buffer;
7170b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák
718a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
719a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      real_vb->stride = orig_vb->stride = vb->stride;
72096863baa42564ce2daa5f4651f1c52f1d281d9a5Marek Olšák      real_vb->user_buffer = NULL;
7210b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák
722b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (vb->stride) {
723b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->nonzero_stride_vb_mask |= 1 << i;
724b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
725b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
7264552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!vb->buffer && !vb->user_buffer) {
727a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
728a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         continue;
729a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      }
730975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
731eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák      if ((!mgr->caps.buffer_offset_unaligned && vb->buffer_offset % 4 != 0) ||
732eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák          (!mgr->caps.buffer_stride_unaligned && vb->stride % 4 != 0)) {
733b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->incompatible_vb_mask |= 1 << i;
734a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
735975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
736975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
737975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
7384552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
739b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->user_vb_mask |= 1 << i;
740a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
741975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
742975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
743975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
744a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      pipe_resource_reference(&real_vb->buffer, vb->buffer);
74596863baa42564ce2daa5f4651f1c52f1d281d9a5Marek Olšák      real_vb->user_buffer = vb->user_buffer;
746975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
747975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
748e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = count; i < mgr->nr_vertex_buffers; i++) {
749e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
750975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
7512d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = count; i < mgr->nr_real_vertex_buffers; i++) {
7522d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
7530b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák   }
754975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
755e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_vertex_buffers = count;
7562d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->nr_real_vertex_buffers = count;
7575ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   mgr->vertex_buffers_dirty = TRUE;
758975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
759975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
760e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_index_buffer(struct u_vbuf *mgr,
761e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                             const struct pipe_index_buffer *ib)
7624cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák{
763e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
76431714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
765bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák   if (ib) {
7664cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      assert(ib->offset % ib->index_size == 0);
7674cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer);
768bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      memcpy(&mgr->index_buffer, ib, sizeof(*ib));
7694cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák   } else {
7704cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
7714cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák   }
77231714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
773e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->set_index_buffer(pipe, ib);
7744cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák}
7754cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák
776315300e4443f7a2177f2d8c4435f30c9bf95504dMarek Olšákstatic void
777e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_upload_buffers(struct u_vbuf *mgr,
778c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                      int start_vertex, unsigned num_vertices,
779c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                      int start_instance, unsigned num_instances)
780975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
781cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned i;
782cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned nr_velems = mgr->ve->count;
783e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned nr_vbufs = mgr->nr_vertex_buffers;
784df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák   struct pipe_vertex_element *velems =
785e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve;
786cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned start_offset[PIPE_MAX_ATTRIBS];
787cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned end_offset[PIPE_MAX_ATTRIBS] = {0};
788cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
789cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   /* Determine how much data needs to be uploaded. */
790cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   for (i = 0; i < nr_velems; i++) {
791df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák      struct pipe_vertex_element *velem = &velems[i];
792cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      unsigned index = velem->vertex_buffer_index;
793e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index];
79421f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      unsigned instance_div, first, size;
795975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
7965968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Skip the buffers generated by translate. */
7975968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (index == mgr->fallback_vbs[VB_VERTEX] ||
7985968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák          index == mgr->fallback_vbs[VB_INSTANCE] ||
7995968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák          index == mgr->fallback_vbs[VB_CONST]) {
800df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák         continue;
801df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák      }
802df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák
8034552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!vb->user_buffer) {
804cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         continue;
805cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
806975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
80721f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      instance_div = velem->instance_divisor;
808cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      first = vb->buffer_offset + velem->src_offset;
809975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
810cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!vb->stride) {
811cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Constant attrib. */
812cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         size = mgr->ve->src_format_size[i];
813cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      } else if (instance_div) {
814cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Per-instance attrib. */
815c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         unsigned count = (num_instances + instance_div - 1) / instance_div;
816dbd60d27e8087a3bacf36d4eceef15dc4fcdcceeMarek Olšák         first += vb->stride * start_instance;
817cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         size = vb->stride * (count - 1) + mgr->ve->src_format_size[i];
818cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      } else {
819cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Per-vertex attrib. */
820c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         first += vb->stride * start_vertex;
821c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         size = vb->stride * (num_vertices - 1) + mgr->ve->src_format_size[i];
822cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
823975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
824cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      /* Update offsets. */
825cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!end_offset[index]) {
826cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         start_offset[index] = first;
827cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         end_offset[index] = first + size;
828975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      } else {
829cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         if (first < start_offset[index])
830cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák            start_offset[index] = first;
831cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         if (first + size > end_offset[index])
832cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák            end_offset[index] = first + size;
833975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
834975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
835cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
836cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   /* Upload buffers. */
837cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   for (i = 0; i < nr_vbufs; i++) {
83821f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      unsigned start, end = end_offset[i];
83921f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      struct pipe_vertex_buffer *real_vb;
8404552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      const uint8_t *ptr;
841cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
842cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!end) {
843cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         continue;
844cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
84521f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák
84621f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      start = start_offset[i];
847cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      assert(start < end);
848cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
8492d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      real_vb = &mgr->real_vertex_buffer[i];
8504552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      ptr = mgr->vertex_buffer[i].user_buffer;
85121f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák
852e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      u_upload_data(mgr->uploader, start, end - start, ptr + start,
853f94d390213308d4aca1515c75acc6865ebb45796Marek Olšák                    &real_vb->buffer_offset, &real_vb->buffer);
854cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
85521f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      real_vb->buffer_offset -= start;
856cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   }
857975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
858975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
859e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic boolean u_vbuf_need_minmax_index(struct u_vbuf *mgr)
86072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák{
861b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* See if there are any per-vertex attribs which will be uploaded or
862b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * translated. Use bitmasks to get the info instead of looping over vertex
863b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * elements. */
864b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   return ((mgr->user_vb_mask | mgr->incompatible_vb_mask |
865b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            mgr->ve->incompatible_vb_mask_any) &
866b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->ve->noninstance_vb_mask_any & mgr->nonzero_stride_vb_mask) != 0;
86772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák}
86872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
869e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr)
8702bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák{
871b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Return true if there are hw buffers which don't need to be translated.
872b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    *
873b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * We could query whether each buffer is busy, but that would
874b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * be way more costly than this. */
875b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   return (~mgr->user_vb_mask & ~mgr->incompatible_vb_mask &
876b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->ve->compatible_vb_mask_all & mgr->ve->noninstance_vb_mask_any &
877b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->nonzero_stride_vb_mask) != 0;
8782bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák}
8792bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák
88072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšákstatic void u_vbuf_get_minmax_index(struct pipe_context *pipe,
88172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    struct pipe_index_buffer *ib,
88272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    const struct pipe_draw_info *info,
88372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    int *out_min_index,
88472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    int *out_max_index)
88572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák{
88672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   struct pipe_transfer *transfer = NULL;
88772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   const void *indices;
88872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   unsigned i;
88972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   unsigned restart_index = info->restart_index;
89072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
891bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák   if (ib->user_buffer) {
892bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      indices = (uint8_t*)ib->user_buffer +
89372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                ib->offset + info->start * ib->index_size;
89472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   } else {
89572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      indices = pipe_buffer_map_range(pipe, ib->buffer,
89672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      ib->offset + info->start * ib->index_size,
89772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      info->count * ib->index_size,
89872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      PIPE_TRANSFER_READ, &transfer);
89972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
90072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
90172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   switch (ib->index_size) {
90272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 4: {
90372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned *ui_indices = (const unsigned*)indices;
90472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_ui = 0;
90572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_ui = ~0U;
90672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
90772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
90872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] != restart_index) {
90972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
91072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
91172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
91272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
91372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
91472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
91572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
91672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
91772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
91872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
91972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
92072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_ui;
92172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_ui;
92272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
92372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
92472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 2: {
92572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned short *us_indices = (const unsigned short*)indices;
92672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_us = 0;
92772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_us = ~0U;
92872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
92972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
93072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] != restart_index) {
93172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (us_indices[i] > max_us) max_us = us_indices[i];
93272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (us_indices[i] < min_us) min_us = us_indices[i];
93372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
93472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
93572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
93672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
93772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
93872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] > max_us) max_us = us_indices[i];
93972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] < min_us) min_us = us_indices[i];
94072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
94172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
94272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_us;
94372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_us;
94472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
94572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
94672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 1: {
94772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned char *ub_indices = (const unsigned char*)indices;
94872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_ub = 0;
94972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_ub = ~0U;
95072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
95172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
95272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] != restart_index) {
95372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
95472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
95572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
95672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
95772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
95872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
95972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
96072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
96172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
96272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
96372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
96472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_ub;
96572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_ub;
96672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
96772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
96872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   default:
96972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      assert(0);
970de93347d482a96f88c898622c9620f03e677e386Vinson Lee      *out_min_index = 0;
971de93347d482a96f88c898622c9620f03e677e386Vinson Lee      *out_max_index = 0;
97272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
97372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
97472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   if (transfer) {
97572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      pipe_buffer_unmap(pipe, transfer);
97672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
97772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák}
97872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
979e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
980975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
981e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
982ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   int start_vertex, min_index;
98364242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák   unsigned num_vertices;
984e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   boolean unroll_indices = FALSE;
98589c488871056185b8633aae7e7573b398827b038Marek Olšák   uint32_t user_vb_mask = mgr->user_vb_mask;
986975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
9875ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   /* Normal draw. No fallback and no user buffers. */
988b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   if (!mgr->incompatible_vb_mask &&
989b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       !mgr->ve->incompatible_elem_mask &&
99089c488871056185b8633aae7e7573b398827b038Marek Olšák       !user_vb_mask) {
9915ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      /* Set vertex buffers if needed. */
9925ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      if (mgr->vertex_buffers_dirty) {
993e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
994e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                  mgr->real_vertex_buffer);
9955ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák         mgr->vertex_buffers_dirty = FALSE;
9965ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      }
9975ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák
998e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, info);
9992d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      return;
100072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
100172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
100260a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák   if (info->indexed) {
1003b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      /* See if anything needs to be done for per-vertex attribs. */
1004b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (u_vbuf_need_minmax_index(mgr)) {
1005b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         int max_index;
1006b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
1007b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (info->max_index != ~0) {
1008b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            min_index = info->min_index;
1009b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            max_index = info->max_index;
1010b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         } else {
1011b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
1012b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák                                    &min_index, &max_index);
1013b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         }
101464242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák
101564242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         assert(min_index <= max_index);
101664242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák
101764242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         start_vertex = min_index + info->index_bias;
101864242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         num_vertices = max_index + 1 - min_index;
1019ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1020ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Primitive restart doesn't work when unrolling indices.
1021ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          * We would have to break this drawing operation into several ones. */
1022ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Use some heuristic to see if unrolling indices improves
1023ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          * performance. */
1024ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (!info->primitive_restart &&
1025ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák             num_vertices > info->count*2 &&
10262bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák             num_vertices-info->count > 32 &&
10272bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák             !u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
1028ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
1029e0773da1e897164ed7597437070e32b867734ee5Marek Olšák            unroll_indices = TRUE;
103089c488871056185b8633aae7e7573b398827b038Marek Olšák            user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
103189c488871056185b8633aae7e7573b398827b038Marek Olšák                              mgr->ve->noninstance_vb_mask_any);
1032ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
103360a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák      } else {
103464242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         /* Nothing to do for per-vertex attribs. */
103564242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         start_vertex = 0;
103664242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         num_vertices = 0;
103772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         min_index = 0;
103860a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák      }
1039a0d154dc1385d92a31dca8e65e50d958bdf6d532Marek Olšák   } else {
104064242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      start_vertex = info->start;
104164242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      num_vertices = info->count;
1042ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      min_index = 0;
1043a0d154dc1385d92a31dca8e65e50d958bdf6d532Marek Olšák   }
1044975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1045975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Translate vertices with non-native layouts or formats. */
1046ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices ||
1047b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       mgr->incompatible_vb_mask ||
1048b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       mgr->ve->incompatible_elem_mask) {
10495968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* XXX check the return value */
105064242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      u_vbuf_translate_begin(mgr, start_vertex, num_vertices,
1051ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                             info->start_instance, info->instance_count,
1052ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                             info->start, info->count, min_index,
1053ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                             unroll_indices);
105489c488871056185b8633aae7e7573b398827b038Marek Olšák
105589c488871056185b8633aae7e7573b398827b038Marek Olšák      user_vb_mask &= ~(mgr->incompatible_vb_mask |
105689c488871056185b8633aae7e7573b398827b038Marek Olšák                        mgr->ve->incompatible_vb_mask_all);
1057975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
1058975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1059975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Upload user buffers. */
106089c488871056185b8633aae7e7573b398827b038Marek Olšák   if (user_vb_mask) {
106164242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
1062dbd60d27e8087a3bacf36d4eceef15dc4fcdcceeMarek Olšák                            info->start_instance, info->instance_count);
1063975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
10645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
1065ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   /*
1066ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices) {
1067ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      printf("unrolling indices: start_vertex = %i, num_vertices = %i\n",
1068ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák             start_vertex, num_vertices);
1069ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      util_dump_draw_info(stdout, info);
1070ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      printf("\n");
1071ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
1072ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1073ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   unsigned i;
1074e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
10755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("input %i: ", i);
1076e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
10775968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("\n");
10785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
10792d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
10805968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("real %i: ", i);
10812d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i);
10825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("\n");
1083ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
1084ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   */
1085ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1086e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_upload_unmap(mgr->uploader);
1087e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
1088e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->real_vertex_buffer);
1089975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
10905ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   if (unlikely(unroll_indices)) {
10915ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      struct pipe_draw_info new_info = *info;
10925ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.indexed = FALSE;
10935ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.index_bias = 0;
10945ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.min_index = 0;
10955ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.max_index = info->count - 1;
10965ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.start = 0;
10975ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák
1098e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, &new_info);
10995ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   } else {
1100e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, info);
11015ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   }
1102975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1103e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   if (mgr->using_translate) {
1104975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      u_vbuf_translate_end(mgr);
1105975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
11065ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   mgr->vertex_buffers_dirty = TRUE;
1107975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
110831714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
1109e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_save_vertex_elements(struct u_vbuf *mgr)
111031714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák{
1111e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   assert(!mgr->ve_saved);
1112e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve_saved = mgr->ve;
1113e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1114e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1115e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_restore_vertex_elements(struct u_vbuf *mgr)
1116e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1117e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   if (mgr->ve != mgr->ve_saved) {
1118e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      struct pipe_context *pipe = mgr->pipe;
1119e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1120e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      mgr->ve = mgr->ve_saved;
1121e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->bind_vertex_elements_state(pipe,
1122e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                       mgr->ve ? mgr->ve->driver_cso : NULL);
1123e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   }
1124e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve_saved = NULL;
1125e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1126e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1127e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_save_vertex_buffers(struct u_vbuf *mgr)
1128e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1129e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   util_copy_vertex_buffers(mgr->vertex_buffer_saved,
1130e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            &mgr->nr_vertex_buffers_saved,
1131e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->vertex_buffer,
1132e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->nr_vertex_buffers);
1133e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1134e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1135e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr)
1136e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1137e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned i;
1138e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1139e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_vbuf_set_vertex_buffers(mgr, mgr->nr_vertex_buffers_saved,
1140e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                             mgr->vertex_buffer_saved);
1141e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers_saved; i++) {
1142e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer_saved[i].buffer, NULL);
1143e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   }
1144e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_vertex_buffers_saved = 0;
114531714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák}
1146