Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Copyright © 2009 Intel Corporation |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice (including the next |
||
12 | * paragraph) shall be included in all copies or substantial portions of the |
||
13 | * Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||
21 | * DEALINGS IN THE SOFTWARE. |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * \file prog_parameter_layout.c |
||
26 | * \brief Helper functions to layout storage for program parameters |
||
27 | * |
||
28 | * \author Ian Romanick |
||
29 | */ |
||
30 | |||
31 | #include "main/compiler.h" |
||
32 | #include "main/mtypes.h" |
||
33 | #include "prog_parameter.h" |
||
34 | #include "prog_parameter_layout.h" |
||
35 | #include "prog_instruction.h" |
||
36 | #include "program_parser.h" |
||
37 | |||
38 | unsigned |
||
39 | _mesa_combine_swizzles(unsigned base, unsigned applied) |
||
40 | { |
||
41 | unsigned swiz = 0; |
||
42 | unsigned i; |
||
43 | |||
44 | for (i = 0; i < 4; i++) { |
||
45 | const unsigned s = GET_SWZ(applied, i); |
||
46 | |||
47 | swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3); |
||
48 | } |
||
49 | |||
50 | return swiz; |
||
51 | } |
||
52 | |||
53 | |||
54 | /** |
||
55 | * Copy indirect access array from one parameter list to another |
||
56 | * |
||
57 | * \param src Parameter array copied from |
||
58 | * \param dst Parameter array copied to |
||
59 | * \param first Index of first element in \c src to copy |
||
60 | * \param count Number of elements to copy |
||
61 | * |
||
62 | * \return |
||
63 | * The location in \c dst of the first element copied from \c src on |
||
64 | * success. -1 on failure. |
||
65 | * |
||
66 | * \warning |
||
67 | * This function assumes that there is already enough space available in |
||
68 | * \c dst to hold all of the elements that will be copied over. |
||
69 | */ |
||
70 | static int |
||
71 | copy_indirect_accessed_array(struct gl_program_parameter_list *src, |
||
72 | struct gl_program_parameter_list *dst, |
||
73 | unsigned first, unsigned count) |
||
74 | { |
||
75 | const int base = dst->NumParameters; |
||
76 | unsigned i, j; |
||
77 | |||
78 | for (i = first; i < (first + count); i++) { |
||
79 | struct gl_program_parameter *curr = & src->Parameters[i]; |
||
80 | |||
81 | if (curr->Type == PROGRAM_CONSTANT) { |
||
82 | j = dst->NumParameters; |
||
83 | } else { |
||
84 | for (j = 0; j < dst->NumParameters; j++) { |
||
85 | if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, |
||
86 | sizeof(curr->StateIndexes)) == 0) { |
||
87 | return -1; |
||
88 | } |
||
89 | } |
||
90 | } |
||
91 | |||
92 | assert(j == dst->NumParameters); |
||
93 | |||
94 | /* copy src parameter [i] to dest parameter [j] */ |
||
95 | memcpy(& dst->Parameters[j], curr, |
||
96 | sizeof(dst->Parameters[j])); |
||
97 | memcpy(dst->ParameterValues[j], src->ParameterValues[i], |
||
98 | sizeof(GLfloat) * 4); |
||
99 | |||
100 | /* Pointer to the string name was copied. Null-out src param name |
||
101 | * to prevent double free later. |
||
102 | */ |
||
103 | curr->Name = NULL; |
||
104 | |||
105 | dst->NumParameters++; |
||
106 | } |
||
107 | |||
108 | return base; |
||
109 | } |
||
110 | |||
111 | |||
112 | /** |
||
113 | * XXX description??? |
||
114 | * \return GL_TRUE for success, GL_FALSE for failure |
||
115 | */ |
||
116 | GLboolean |
||
117 | _mesa_layout_parameters(struct asm_parser_state *state) |
||
118 | { |
||
119 | struct gl_program_parameter_list *layout; |
||
120 | struct asm_instruction *inst; |
||
121 | unsigned i; |
||
122 | |||
123 | layout = |
||
124 | _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters); |
||
125 | |||
126 | /* PASS 1: Move any parameters that are accessed indirectly from the |
||
127 | * original parameter list to the new parameter list. |
||
128 | */ |
||
129 | for (inst = state->inst_head; inst != NULL; inst = inst->next) { |
||
130 | for (i = 0; i < 3; i++) { |
||
131 | if (inst->SrcReg[i].Base.RelAddr) { |
||
132 | /* Only attempt to add the to the new parameter list once. |
||
133 | */ |
||
134 | if (!inst->SrcReg[i].Symbol->pass1_done) { |
||
135 | const int new_begin = |
||
136 | copy_indirect_accessed_array(state->prog->Parameters, layout, |
||
137 | inst->SrcReg[i].Symbol->param_binding_begin, |
||
138 | inst->SrcReg[i].Symbol->param_binding_length); |
||
139 | |||
140 | if (new_begin < 0) { |
||
141 | _mesa_free_parameter_list(layout); |
||
142 | return GL_FALSE; |
||
143 | } |
||
144 | |||
145 | inst->SrcReg[i].Symbol->param_binding_begin = new_begin; |
||
146 | inst->SrcReg[i].Symbol->pass1_done = 1; |
||
147 | } |
||
148 | |||
149 | /* Previously the Index was just the offset from the parameter |
||
150 | * array. Now that the base of the parameter array is known, the |
||
151 | * index can be updated to its actual value. |
||
152 | */ |
||
153 | inst->Base.SrcReg[i] = inst->SrcReg[i].Base; |
||
154 | inst->Base.SrcReg[i].Index += |
||
155 | inst->SrcReg[i].Symbol->param_binding_begin; |
||
156 | } |
||
157 | } |
||
158 | } |
||
159 | |||
160 | /* PASS 2: Move any parameters that are not accessed indirectly from the |
||
161 | * original parameter list to the new parameter list. |
||
162 | */ |
||
163 | for (inst = state->inst_head; inst != NULL; inst = inst->next) { |
||
164 | for (i = 0; i < 3; i++) { |
||
165 | const struct gl_program_parameter *p; |
||
166 | const int idx = inst->SrcReg[i].Base.Index; |
||
167 | unsigned swizzle = SWIZZLE_NOOP; |
||
168 | |||
169 | /* All relative addressed operands were processed on the first |
||
170 | * pass. Just skip them here. |
||
171 | */ |
||
172 | if (inst->SrcReg[i].Base.RelAddr) { |
||
173 | continue; |
||
174 | } |
||
175 | |||
176 | if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT) |
||
177 | || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { |
||
178 | continue; |
||
179 | } |
||
180 | |||
181 | inst->Base.SrcReg[i] = inst->SrcReg[i].Base; |
||
182 | p = & state->prog->Parameters->Parameters[idx]; |
||
183 | |||
184 | switch (p->Type) { |
||
185 | case PROGRAM_CONSTANT: { |
||
186 | const gl_constant_value *const v = |
||
187 | state->prog->Parameters->ParameterValues[idx]; |
||
188 | |||
189 | inst->Base.SrcReg[i].Index = |
||
190 | _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); |
||
191 | |||
192 | inst->Base.SrcReg[i].Swizzle = |
||
193 | _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle); |
||
194 | break; |
||
195 | } |
||
196 | |||
197 | case PROGRAM_STATE_VAR: |
||
198 | inst->Base.SrcReg[i].Index = |
||
199 | _mesa_add_state_reference(layout, p->StateIndexes); |
||
200 | break; |
||
201 | |||
202 | default: |
||
203 | break; |
||
204 | } |
||
205 | |||
206 | inst->SrcReg[i].Base.File = p->Type; |
||
207 | inst->Base.SrcReg[i].File = p->Type; |
||
208 | } |
||
209 | } |
||
210 | |||
211 | layout->StateFlags = state->prog->Parameters->StateFlags; |
||
212 | _mesa_free_parameter_list(state->prog->Parameters); |
||
213 | state->prog->Parameters = layout; |
||
214 | |||
215 | return GL_TRUE; |
||
216 | }=>>>>>>><>=>> |