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