glx: Sync <GL/glxext.h> with Khronos
[mesa.git] / src / mesa / state_tracker / st_glsl_types.cpp
1 /*
2 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
3 * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
4 * Copyright © 2010 Intel Corporation
5 * Copyright © 2011 Bryan Cain
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27 #include "st_glsl_types.h"
28
29 /**
30 * Returns the number of places to offset the uniform index, given the type of
31 * a struct member. We use this because samplers and images have backing
32 * storeage only when they are bindless.
33 */
34 int
35 st_glsl_storage_type_size(const struct glsl_type *type, bool is_bindless)
36 {
37 unsigned int i;
38 int size;
39
40 switch (type->base_type) {
41 case GLSL_TYPE_UINT:
42 case GLSL_TYPE_INT:
43 case GLSL_TYPE_FLOAT:
44 case GLSL_TYPE_BOOL:
45 if (type->is_matrix()) {
46 return type->matrix_columns;
47 } else {
48 /* Regardless of size of vector, it gets a vec4. This is bad
49 * packing for things like floats, but otherwise arrays become a
50 * mess. Hopefully a later pass over the code can pack scalars
51 * down if appropriate.
52 */
53 return 1;
54 }
55 break;
56 case GLSL_TYPE_DOUBLE:
57 if (type->is_matrix()) {
58 if (type->vector_elements <= 2)
59 return type->matrix_columns;
60 else
61 return type->matrix_columns * 2;
62 } else {
63 /* For doubles if we have a double or dvec2 they fit in one
64 * vec4, else they need 2 vec4s.
65 */
66 if (type->vector_elements <= 2)
67 return 1;
68 else
69 return 2;
70 }
71 break;
72 case GLSL_TYPE_UINT64:
73 case GLSL_TYPE_INT64:
74 if (type->vector_elements <= 2)
75 return 1;
76 else
77 return 2;
78 case GLSL_TYPE_ARRAY:
79 assert(type->length > 0);
80 return st_glsl_storage_type_size(type->fields.array, is_bindless) *
81 type->length;
82 case GLSL_TYPE_STRUCT:
83 size = 0;
84 for (i = 0; i < type->length; i++) {
85 size += st_glsl_storage_type_size(type->fields.structure[i].type,
86 is_bindless);
87 }
88 return size;
89 case GLSL_TYPE_SAMPLER:
90 case GLSL_TYPE_IMAGE:
91 if (!is_bindless)
92 return 0;
93 /* fall through */
94 case GLSL_TYPE_SUBROUTINE:
95 return 1;
96 case GLSL_TYPE_ATOMIC_UINT:
97 case GLSL_TYPE_INTERFACE:
98 case GLSL_TYPE_VOID:
99 case GLSL_TYPE_ERROR:
100 case GLSL_TYPE_FUNCTION:
101 case GLSL_TYPE_FLOAT16:
102 case GLSL_TYPE_UINT16:
103 case GLSL_TYPE_INT16:
104 case GLSL_TYPE_UINT8:
105 case GLSL_TYPE_INT8:
106 assert(!"Invalid type in type_size");
107 break;
108 }
109 return 0;
110 }
111
112 int
113 st_glsl_type_dword_size(const struct glsl_type *type, bool bindless)
114 {
115 unsigned int size, i;
116
117 switch (type->base_type) {
118 case GLSL_TYPE_UINT:
119 case GLSL_TYPE_INT:
120 case GLSL_TYPE_FLOAT:
121 case GLSL_TYPE_BOOL:
122 return type->components();
123 case GLSL_TYPE_UINT16:
124 case GLSL_TYPE_INT16:
125 case GLSL_TYPE_FLOAT16:
126 return DIV_ROUND_UP(type->components(), 2);
127 case GLSL_TYPE_UINT8:
128 case GLSL_TYPE_INT8:
129 return DIV_ROUND_UP(type->components(), 4);
130 case GLSL_TYPE_IMAGE:
131 case GLSL_TYPE_SAMPLER:
132 if (!bindless)
133 return 0;
134 case GLSL_TYPE_DOUBLE:
135 case GLSL_TYPE_UINT64:
136 case GLSL_TYPE_INT64:
137 return type->components() * 2;
138 case GLSL_TYPE_ARRAY:
139 return st_glsl_type_dword_size(type->fields.array, bindless) *
140 type->length;
141 case GLSL_TYPE_STRUCT:
142 size = 0;
143 for (i = 0; i < type->length; i++) {
144 size += st_glsl_type_dword_size(type->fields.structure[i].type,
145 bindless);
146 }
147 return size;
148 case GLSL_TYPE_ATOMIC_UINT:
149 return 0;
150 case GLSL_TYPE_SUBROUTINE:
151 return 1;
152 case GLSL_TYPE_VOID:
153 case GLSL_TYPE_ERROR:
154 case GLSL_TYPE_INTERFACE:
155 case GLSL_TYPE_FUNCTION:
156 default:
157 unreachable("invalid type in st_glsl_type_dword_size()");
158 }
159
160 return 0;
161 }
162
163 /**
164 * Returns the type size of uniforms when !PIPE_CAP_PACKED_UNIFORMS -- each
165 * value or array element is aligned to a vec4 offset and expanded out to a
166 * vec4.
167 */
168 int
169 st_glsl_uniforms_type_size(const struct glsl_type *type, bool bindless)
170 {
171 return st_glsl_storage_type_size(type, bindless);
172 }