2 * Copyright © 2009 Intel Corporation
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:
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
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.
25 * \file prog_parameter_layout.c
26 * \brief Helper functions to layout storage for program parameters
28 * \author Ian Romanick <ian.d.romanick@intel.com>
31 #include "util/imports.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"
39 _mesa_combine_swizzles(unsigned base
, unsigned applied
)
44 for (i
= 0; i
< 4; i
++) {
45 const unsigned s
= GET_SWZ(applied
, i
);
47 swiz
|= ((s
<= SWIZZLE_W
) ? GET_SWZ(base
, s
) : s
) << (i
* 3);
55 * Copy indirect access array from one parameter list to another
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
63 * The location in \c dst of the first element copied from \c src on
64 * success. -1 on failure.
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.
71 copy_indirect_accessed_array(struct gl_program_parameter_list
*src
,
72 struct gl_program_parameter_list
*dst
,
73 unsigned first
, unsigned count
)
75 const int base
= dst
->NumParameters
;
78 for (i
= first
; i
< (first
+ count
); i
++) {
79 struct gl_program_parameter
*curr
= & src
->Parameters
[i
];
81 if (curr
->Type
== PROGRAM_CONSTANT
) {
82 j
= dst
->NumParameters
;
84 for (j
= 0; j
< dst
->NumParameters
; j
++) {
85 if (memcmp(dst
->Parameters
[j
].StateIndexes
, curr
->StateIndexes
,
86 sizeof(curr
->StateIndexes
)) == 0) {
92 assert(j
== dst
->NumParameters
);
94 /* copy src parameter [i] to dest parameter [j] */
95 memcpy(&dst
->Parameters
[j
], curr
,
96 sizeof(dst
->Parameters
[j
]));
98 dst
->ParameterValueOffset
[j
] = dst
->NumParameterValues
;
100 gl_constant_value
*pv_dst
=
101 dst
->ParameterValues
+ dst
->ParameterValueOffset
[j
];
102 gl_constant_value
*pv_src
=
103 src
->ParameterValues
+ src
->ParameterValueOffset
[i
];
105 memcpy(pv_dst
, pv_src
, MIN2(src
->Parameters
[i
].Size
, 4) *
107 dst
->NumParameterValues
+= MIN2(dst
->Parameters
[j
].Size
, 4);
110 /* Pointer to the string name was copied. Null-out src param name
111 * to prevent double free later.
115 dst
->NumParameters
++;
124 * \return GL_TRUE for success, GL_FALSE for failure
127 _mesa_layout_parameters(struct asm_parser_state
*state
)
129 struct gl_program_parameter_list
*layout
;
130 struct asm_instruction
*inst
;
134 _mesa_new_parameter_list_sized(state
->prog
->Parameters
->NumParameters
);
136 /* PASS 1: Move any parameters that are accessed indirectly from the
137 * original parameter list to the new parameter list.
139 for (inst
= state
->inst_head
; inst
!= NULL
; inst
= inst
->next
) {
140 for (i
= 0; i
< 3; i
++) {
141 if (inst
->SrcReg
[i
].Base
.RelAddr
) {
142 /* Only attempt to add the to the new parameter list once.
144 if (!inst
->SrcReg
[i
].Symbol
->pass1_done
) {
145 const int new_begin
=
146 copy_indirect_accessed_array(state
->prog
->Parameters
, layout
,
147 inst
->SrcReg
[i
].Symbol
->param_binding_begin
,
148 inst
->SrcReg
[i
].Symbol
->param_binding_length
);
151 _mesa_free_parameter_list(layout
);
155 inst
->SrcReg
[i
].Symbol
->param_binding_begin
= new_begin
;
156 inst
->SrcReg
[i
].Symbol
->pass1_done
= 1;
159 /* Previously the Index was just the offset from the parameter
160 * array. Now that the base of the parameter array is known, the
161 * index can be updated to its actual value.
163 inst
->Base
.SrcReg
[i
] = inst
->SrcReg
[i
].Base
;
164 inst
->Base
.SrcReg
[i
].Index
+=
165 inst
->SrcReg
[i
].Symbol
->param_binding_begin
;
170 /* PASS 2: Move any parameters that are not accessed indirectly from the
171 * original parameter list to the new parameter list.
173 for (inst
= state
->inst_head
; inst
!= NULL
; inst
= inst
->next
) {
174 for (i
= 0; i
< 3; i
++) {
175 const struct gl_program_parameter
*p
;
176 const int idx
= inst
->SrcReg
[i
].Base
.Index
;
177 unsigned swizzle
= SWIZZLE_NOOP
;
179 /* All relative addressed operands were processed on the first
180 * pass. Just skip them here.
182 if (inst
->SrcReg
[i
].Base
.RelAddr
) {
186 if ((inst
->SrcReg
[i
].Base
.File
<= PROGRAM_OUTPUT
)
187 || (inst
->SrcReg
[i
].Base
.File
>= PROGRAM_WRITE_ONLY
)) {
191 inst
->Base
.SrcReg
[i
] = inst
->SrcReg
[i
].Base
;
192 p
= & state
->prog
->Parameters
->Parameters
[idx
];
195 case PROGRAM_CONSTANT
: {
196 unsigned pvo
= state
->prog
->Parameters
->ParameterValueOffset
[idx
];
197 const gl_constant_value
*const v
=
198 state
->prog
->Parameters
->ParameterValues
+ pvo
;
200 inst
->Base
.SrcReg
[i
].Index
=
201 _mesa_add_unnamed_constant(layout
, v
, p
->Size
, & swizzle
);
203 inst
->Base
.SrcReg
[i
].Swizzle
=
204 _mesa_combine_swizzles(swizzle
, inst
->Base
.SrcReg
[i
].Swizzle
);
208 case PROGRAM_STATE_VAR
:
209 inst
->Base
.SrcReg
[i
].Index
=
210 _mesa_add_state_reference(layout
, p
->StateIndexes
);
217 inst
->SrcReg
[i
].Base
.File
= p
->Type
;
218 inst
->Base
.SrcReg
[i
].File
= p
->Type
;
222 layout
->StateFlags
= state
->prog
->Parameters
->StateFlags
;
223 _mesa_free_parameter_list(state
->prog
->Parameters
);
224 state
->prog
->Parameters
= layout
;