xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r300/compiler/radeon_code.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2009 Nicolai Haehnle.
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "radeon_code.h"
7 
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "radeon_program.h"
13 
rc_constants_init(struct rc_constant_list * c)14 void rc_constants_init(struct rc_constant_list * c)
15 {
16 	memset(c, 0, sizeof(*c));
17 }
18 
19 /**
20  * Copy a constants structure, assuming that the destination structure
21  * is not initialized.
22  */
rc_constants_copy(struct rc_constant_list * dst,struct rc_constant_list * src)23 void rc_constants_copy(struct rc_constant_list * dst, struct rc_constant_list * src)
24 {
25 	dst->Constants = malloc(sizeof(struct rc_constant) * src->Count);
26 	memcpy(dst->Constants, src->Constants, sizeof(struct rc_constant) * src->Count);
27 	dst->Count = src->Count;
28 	dst->_Reserved = src->Count;
29 }
30 
rc_constants_destroy(struct rc_constant_list * c)31 void rc_constants_destroy(struct rc_constant_list * c)
32 {
33 	free(c->Constants);
34 	memset(c, 0, sizeof(*c));
35 }
36 
rc_constants_add(struct rc_constant_list * c,struct rc_constant * constant)37 unsigned rc_constants_add(struct rc_constant_list * c, struct rc_constant * constant)
38 {
39 	unsigned index = c->Count;
40 
41 	if (c->Count >= c->_Reserved) {
42 		struct rc_constant * newlist;
43 
44 		c->_Reserved = c->_Reserved * 2;
45 		if (!c->_Reserved)
46 			c->_Reserved = 16;
47 
48 		newlist = malloc(sizeof(struct rc_constant) * c->_Reserved);
49 		memcpy(newlist, c->Constants, sizeof(struct rc_constant) * c->Count);
50 
51 		free(c->Constants);
52 		c->Constants = newlist;
53 	}
54 
55 	c->Constants[index] = *constant;
56 	c->Count++;
57 
58 	return index;
59 }
60 
61 
62 /**
63  * Add a state vector to the constant list, while trying to avoid duplicates.
64  */
rc_constants_add_state(struct rc_constant_list * c,unsigned state0,unsigned state1)65 unsigned rc_constants_add_state(struct rc_constant_list * c, unsigned state0, unsigned state1)
66 {
67 	unsigned index;
68 	struct rc_constant constant;
69 
70 	for(index = 0; index < c->Count; ++index) {
71 		if (c->Constants[index].Type == RC_CONSTANT_STATE) {
72 			if (c->Constants[index].u.State[0] == state0 &&
73 			    c->Constants[index].u.State[1] == state1)
74 				return index;
75 		}
76 	}
77 
78 	memset(&constant, 0, sizeof(constant));
79 	constant.Type = RC_CONSTANT_STATE;
80 	constant.UseMask = RC_MASK_XYZW;
81 	constant.u.State[0] = state0;
82 	constant.u.State[1] = state1;
83 
84 	return rc_constants_add(c, &constant);
85 }
86 
87 
88 /**
89  * Add an immediate vector to the constant list, while trying to avoid
90  * duplicates.
91  */
rc_constants_add_immediate_vec4(struct rc_constant_list * c,const float * data)92 unsigned rc_constants_add_immediate_vec4(struct rc_constant_list * c, const float * data)
93 {
94 	unsigned index;
95 	struct rc_constant constant;
96 
97 	for(index = 0; index < c->Count; ++index) {
98 		if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
99 			if (!memcmp(c->Constants[index].u.Immediate, data, sizeof(float)*4))
100 				return index;
101 		}
102 	}
103 
104 	memset(&constant, 0, sizeof(constant));
105 	constant.Type = RC_CONSTANT_IMMEDIATE;
106 	constant.UseMask = RC_MASK_XYZW;
107 	memcpy(constant.u.Immediate, data, sizeof(float) * 4);
108 
109 	return rc_constants_add(c, &constant);
110 }
111 
112 
113 /**
114  * Add an immediate scalar to the constant list, while trying to avoid
115  * duplicates.
116  */
rc_constants_add_immediate_scalar(struct rc_constant_list * c,float data,unsigned * swizzle)117 unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle)
118 {
119 	unsigned index, free_comp;
120 	int free_index = -1;
121 	struct rc_constant constant;
122 
123 	for(index = 0; index < c->Count; ++index) {
124 		if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
125 			unsigned comp;
126 			for(comp = 0; comp < 4; ++comp) {
127 				if (c->Constants[index].UseMask & 1 << comp) {
128 					if (c->Constants[index].u.Immediate[comp] == data) {
129 						*swizzle = RC_MAKE_SWIZZLE_SMEAR(comp);
130 						return index;
131 					}
132 				} else {
133 					if (free_index == -1) {
134 						free_index = index;
135 						free_comp = comp;
136 					}
137 				}
138 			}
139 		}
140 	}
141 
142 	if (free_index >= 0) {
143 		c->Constants[free_index].u.Immediate[free_comp] = data;
144 		c->Constants[free_index].UseMask |= 1 << free_comp;
145 		*swizzle = RC_MAKE_SWIZZLE_SMEAR(free_comp);
146 		return free_index;
147 	}
148 
149 	memset(&constant, 0, sizeof(constant));
150 	constant.Type = RC_CONSTANT_IMMEDIATE;
151 	constant.UseMask = RC_MASK_X;
152 	constant.u.Immediate[0] = data;
153 	*swizzle = RC_SWIZZLE_XXXX;
154 
155 	return rc_constants_add(c, &constant);
156 }
157 
swizzle_char(unsigned swz)158 static char swizzle_char(unsigned swz)
159 {
160 	switch (swz) {
161 	case RC_SWIZZLE_X:
162 		return 'x';
163 	case RC_SWIZZLE_Y:
164 		return 'y';
165 	case RC_SWIZZLE_Z:
166 		return 'z';
167 	case RC_SWIZZLE_W:
168 		return 'w';
169 	default:
170 		return 'u';
171 	}
172 }
173 
rc_constants_print(struct rc_constant_list * c,struct const_remap * r)174 void rc_constants_print(struct rc_constant_list *c, struct const_remap *r)
175 {
176 	for (unsigned i = 0; i < c->Count; i++) {
177 		if (c->Constants[i].Type == RC_CONSTANT_IMMEDIATE) {
178 			float *values = c->Constants[i].u.Immediate;
179 			fprintf(stderr, "CONST[%u] = {", i);
180 			for (unsigned chan = 0; chan < 4; chan++) {
181 				if (c->Constants[i].UseMask & 1 << chan)
182 					fprintf(stderr, "%11.6f ", values[chan]);
183 				else
184 					fprintf(stderr, "     unused ");
185 			}
186 			fprintf(stderr, "}\n");
187 		}
188 		if (r && c->Constants[i].Type == RC_CONSTANT_EXTERNAL) {
189 			fprintf(stderr, "CONST[%u] = {", i);
190 			for (unsigned chan = 0; chan < 4; chan++) {
191 				fprintf(stderr, "CONST[%i].%c ", r[i].index[chan],
192 					swizzle_char(r[i].swizzle[chan]));
193 			}
194 			fprintf(stderr, " }\n");
195 		}
196 	}
197 }
198