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);
2286463eb013f645440d252b8b390e1c6e3c1212b7eVadim Girlin
2296463eb013f645440d252b8b390e1c6e3c1212b7eVadim Girlin   if (ve != mgr->ve)
2306463eb013f645440d252b8b390e1c6e3c1212b7eVadim Girlin	   pipe->bind_vertex_elements_state(pipe, ve->driver_cso);
231e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   return ve;
232c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák}
233c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák
234e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count,
235e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                               const struct pipe_vertex_element *states)
236975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
237e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve = u_vbuf_set_vertex_elements_internal(mgr, count, states);
238e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
239975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
240e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_destroy(struct u_vbuf *mgr)
241e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
242e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned i;
24331714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
24418bcb962bbad451a5e34f0315f03b8fb4533ea73Marek Olšák   mgr->pipe->set_vertex_buffers(mgr->pipe, 0, NULL);
24518bcb962bbad451a5e34f0315f03b8fb4533ea73Marek Olšák
246e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
247e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
2480b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák   }
2492d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
2502d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
251975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
252975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
253975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   translate_cache_destroy(mgr->translate_cache);
254e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_upload_destroy(mgr->uploader);
255c2cc630f2896175ff0f368d9199acbe24afb7e75Marek Olšák   cso_cache_delete(mgr->cso_cache);
256975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   FREE(mgr);
257975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
258975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
259914368538ec72926f160e784dcbae5db05e34abeBrian Paulstatic enum pipe_error
260e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
2612b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák                         unsigned vb_mask, unsigned out_vb,
262ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                         int start_vertex, unsigned num_vertices,
263ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                         int start_index, unsigned num_indices, int min_index,
264e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                         boolean unroll_indices)
2655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák{
2665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct translate *tr;
2675968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
2685968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct pipe_resource *out_buffer = NULL;
2695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   uint8_t *out_map;
270914368538ec72926f160e784dcbae5db05e34abeBrian Paul   unsigned out_offset, i;
271914368538ec72926f160e784dcbae5db05e34abeBrian Paul   enum pipe_error err;
2725968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Get a translate object. */
2745968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   tr = translate_cache_find(mgr->translate_cache, key);
2755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2765968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Map buffers we want to translate. */
277e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
2785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb_mask & (1 << i)) {
279e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[i];
2802b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák         unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
2815968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         uint8_t *map;
2825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2834552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák         if (vb->user_buffer) {
2844552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák            map = (uint8_t*)vb->user_buffer + offset;
2855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         } else {
2862b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák            unsigned size = vb->stride ? num_vertices * vb->stride
2875968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                       : sizeof(double)*4;
2885968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
2895968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            if (offset+size > vb->buffer->width0) {
2905968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák               size = vb->buffer->width0 - offset;
2915968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            }
292975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
2935968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size,
2945968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                        PIPE_TRANSFER_READ, &vb_transfer[i]);
2955968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
2965968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
297ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Subtract min_index so that indexing with the index buffer works. */
298ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (unroll_indices) {
299ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            map -= vb->stride * min_index;
300ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
301ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
3025968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         tr->set_buffer(tr, i, map, vb->stride, ~0);
3035968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
3045968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
3055968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
306ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   /* Translate. */
307ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices) {
30831714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák      struct pipe_index_buffer *ib = &mgr->index_buffer;
309ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      struct pipe_transfer *transfer = NULL;
310ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      unsigned offset = ib->offset + start_index * ib->index_size;
311ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      uint8_t *map;
3125968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
313bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      assert((ib->buffer || ib->user_buffer) && ib->index_size);
3145968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
315914368538ec72926f160e784dcbae5db05e34abeBrian Paul      /* Create and map the output buffer. */
316914368538ec72926f160e784dcbae5db05e34abeBrian Paul      err = u_upload_alloc(mgr->uploader, 0,
317914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           key->output_stride * num_indices,
318914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           &out_offset, &out_buffer,
319914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           (void**)&out_map);
320914368538ec72926f160e784dcbae5db05e34abeBrian Paul      if (err != PIPE_OK)
321914368538ec72926f160e784dcbae5db05e34abeBrian Paul         return err;
322914368538ec72926f160e784dcbae5db05e34abeBrian Paul
323bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      if (ib->user_buffer) {
324bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák         map = (uint8_t*)ib->user_buffer + offset;
325ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      } else {
326ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset,
327ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                     num_indices * ib->index_size,
328ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                                     PIPE_TRANSFER_READ, &transfer);
329ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
330ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
331ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      switch (ib->index_size) {
332ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 4:
333ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts(tr, (unsigned*)map, num_indices, 0, out_map);
334ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
335ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 2:
336ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts16(tr, (uint16_t*)map, num_indices, 0, out_map);
337ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
338ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      case 1:
339ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         tr->run_elts8(tr, map, num_indices, 0, out_map);
340ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         break;
341ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
342ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
343ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      if (transfer) {
344ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         pipe_buffer_unmap(mgr->pipe, transfer);
345ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      }
346ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   } else {
347ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      /* Create and map the output buffer. */
348914368538ec72926f160e784dcbae5db05e34abeBrian Paul      err = u_upload_alloc(mgr->uploader,
349914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           key->output_stride * start_vertex,
350914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           key->output_stride * num_vertices,
351914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           &out_offset, &out_buffer,
352914368538ec72926f160e784dcbae5db05e34abeBrian Paul                           (void**)&out_map);
353914368538ec72926f160e784dcbae5db05e34abeBrian Paul      if (err != PIPE_OK)
354914368538ec72926f160e784dcbae5db05e34abeBrian Paul         return err;
355ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
356ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      out_offset -= key->output_stride * start_vertex;
357ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
358ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      tr->run(tr, 0, num_vertices, 0, out_map);
359ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
3605968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3615968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Unmap all buffers. */
362e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
3635968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb_transfer[i]) {
3645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
3655968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
3665968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
3675968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3685968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Setup the new vertex buffer. */
3692d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].buffer_offset = out_offset;
3702d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].stride = key->output_stride;
3715968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3725968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Move the buffer reference. */
3735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   pipe_resource_reference(
3742d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      &mgr->real_vertex_buffer[out_vb].buffer, NULL);
3752d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->real_vertex_buffer[out_vb].buffer = out_buffer;
376914368538ec72926f160e784dcbae5db05e34abeBrian Paul
377914368538ec72926f160e784dcbae5db05e34abeBrian Paul   return PIPE_OK;
3785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák}
3795968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3805968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákstatic boolean
381e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
3825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák                                    unsigned mask[VB_NUM])
383611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák{
3846fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   unsigned type;
3855968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned fallback_vbs[VB_NUM];
3866fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   /* Set the bit for each buffer which is incompatible, or isn't set. */
3876fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák   uint32_t unused_vb_mask =
3886fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák      mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
3896fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák      ~((1 << mgr->nr_vertex_buffers) - 1);
3905968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
3915968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(fallback_vbs, ~0, sizeof(fallback_vbs));
392611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
3935968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Find free slots for each type if needed. */
3945968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (type = 0; type < VB_NUM; type++) {
3955968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (mask[type]) {
3966fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         uint32_t index;
3976fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák
3986fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         if (!unused_vb_mask) {
3995968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            /* fail, reset the number to its original value */
400e0773da1e897164ed7597437070e32b867734ee5Marek Olšák            mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
4015968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            return FALSE;
402611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák         }
4036fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák
4046fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         index = ffs(unused_vb_mask) - 1;
4056fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         fallback_vbs[type] = index;
4066fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         if (index >= mgr->nr_real_vertex_buffers) {
4076fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák            mgr->nr_real_vertex_buffers = index + 1;
4086fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         }
4096fe30fbc96a7b102d7c23ae0dd7be0b8739276c9Marek Olšák         /*printf("found slot=%i for type=%i\n", index, type);*/
410611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      }
411611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
4125968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4135968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memcpy(mgr->fallback_vbs, fallback_vbs, sizeof(fallback_vbs));
4145968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   return TRUE;
415611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák}
416611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4175968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšákstatic boolean
418e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_translate_begin(struct u_vbuf *mgr,
419c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                       int start_vertex, unsigned num_vertices,
420ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                       int start_instance, unsigned num_instances,
421ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák                       int start_index, unsigned num_indices, int min_index,
422e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                       boolean unroll_indices)
423975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
4245968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned mask[VB_NUM] = {0};
4255968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   struct translate_key key[VB_NUM];
4265968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned elem_index[VB_NUM][PIPE_MAX_ATTRIBS]; /* ... into key.elements */
4275968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned i, type;
4285968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
429c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák   int start[VB_NUM] = {
430c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      start_vertex,     /* VERTEX */
4315968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      start_instance,   /* INSTANCE */
4325968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      0                 /* CONST */
4335968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   };
4345968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4352b851526c1c047bba7ebb7e51706b1694f027947Marek Olšák   unsigned num[VB_NUM] = {
436c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      num_vertices,     /* VERTEX */
437c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      num_instances,    /* INSTANCE */
438c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák      1                 /* CONST */
4395968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   };
4405968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4415968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(key, 0, sizeof(key));
4425968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   memset(elem_index, ~0, sizeof(elem_index));
4435968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4445968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* See if there are vertex attribs of each type to translate and
4455968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák    * which ones. */
4465968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (i = 0; i < mgr->ve->count; i++) {
4475968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index;
448975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
449e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      if (!mgr->vertex_buffer[vb_index].stride) {
450b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
451b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
452ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
453ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4545968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_CONST] |= 1 << vb_index;
4555968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      } else if (mgr->ve->ve[i].instance_divisor) {
456b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
457b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
458ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
459ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4605968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_INSTANCE] |= 1 << vb_index;
4615968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      } else {
462ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (!unroll_indices &&
463b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->ve->incompatible_elem_mask & (1 << i)) &&
464b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák             !(mgr->incompatible_vb_mask & (1 << vb_index))) {
465ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            continue;
466ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
4675968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mask[VB_VERTEX] |= 1 << vb_index;
4685968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
4695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
470611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4715968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]);
4725968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
4735968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Find free vertex buffer slots. */
4745968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) {
4755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      return FALSE;
476611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
477611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák
4785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Initialize the translate keys. */
479975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < mgr->ve->count; i++) {
4805968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      struct translate_key *k;
4815968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      struct translate_element *te;
4825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned bit, vb_index = mgr->ve->ve[i].vertex_buffer_index;
483ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      bit = 1 << vb_index;
484975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
485b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (!(mgr->ve->incompatible_elem_mask & (1 << i)) &&
486b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák          !(mgr->incompatible_vb_mask & (1 << vb_index)) &&
487ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          (!unroll_indices || !(mask[VB_VERTEX] & bit))) {
488975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
489975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
490975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
4915968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Set type to what we will translate.
4925968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák       * Whether vertex, instance, or constant attribs. */
4935968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      for (type = 0; type < VB_NUM; type++) {
4945968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (mask[type] & bit) {
4955968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            break;
4965968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
4975968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
4985968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      assert(type < VB_NUM);
4995968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      assert(translate_is_output_format_supported(mgr->ve->native_format[i]));
5005968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /*printf("velem=%i type=%i\n", i, type);*/
5015968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
5025968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Add the vertex element. */
5035968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k = &key[type];
5045968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      elem_index[type][i] = k->nr_elements;
505975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5065968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te = &k->element[k->nr_elements];
507611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      te->type = TRANSLATE_ELEMENT_NORMAL;
508611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák      te->instance_divisor = 0;
5095968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->input_buffer = vb_index;
510975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      te->input_format = mgr->ve->ve[i].src_format;
511975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      te->input_offset = mgr->ve->ve[i].src_offset;
5125968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->output_format = mgr->ve->native_format[i];
5135968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      te->output_offset = k->output_stride;
514975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5155968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k->output_stride += mgr->ve->native_format_size[i];
5165968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      k->nr_elements++;
517975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
518975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5195968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Translate buffers. */
5205968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (type = 0; type < VB_NUM; type++) {
5215968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (key[type].nr_elements) {
522914368538ec72926f160e784dcbae5db05e34abeBrian Paul         enum pipe_error err;
523914368538ec72926f160e784dcbae5db05e34abeBrian Paul         err = u_vbuf_translate_buffers(mgr, &key[type], mask[type],
524914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                        mgr->fallback_vbs[type],
525914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                        start[type], num[type],
526914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                        start_index, num_indices, min_index,
527914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                        unroll_indices && type == VB_VERTEX);
528914368538ec72926f160e784dcbae5db05e34abeBrian Paul         if (err != PIPE_OK)
529914368538ec72926f160e784dcbae5db05e34abeBrian Paul            return FALSE;
530975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5315968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         /* Fixup the stride for constant attribs. */
5325968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (type == VB_CONST) {
5332d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák            mgr->real_vertex_buffer[mgr->fallback_vbs[VB_CONST]].stride = 0;
534c727cc175bcbf96f12f27c46819667948d5ebbe2Marek Olšák         }
535975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
536975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
537975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
538611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   /* Setup new vertex elements. */
539611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   for (i = 0; i < mgr->ve->count; i++) {
5405968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      for (type = 0; type < VB_NUM; type++) {
5415968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         if (elem_index[type][i] < key[type].nr_elements) {
5425968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            struct translate_element *te = &key[type].element[elem_index[type][i]];
5435968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor;
5445968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].src_format = te->output_format;
5455968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].src_offset = te->output_offset;
5465968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            mgr->fallback_velems[i].vertex_buffer_index = mgr->fallback_vbs[type];
5475968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
5485968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            /* elem_index[type][i] can only be set for one type. */
5495968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            assert(type > VB_INSTANCE || elem_index[type+1][i] == ~0);
5505968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            assert(type > VB_VERTEX   || elem_index[type+2][i] == ~0);
5515968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák            break;
5525968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         }
5535968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
5545968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* No translating, just copy the original vertex element over. */
5555968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (type == VB_NUM) {
556611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák         memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i],
557611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák                sizeof(struct pipe_vertex_element));
558975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
559611a8b82e3827dd7c256edd5c014f4d48cb045f0Marek Olšák   }
560975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
561e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count,
562e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                       mgr->fallback_velems);
563e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->using_translate = TRUE;
5645968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   return TRUE;
565975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
566975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
567e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void u_vbuf_translate_end(struct u_vbuf *mgr)
568975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
5695968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   unsigned i;
5705968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
571975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Restore vertex elements. */
572e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
573e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->using_translate = FALSE;
574975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
5755968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   /* Unreference the now-unused VBOs. */
5765968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   for (i = 0; i < VB_NUM; i++) {
5775968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      unsigned vb = mgr->fallback_vbs[i];
5785968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (vb != ~0) {
5792d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák         pipe_resource_reference(&mgr->real_vertex_buffer[vb].buffer, NULL);
5805968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák         mgr->fallback_vbs[i] = ~0;
5815968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      }
5825968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
583e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
584975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
585975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
586975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák#define FORMAT_REPLACE(what, withwhat) \
587975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
588975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
589889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšákstatic void *
590e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
591889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák                              const struct pipe_vertex_element *attribs)
592975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
593e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
594975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned i;
595039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák   struct pipe_vertex_element driver_attribs[PIPE_MAX_ATTRIBS];
59628fb79891101c23c75982726c81112caa96f9275Marek Olšák   struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements);
597b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   uint32_t used_buffers = 0;
598975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
599975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   ve->count = count;
600975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
601975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count);
602039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák   memcpy(driver_attribs, attribs, sizeof(struct pipe_vertex_element) * count);
603975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
604975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Set the best native format in case the original format is not
605975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák    * supported. */
606975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < count; i++) {
607975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      enum pipe_format format = ve->ve[i].src_format;
608975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
60951095f74cf92d3cada7366ce898ade7693570b48Marek Olšák      ve->src_format_size[i] = util_format_get_blocksize(format);
61051095f74cf92d3cada7366ce898ade7693570b48Marek Olšák
611b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      used_buffers |= 1 << ve->ve[i].vertex_buffer_index;
612b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
613b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (!ve->ve[i].instance_divisor) {
614b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->noninstance_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
615b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
616b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
617975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      /* Choose a native format.
618975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák       * For now we don't care about the alignment, that's going to
619975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák       * be sorted out later. */
6207fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_fixed32) {
621975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
622975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_FIXED,           R32_FLOAT);
623975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_FIXED,        R32G32_FLOAT);
624975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_FIXED,     R32G32B32_FLOAT);
625975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_FIXED,  R32G32B32A32_FLOAT);
626975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
627975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
628975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6297fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_float16) {
630975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
631975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16_FLOAT,           R32_FLOAT);
632975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16_FLOAT,        R32G32_FLOAT);
633975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16B16_FLOAT,     R32G32B32_FLOAT);
634975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R16G16B16A16_FLOAT,  R32G32B32A32_FLOAT);
635975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
636975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
637975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6387fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_float64) {
639975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
640975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64_FLOAT,           R32_FLOAT);
641975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64_FLOAT,        R32G32_FLOAT);
642975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64B64_FLOAT,     R32G32B32_FLOAT);
643975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R64G64B64A64_FLOAT,  R32G32B32A32_FLOAT);
644975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
645975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
646975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6477fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_norm32) {
648975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
649975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_UNORM,           R32_FLOAT);
650975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_UNORM,        R32G32_FLOAT);
651975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_UNORM,     R32G32B32_FLOAT);
652975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_UNORM,  R32G32B32A32_FLOAT);
653975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_SNORM,           R32_FLOAT);
654975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_SNORM,        R32G32_FLOAT);
655975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_SNORM,     R32G32B32_FLOAT);
656975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_SNORM,  R32G32B32A32_FLOAT);
657975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
658975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
659975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
6607fe3631a7a0ad7602b4e947ac87ef86875c8bb3fMarek Olšák      if (!mgr->caps.format_scaled32) {
661975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         switch (format) {
662975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_USCALED,         R32_FLOAT);
663975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_USCALED,      R32G32_FLOAT);
664975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_USCALED,   R32G32B32_FLOAT);
665975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
666975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32_SSCALED,         R32_FLOAT);
667975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32_SSCALED,      R32G32_FLOAT);
668975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32_SSCALED,   R32G32B32_FLOAT);
669975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
670975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            default:;
671975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         }
672975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
673975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
674039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák      driver_attribs[i].src_format = format;
675975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      ve->native_format[i] = format;
676975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      ve->native_format_size[i] =
677975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák            util_format_get_blocksize(ve->native_format[i]);
678975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
679b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (ve->ve[i].src_format != format ||
680b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák          (!mgr->caps.velem_src_offset_unaligned &&
681b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           ve->ve[i].src_offset % 4 != 0)) {
682b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->incompatible_elem_mask |= 1 << i;
683b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->incompatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
684b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      } else {
685b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         ve->compatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
686b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
687975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
688975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
689b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers;
690b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers;
691b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
692975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Align the formats to the size of DWORD if needed. */
693eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák   if (!mgr->caps.velem_src_offset_unaligned) {
694975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      for (i = 0; i < count; i++) {
695975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         ve->native_format_size[i] = align(ve->native_format_size[i], 4);
696975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
697975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
698975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
699889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák   ve->driver_cso =
700039f53b814cef8fce0f591e3ff36a68f4780b620Marek Olšák      pipe->create_vertex_elements_state(pipe, count, driver_attribs);
701975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   return ve;
702975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
703975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
704e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso)
705975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
706e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
707889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák   struct u_vbuf_elements *ve = cso;
708889238c8b1e6b8ac5eed30ec3122be94216ca7cfMarek Olšák
709e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->delete_vertex_elements_state(pipe, ve->driver_cso);
710975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   FREE(ve);
711975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
712975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
713e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
714e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                               const struct pipe_vertex_buffer *bufs)
715975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
716975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   unsigned i;
717975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
718b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->user_vb_mask = 0;
719b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->incompatible_vb_mask = 0;
720b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   mgr->nonzero_stride_vb_mask = 0;
721975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
722975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   for (i = 0; i < count; i++) {
723975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      const struct pipe_vertex_buffer *vb = &bufs[i];
724a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      struct pipe_vertex_buffer *orig_vb = &mgr->vertex_buffer[i];
725a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
726975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
727a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      pipe_resource_reference(&orig_vb->buffer, vb->buffer);
7284552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      orig_vb->user_buffer = vb->user_buffer;
7290b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák
730a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
731a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      real_vb->stride = orig_vb->stride = vb->stride;
73296863baa42564ce2daa5f4651f1c52f1d281d9a5Marek Olšák      real_vb->user_buffer = NULL;
7330b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák
734b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (vb->stride) {
735b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->nonzero_stride_vb_mask |= 1 << i;
736b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      }
737b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
7384552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!vb->buffer && !vb->user_buffer) {
739a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
740a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         continue;
741a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      }
742975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
743eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák      if ((!mgr->caps.buffer_offset_unaligned && vb->buffer_offset % 4 != 0) ||
744eaf8fe3335b1c7e62275ac0fef202f51750ffba9Marek Olšák          (!mgr->caps.buffer_stride_unaligned && vb->stride % 4 != 0)) {
745b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->incompatible_vb_mask |= 1 << i;
746a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
747975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
748975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
749975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
7504552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
751b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         mgr->user_vb_mask |= 1 << i;
752a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák         pipe_resource_reference(&real_vb->buffer, NULL);
753975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák         continue;
754975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
755975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
756a0e352f5ebac0f533481d353b7f3ba66b3a9ed7fMarek Olšák      pipe_resource_reference(&real_vb->buffer, vb->buffer);
75796863baa42564ce2daa5f4651f1c52f1d281d9a5Marek Olšák      real_vb->user_buffer = vb->user_buffer;
758975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
759975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
760e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = count; i < mgr->nr_vertex_buffers; i++) {
761e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
762975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
7632d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = count; i < mgr->nr_real_vertex_buffers; i++) {
7642d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
7650b3270b9b72c2ca4fad172752045d8fa93c1ad6eMarek Olšák   }
766975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
767e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_vertex_buffers = count;
7682d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   mgr->nr_real_vertex_buffers = count;
7695ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   mgr->vertex_buffers_dirty = TRUE;
770975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
771975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
772e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_set_index_buffer(struct u_vbuf *mgr,
773e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                             const struct pipe_index_buffer *ib)
7744cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák{
775e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
77631714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
777bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák   if (ib) {
7784cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      assert(ib->offset % ib->index_size == 0);
7794cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer);
780bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      memcpy(&mgr->index_buffer, ib, sizeof(*ib));
7814cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák   } else {
7824cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák      pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
7834cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák   }
78431714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
785e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->set_index_buffer(pipe, ib);
7864cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák}
7874cfc8c775c751dd2b2b43f3ca58ae9798a84c0f1Marek Olšák
788914368538ec72926f160e784dcbae5db05e34abeBrian Paulstatic enum pipe_error
789e0773da1e897164ed7597437070e32b867734ee5Marek Olšáku_vbuf_upload_buffers(struct u_vbuf *mgr,
790c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                      int start_vertex, unsigned num_vertices,
791c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák                      int start_instance, unsigned num_instances)
792975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
793cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned i;
794cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned nr_velems = mgr->ve->count;
795e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned nr_vbufs = mgr->nr_vertex_buffers;
796df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák   struct pipe_vertex_element *velems =
797e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve;
798cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned start_offset[PIPE_MAX_ATTRIBS];
799cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   unsigned end_offset[PIPE_MAX_ATTRIBS] = {0};
800cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
801cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   /* Determine how much data needs to be uploaded. */
802cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   for (i = 0; i < nr_velems; i++) {
803df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák      struct pipe_vertex_element *velem = &velems[i];
804cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      unsigned index = velem->vertex_buffer_index;
805e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index];
80621f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      unsigned instance_div, first, size;
807975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
8085968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      /* Skip the buffers generated by translate. */
8095968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      if (index == mgr->fallback_vbs[VB_VERTEX] ||
8105968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák          index == mgr->fallback_vbs[VB_INSTANCE] ||
8115968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák          index == mgr->fallback_vbs[VB_CONST]) {
812df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák         continue;
813df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák      }
814df49b0ce9009e867f6d44fd48e31a16e5a933c64Marek Olšák
8154552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      if (!vb->user_buffer) {
816cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         continue;
817cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
818975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
81921f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      instance_div = velem->instance_divisor;
820cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      first = vb->buffer_offset + velem->src_offset;
821975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
822cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!vb->stride) {
823cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Constant attrib. */
824cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         size = mgr->ve->src_format_size[i];
825cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      } else if (instance_div) {
826cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Per-instance attrib. */
827c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         unsigned count = (num_instances + instance_div - 1) / instance_div;
828dbd60d27e8087a3bacf36d4eceef15dc4fcdcceeMarek Olšák         first += vb->stride * start_instance;
829cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         size = vb->stride * (count - 1) + mgr->ve->src_format_size[i];
830cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      } else {
831cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         /* Per-vertex attrib. */
832c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         first += vb->stride * start_vertex;
833c897b943f4ba6ad4c7547d16aa9bca47ac1230deMarek Olšák         size = vb->stride * (num_vertices - 1) + mgr->ve->src_format_size[i];
834cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
835975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
836cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      /* Update offsets. */
837cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!end_offset[index]) {
838cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         start_offset[index] = first;
839cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         end_offset[index] = first + size;
840975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      } else {
841cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         if (first < start_offset[index])
842cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák            start_offset[index] = first;
843cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         if (first + size > end_offset[index])
844cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák            end_offset[index] = first + size;
845975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      }
846975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
847cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
848cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   /* Upload buffers. */
849cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   for (i = 0; i < nr_vbufs; i++) {
85021f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      unsigned start, end = end_offset[i];
85121f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      struct pipe_vertex_buffer *real_vb;
8524552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      const uint8_t *ptr;
853914368538ec72926f160e784dcbae5db05e34abeBrian Paul      enum pipe_error err;
854cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
855cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      if (!end) {
856cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák         continue;
857cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      }
85821f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák
85921f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      start = start_offset[i];
860cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák      assert(start < end);
861cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
8622d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      real_vb = &mgr->real_vertex_buffer[i];
8634552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák      ptr = mgr->vertex_buffer[i].user_buffer;
86421f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák
865914368538ec72926f160e784dcbae5db05e34abeBrian Paul      err = u_upload_data(mgr->uploader, start, end - start, ptr + start,
866914368538ec72926f160e784dcbae5db05e34abeBrian Paul                          &real_vb->buffer_offset, &real_vb->buffer);
867914368538ec72926f160e784dcbae5db05e34abeBrian Paul      if (err != PIPE_OK)
868914368538ec72926f160e784dcbae5db05e34abeBrian Paul         return err;
869cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák
87021f71b6c050f8a746f6a671e57afc8e5500c5e77Marek Olšák      real_vb->buffer_offset -= start;
871cd9bbb3935320fd838c9b64236ccef865782a248Marek Olšák   }
872914368538ec72926f160e784dcbae5db05e34abeBrian Paul
873914368538ec72926f160e784dcbae5db05e34abeBrian Paul   return PIPE_OK;
874975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
875975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
876e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic boolean u_vbuf_need_minmax_index(struct u_vbuf *mgr)
87772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák{
878b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* See if there are any per-vertex attribs which will be uploaded or
879b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * translated. Use bitmasks to get the info instead of looping over vertex
880b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * elements. */
881b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   return ((mgr->user_vb_mask | mgr->incompatible_vb_mask |
882b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            mgr->ve->incompatible_vb_mask_any) &
883b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->ve->noninstance_vb_mask_any & mgr->nonzero_stride_vb_mask) != 0;
88472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák}
88572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
886e0773da1e897164ed7597437070e32b867734ee5Marek Olšákstatic boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr)
8872bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák{
888b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   /* Return true if there are hw buffers which don't need to be translated.
889b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    *
890b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * We could query whether each buffer is busy, but that would
891b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák    * be way more costly than this. */
892b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   return (~mgr->user_vb_mask & ~mgr->incompatible_vb_mask &
893b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->ve->compatible_vb_mask_all & mgr->ve->noninstance_vb_mask_any &
894b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák           mgr->nonzero_stride_vb_mask) != 0;
8952bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák}
8962bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák
89772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšákstatic void u_vbuf_get_minmax_index(struct pipe_context *pipe,
89872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    struct pipe_index_buffer *ib,
89972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    const struct pipe_draw_info *info,
90072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    int *out_min_index,
90172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                    int *out_max_index)
90272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák{
90372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   struct pipe_transfer *transfer = NULL;
90472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   const void *indices;
90572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   unsigned i;
90672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   unsigned restart_index = info->restart_index;
90772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
908bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák   if (ib->user_buffer) {
909bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák      indices = (uint8_t*)ib->user_buffer +
91072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                ib->offset + info->start * ib->index_size;
91172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   } else {
91272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      indices = pipe_buffer_map_range(pipe, ib->buffer,
91372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      ib->offset + info->start * ib->index_size,
91472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      info->count * ib->index_size,
91572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák                                      PIPE_TRANSFER_READ, &transfer);
91672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
91772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
91872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   switch (ib->index_size) {
91972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 4: {
92072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned *ui_indices = (const unsigned*)indices;
92172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_ui = 0;
92272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_ui = ~0U;
92372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
92472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
92572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] != restart_index) {
92672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
92772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
92872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
92972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
93072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
93172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
93272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
93372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
93472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
93572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
93672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
93772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_ui;
93872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_ui;
93972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
94072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
94172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 2: {
94272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned short *us_indices = (const unsigned short*)indices;
94372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_us = 0;
94472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_us = ~0U;
94572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
94672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
94772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] != restart_index) {
94872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (us_indices[i] > max_us) max_us = us_indices[i];
94972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (us_indices[i] < min_us) min_us = us_indices[i];
95072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
95172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
95272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
95372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
95472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
95572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] > max_us) max_us = us_indices[i];
95672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (us_indices[i] < min_us) min_us = us_indices[i];
95772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
95872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
95972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_us;
96072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_us;
96172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
96272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
96372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   case 1: {
96472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      const unsigned char *ub_indices = (const unsigned char*)indices;
96572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned max_ub = 0;
96672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      unsigned min_ub = ~0U;
96772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      if (info->primitive_restart) {
96872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
96972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] != restart_index) {
97072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
97172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák               if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
97272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            }
97372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
97472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
97572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      else {
97672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         for (i = 0; i < info->count; i++) {
97772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
97872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák            if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
97972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         }
98072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      }
98172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_min_index = min_ub;
98272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      *out_max_index = max_ub;
98372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      break;
98472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
98572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   default:
98672e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      assert(0);
987de93347d482a96f88c898622c9620f03e677e386Vinson Lee      *out_min_index = 0;
988de93347d482a96f88c898622c9620f03e677e386Vinson Lee      *out_max_index = 0;
98972e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
99072e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
99172e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   if (transfer) {
99272e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák      pipe_buffer_unmap(pipe, transfer);
99372e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
99472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák}
99572e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
996e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
997975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák{
998e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   struct pipe_context *pipe = mgr->pipe;
999ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   int start_vertex, min_index;
100064242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák   unsigned num_vertices;
1001e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   boolean unroll_indices = FALSE;
100289c488871056185b8633aae7e7573b398827b038Marek Olšák   uint32_t user_vb_mask = mgr->user_vb_mask;
1003975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
10045ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   /* Normal draw. No fallback and no user buffers. */
1005b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák   if (!mgr->incompatible_vb_mask &&
1006b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       !mgr->ve->incompatible_elem_mask &&
100789c488871056185b8633aae7e7573b398827b038Marek Olšák       !user_vb_mask) {
10085ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      /* Set vertex buffers if needed. */
10095ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      if (mgr->vertex_buffers_dirty) {
1010e0773da1e897164ed7597437070e32b867734ee5Marek Olšák         pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
1011e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                  mgr->real_vertex_buffer);
10125ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák         mgr->vertex_buffers_dirty = FALSE;
10135ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      }
10145ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák
1015e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, info);
10162d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      return;
101772e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák   }
101872e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák
101960a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák   if (info->indexed) {
1020b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      /* See if anything needs to be done for per-vertex attribs. */
1021b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák      if (u_vbuf_need_minmax_index(mgr)) {
1022b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         int max_index;
1023b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák
1024b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         if (info->max_index != ~0) {
1025b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            min_index = info->min_index;
1026b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            max_index = info->max_index;
1027b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         } else {
1028b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák            u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
1029b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák                                    &min_index, &max_index);
1030b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák         }
103164242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák
103264242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         assert(min_index <= max_index);
103364242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák
103464242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         start_vertex = min_index + info->index_bias;
103564242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         num_vertices = max_index + 1 - min_index;
1036ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1037ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Primitive restart doesn't work when unrolling indices.
1038ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          * We would have to break this drawing operation into several ones. */
1039ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         /* Use some heuristic to see if unrolling indices improves
1040ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák          * performance. */
1041ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         if (!info->primitive_restart &&
1042ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák             num_vertices > info->count*2 &&
10432bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák             num_vertices-info->count > 32 &&
10442bdf93449a0b00145fabdd3f7866acbafa18e734Marek Olšák             !u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
1045ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák            /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
1046e0773da1e897164ed7597437070e32b867734ee5Marek Olšák            unroll_indices = TRUE;
104789c488871056185b8633aae7e7573b398827b038Marek Olšák            user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
104889c488871056185b8633aae7e7573b398827b038Marek Olšák                              mgr->ve->noninstance_vb_mask_any);
1049ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák         }
105060a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák      } else {
105164242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         /* Nothing to do for per-vertex attribs. */
105264242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         start_vertex = 0;
105364242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák         num_vertices = 0;
105472e1117e489986783dd5b27a3ad781b86c2d5d67Marek Olšák         min_index = 0;
105560a77cf316a90cb5be4f73495c2545b3d49e5ca1Marek Olšák      }
1056a0d154dc1385d92a31dca8e65e50d958bdf6d532Marek Olšák   } else {
105764242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      start_vertex = info->start;
105864242b23c1893dd6e1c048beee0e1573aeaf1abcMarek Olšák      num_vertices = info->count;
1059ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      min_index = 0;
1060a0d154dc1385d92a31dca8e65e50d958bdf6d532Marek Olšák   }
1061975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1062975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Translate vertices with non-native layouts or formats. */
1063ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices ||
1064b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       mgr->incompatible_vb_mask ||
1065b5e5e61439bda7a3cf1f909b48467371ea53d9d7Marek Olšák       mgr->ve->incompatible_elem_mask) {
1066914368538ec72926f160e784dcbae5db05e34abeBrian Paul      if (!u_vbuf_translate_begin(mgr, start_vertex, num_vertices,
1067914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                  info->start_instance, info->instance_count,
1068914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                  info->start, info->count, min_index,
1069914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                  unroll_indices)) {
1070914368538ec72926f160e784dcbae5db05e34abeBrian Paul         debug_warn_once("u_vbuf_translate_begin() failed");
1071914368538ec72926f160e784dcbae5db05e34abeBrian Paul         return;
1072914368538ec72926f160e784dcbae5db05e34abeBrian Paul      }
107389c488871056185b8633aae7e7573b398827b038Marek Olšák
107489c488871056185b8633aae7e7573b398827b038Marek Olšák      user_vb_mask &= ~(mgr->incompatible_vb_mask |
107589c488871056185b8633aae7e7573b398827b038Marek Olšák                        mgr->ve->incompatible_vb_mask_all);
1076975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
1077975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1078975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   /* Upload user buffers. */
107989c488871056185b8633aae7e7573b398827b038Marek Olšák   if (user_vb_mask) {
1080914368538ec72926f160e784dcbae5db05e34abeBrian Paul      if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
1081914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                info->start_instance,
1082914368538ec72926f160e784dcbae5db05e34abeBrian Paul                                info->instance_count) != PIPE_OK) {
1083914368538ec72926f160e784dcbae5db05e34abeBrian Paul         debug_warn_once("u_vbuf_upload_buffers() failed");
1084914368538ec72926f160e784dcbae5db05e34abeBrian Paul         return;
1085914368538ec72926f160e784dcbae5db05e34abeBrian Paul      }
1086975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
10875968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák
1088ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   /*
1089ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   if (unroll_indices) {
1090ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      printf("unrolling indices: start_vertex = %i, num_vertices = %i\n",
1091ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák             start_vertex, num_vertices);
1092ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      util_dump_draw_info(stdout, info);
1093ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák      printf("\n");
1094ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
1095ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1096ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   unsigned i;
1097e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers; i++) {
10985968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("input %i: ", i);
1099e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
11005968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("\n");
11015968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák   }
11022d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák   for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
11035968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("real %i: ", i);
11042d03d4f4a365d7af5f4dac20700009152eba1682Marek Olšák      util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i);
11055968e4068cdcb0551f1c519f236560bb44ea659eMarek Olšák      printf("\n");
1106ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   }
1107ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák   */
1108ce44bae366ade59fb2dbdfbfe5a1ab8d24518a57Marek Olšák
1109e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_upload_unmap(mgr->uploader);
1110e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
1111e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->real_vertex_buffer);
1112975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
11135ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   if (unlikely(unroll_indices)) {
11145ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      struct pipe_draw_info new_info = *info;
11155ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.indexed = FALSE;
11165ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.index_bias = 0;
11175ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.min_index = 0;
11185ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.max_index = info->count - 1;
11195ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák      new_info.start = 0;
11205ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák
1121e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, &new_info);
11225ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   } else {
1123e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->draw_vbo(pipe, info);
11245ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   }
1125975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák
1126e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   if (mgr->using_translate) {
1127975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák      u_vbuf_translate_end(mgr);
1128975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák   }
11295ec7c28fdbc2e05d20b1a07cba1fe6ac3b6658f9Marek Olšák   mgr->vertex_buffers_dirty = TRUE;
1130975320ab76f5c247f6ed4dab80627173845200d0Marek Olšák}
113131714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák
1132e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_save_vertex_elements(struct u_vbuf *mgr)
113331714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák{
1134e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   assert(!mgr->ve_saved);
1135e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve_saved = mgr->ve;
1136e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1137e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1138e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_restore_vertex_elements(struct u_vbuf *mgr)
1139e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1140e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   if (mgr->ve != mgr->ve_saved) {
1141e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      struct pipe_context *pipe = mgr->pipe;
1142e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1143e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      mgr->ve = mgr->ve_saved;
1144e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe->bind_vertex_elements_state(pipe,
1145e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                                       mgr->ve ? mgr->ve->driver_cso : NULL);
1146e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   }
1147e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->ve_saved = NULL;
1148e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1149e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1150e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_save_vertex_buffers(struct u_vbuf *mgr)
1151e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1152e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   util_copy_vertex_buffers(mgr->vertex_buffer_saved,
1153e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            &mgr->nr_vertex_buffers_saved,
1154e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->vertex_buffer,
1155e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                            mgr->nr_vertex_buffers);
1156e0773da1e897164ed7597437070e32b867734ee5Marek Olšák}
1157e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1158e0773da1e897164ed7597437070e32b867734ee5Marek Olšákvoid u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr)
1159e0773da1e897164ed7597437070e32b867734ee5Marek Olšák{
1160e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   unsigned i;
1161e0773da1e897164ed7597437070e32b867734ee5Marek Olšák
1162e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   u_vbuf_set_vertex_buffers(mgr, mgr->nr_vertex_buffers_saved,
1163e0773da1e897164ed7597437070e32b867734ee5Marek Olšák                             mgr->vertex_buffer_saved);
1164e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   for (i = 0; i < mgr->nr_vertex_buffers_saved; i++) {
1165e0773da1e897164ed7597437070e32b867734ee5Marek Olšák      pipe_resource_reference(&mgr->vertex_buffer_saved[i].buffer, NULL);
1166e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   }
1167e0773da1e897164ed7597437070e32b867734ee5Marek Olšák   mgr->nr_vertex_buffers_saved = 0;
116831714ea4d5a20285f398286fe45b53d0609926ddMarek Olšák}
1169