1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * Post-transform vertex format info.  The vertex_info struct is used by
30  * the draw_vbuf code to emit hardware-specific vertex layouts into hw
31  * vertex buffers.
32  *
33  * Author:
34  *    Brian Paul
35  */
36 
37 
38 #ifndef DRAW_VERTEX_H
39 #define DRAW_VERTEX_H
40 
41 
42 #include "pipe/p_compiler.h"
43 #include "pipe/p_state.h"
44 #include "util/u_debug.h"
45 #include "util/u_memory.h"
46 
47 #define DRAW_ATTR_NONEXIST 255
48 
49 /**
50  * Vertex attribute emit modes
51  */
52 enum attrib_emit {
53    EMIT_OMIT,      /**< don't emit the attribute */
54    EMIT_1F,
55    EMIT_1F_PSIZE,  /**< insert constant point size */
56    EMIT_2F,
57    EMIT_3F,
58    EMIT_4F,
59    EMIT_4UB, /**< is RGBA like the rest */
60    EMIT_4UB_BGRA
61 };
62 
63 
64 /**
65  * Information about hardware/rasterization vertex layout.
66  */
67 struct vertex_info
68 {
69    uint num_attribs;
70    uint hwfmt[4];      /**< hardware format info for this format */
71    uint size;          /**< total vertex size in dwords */
72 
73    /* Keep this small and at the end of the struct to allow quick
74     * memcmp() comparisons.
75     */
76    struct {
77       unsigned emit:8;             /**< EMIT_x */
78       unsigned src_index:8;          /**< map to post-xform attribs */
79    } attrib[PIPE_MAX_SHADER_OUTPUTS];
80 };
81 
82 static inline size_t
draw_vinfo_size(const struct vertex_info * a)83 draw_vinfo_size( const struct vertex_info *a )
84 {
85    return offsetof(const struct vertex_info, attrib[a->num_attribs]);
86 }
87 
88 static inline int
draw_vinfo_compare(const struct vertex_info * a,const struct vertex_info * b)89 draw_vinfo_compare( const struct vertex_info *a,
90                     const struct vertex_info *b )
91 {
92    size_t sizea = draw_vinfo_size( a );
93    return memcmp( a, b, sizea );
94 }
95 
96 static inline void
draw_vinfo_copy(struct vertex_info * dst,const struct vertex_info * src)97 draw_vinfo_copy( struct vertex_info *dst,
98                  const struct vertex_info *src )
99 {
100    size_t size = draw_vinfo_size( src );
101    memcpy( dst, src, size );
102 }
103 
104 
105 
106 /**
107  * Add another attribute to the given vertex_info object.
108  * \param src_index  indicates which post-transformed vertex attrib slot
109  *                   corresponds to this attribute.
110  * \return slot in which the attribute was added
111  */
112 static inline uint
draw_emit_vertex_attr(struct vertex_info * vinfo,enum attrib_emit emit,int src_index)113 draw_emit_vertex_attr(struct vertex_info *vinfo,
114                       enum attrib_emit emit,
115                       int src_index)
116 {
117    const uint n = vinfo->num_attribs;
118 
119    /* If the src_index is negative, meaning it hasn't been found
120     * we'll assign it all zeros later - set to DRAW_ATTR_NONEXIST */
121    if (src_index < 0) {
122       src_index = DRAW_ATTR_NONEXIST;
123    }
124 
125    assert(n < ARRAY_SIZE(vinfo->attrib));
126    vinfo->attrib[n].emit = emit;
127    vinfo->attrib[n].src_index = src_index;
128    vinfo->num_attribs++;
129    return n;
130 }
131 
132 
133 extern void draw_compute_vertex_size(struct vertex_info *vinfo);
134 
135 void draw_dump_emitted_vertex(const struct vertex_info *vinfo,
136                               const uint8_t *data);
137 
138 
draw_translate_vinfo_format(enum attrib_emit emit)139 static inline enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit)
140 {
141    switch (emit) {
142    case EMIT_OMIT:
143       return PIPE_FORMAT_NONE;
144    case EMIT_1F:
145    case EMIT_1F_PSIZE:
146       return PIPE_FORMAT_R32_FLOAT;
147    case EMIT_2F:
148       return PIPE_FORMAT_R32G32_FLOAT;
149    case EMIT_3F:
150       return PIPE_FORMAT_R32G32B32_FLOAT;
151    case EMIT_4F:
152       return PIPE_FORMAT_R32G32B32A32_FLOAT;
153    case EMIT_4UB:
154       return PIPE_FORMAT_R8G8B8A8_UNORM;
155    case EMIT_4UB_BGRA:
156       return PIPE_FORMAT_B8G8R8A8_UNORM;
157    default:
158       assert(!"unexpected format");
159       return PIPE_FORMAT_NONE;
160    }
161 }
162 
draw_translate_vinfo_size(enum attrib_emit emit)163 static inline unsigned draw_translate_vinfo_size(enum attrib_emit emit)
164 {
165    switch (emit) {
166    case EMIT_OMIT:
167       return 0;
168    case EMIT_1F:
169    case EMIT_1F_PSIZE:
170       return 1 * sizeof(float);
171    case EMIT_2F:
172       return 2 * sizeof(float);
173    case EMIT_3F:
174       return 3 * sizeof(float);
175    case EMIT_4F:
176       return 4 * sizeof(float);
177    case EMIT_4UB:
178       return 4 * sizeof(unsigned char);
179    case EMIT_4UB_BGRA:
180       return 4 * sizeof(unsigned char);
181    default:
182       assert(!"unexpected format");
183       return 0;
184    }
185 }
186 
187 #endif /* DRAW_VERTEX_H */
188