Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/reshadefx/include/effect_expression.hpp
4246 views
1
/*
2
* Copyright (C) 2014 Patrick Mours
3
* SPDX-License-Identifier: BSD-3-Clause
4
*/
5
6
#pragma once
7
8
#include "effect_token.hpp"
9
#include <cstdint>
10
11
namespace reshadefx
12
{
13
/// <summary>
14
/// Structure which encapsulates a parsed value type
15
/// </summary>
16
struct type
17
{
18
enum datatype : uint32_t
19
{
20
t_void,
21
t_bool,
22
t_min16int,
23
t_int,
24
t_min16uint,
25
t_uint,
26
t_min16float,
27
t_float,
28
t_string,
29
t_struct,
30
t_texture1d,
31
t_texture2d,
32
t_texture3d,
33
t_sampler1d_int,
34
t_sampler2d_int,
35
t_sampler3d_int,
36
t_sampler1d_uint,
37
t_sampler2d_uint,
38
t_sampler3d_uint,
39
t_sampler1d_float,
40
t_sampler2d_float,
41
t_sampler3d_float,
42
t_storage1d_int,
43
t_storage2d_int,
44
t_storage3d_int,
45
t_storage1d_uint,
46
t_storage2d_uint,
47
t_storage3d_uint,
48
t_storage1d_float,
49
t_storage2d_float,
50
t_storage3d_float,
51
t_function,
52
};
53
enum qualifier : uint32_t
54
{
55
q_extern = 1 << 0,
56
q_static = 1 << 1,
57
q_uniform = 1 << 2,
58
q_volatile = 1 << 3,
59
q_precise = 1 << 4,
60
q_groupshared = 1 << 14,
61
q_in = 1 << 5,
62
q_out = 1 << 6,
63
q_inout = q_in | q_out,
64
q_const = 1 << 8,
65
q_linear = 1 << 10,
66
q_noperspective = 1 << 11,
67
q_centroid = 1 << 12,
68
q_nointerpolation = 1 << 13,
69
};
70
71
/// <summary>
72
/// Gets the result type of an operation involving the two input types.
73
/// </summary>
74
static type merge(const type &lhs, const type &rhs);
75
76
/// <summary>
77
/// Calculates the ranking between two types which can be used to select the best matching function overload. The higher the rank, the better the match. A value of zero indicates that the types are not compatible.
78
/// </summary>
79
static unsigned int rank(const type &src, const type &dst);
80
81
/// <summary>
82
/// Returns a human-readable description of this type definition.
83
/// </summary>
84
std::string description() const;
85
86
bool has(qualifier x) const { return (qualifiers & x) == x; }
87
88
bool is_void() const { return base == t_void; }
89
bool is_boolean() const { return base == t_bool; }
90
bool is_numeric() const { return base >= t_bool && base <= t_float; }
91
bool is_integral() const { return (base >= t_bool && base <= t_uint) || (base >= t_sampler1d_int && base <= t_sampler3d_uint) || (base >= t_storage1d_int && base <= t_storage3d_uint); }
92
bool is_floating_point() const { return base == t_min16float || base == t_float || (base >= t_sampler1d_float && base <= t_sampler3d_float) || (base >= t_storage1d_float && base <= t_storage3d_float); }
93
bool is_signed() const { return base == t_min16int || base == t_int || (base >= t_sampler1d_int && base <= t_sampler3d_int) || (base >= t_storage1d_int && base <= t_storage3d_int) || is_floating_point(); }
94
bool is_unsigned() const { return base == t_min16uint || base == t_uint || (base >= t_sampler1d_uint && base <= t_sampler3d_uint) || (base >= t_storage1d_uint && base <= t_storage3d_uint); }
95
96
bool is_struct() const { return base == t_struct; }
97
bool is_object() const { return is_texture() || is_sampler() || is_storage(); }
98
bool is_texture() const { return base >= t_texture1d && base <= t_texture3d; }
99
bool is_sampler() const { return base >= t_sampler1d_int && base <= t_sampler3d_float; }
100
bool is_storage() const { return base >= t_storage1d_int && base <= t_storage3d_float; }
101
bool is_function() const { return base == t_function; }
102
103
bool is_array() const { return array_length != 0; }
104
bool is_bounded_array() const { return is_array() && array_length != 0xFFFFFFFF; }
105
bool is_unbounded_array() const { return array_length == 0xFFFFFFFF; }
106
bool is_scalar() const { return is_numeric() && !is_matrix() && !is_vector() && !is_array(); }
107
bool is_vector() const { return is_numeric() && rows > 1 && cols == 1; }
108
bool is_matrix() const { return is_numeric() && rows >= 1 && cols > 1; }
109
110
unsigned int precision() const { return base == t_min16int || base == t_min16uint || base == t_min16float ? 16 : 32; }
111
unsigned int components() const { return rows * cols; }
112
unsigned int texture_dimension() const { return base >= t_texture1d && base <= t_storage3d_float ? ((base - t_texture1d) % 3) + 1 : 0; }
113
114
friend bool operator==(const type &lhs, const type &rhs)
115
{
116
return lhs.base == rhs.base && lhs.rows == rhs.rows && lhs.cols == rhs.cols && lhs.array_length == rhs.array_length && lhs.struct_definition == rhs.struct_definition;
117
}
118
friend bool operator!=(const type &lhs, const type &rhs)
119
{
120
return !operator==(lhs, rhs);
121
}
122
123
// Underlying base type ('int', 'float', ...)
124
datatype base : 8;
125
// Number of rows if this is a vector type
126
uint32_t rows : 4;
127
// Number of columns if this is a matrix type
128
uint32_t cols : 4;
129
// Bit mask of all the qualifiers decorating the type
130
uint32_t qualifiers : 16;
131
// Number of elements if this is an array type, 0xFFFFFFFF if it is an unsized array
132
uint32_t array_length;
133
// ID of the matching struct if this is a struct type
134
uint32_t struct_definition;
135
};
136
137
/// <summary>
138
/// Structure which encapsulates a parsed constant value
139
/// </summary>
140
struct constant
141
{
142
union
143
{
144
float as_float[16];
145
int32_t as_int[16];
146
uint32_t as_uint[16];
147
};
148
149
// Optional string associated with this constant
150
std::string string_data;
151
// Optional additional elements if this is an array constant
152
std::vector<constant> array_data;
153
};
154
155
/// <summary>
156
/// Structures which keeps track of the access chain of an expression
157
/// </summary>
158
struct expression
159
{
160
struct operation
161
{
162
enum op_type
163
{
164
op_cast,
165
op_member,
166
op_dynamic_index,
167
op_constant_index,
168
op_swizzle,
169
};
170
171
op_type op;
172
reshadefx::type from, to;
173
uint32_t index;
174
signed char swizzle[4];
175
};
176
177
uint32_t base = 0;
178
reshadefx::type type = {};
179
reshadefx::constant constant = {};
180
bool is_lvalue = false;
181
bool is_constant = false;
182
reshadefx::location location;
183
std::vector<operation> chain;
184
185
/// <summary>
186
/// Initializes the expression to a l-value.
187
/// </summary>
188
/// <param name="loc">Code location of the expression.</param>
189
/// <param name="base">SSA ID of the l-value.</param>
190
/// <param name="type">Value type of the expression result.</param>
191
void reset_to_lvalue(const reshadefx::location &loc, uint32_t base, const reshadefx::type &type);
192
/// <summary>
193
/// Initializes the expression to a r-value.
194
/// </summary>
195
/// <param name="loc">Code location of the expression.</param>
196
/// <param name="base">SSA ID of the r-value.</param>
197
/// <param name="type">Value type of the expression result.</param>
198
void reset_to_rvalue(const reshadefx::location &loc, uint32_t base, const reshadefx::type &type);
199
200
/// <summary>
201
/// Initializes the expression to a constant value.
202
/// </summary>
203
/// <param name="loc">Code location of the constant expression.</param>
204
/// <param name="data">Constant value to initialize to.</param>
205
void reset_to_rvalue_constant(const reshadefx::location &loc, bool data);
206
void reset_to_rvalue_constant(const reshadefx::location &loc, float data);
207
void reset_to_rvalue_constant(const reshadefx::location &loc, int32_t data);
208
void reset_to_rvalue_constant(const reshadefx::location &loc, uint32_t data);
209
void reset_to_rvalue_constant(const reshadefx::location &loc, std::string data);
210
void reset_to_rvalue_constant(const reshadefx::location &loc, reshadefx::constant data, const reshadefx::type &type);
211
212
/// <summary>
213
/// Adds a cast operation to the current access chain.
214
/// </summary>
215
/// <param name="type">Type to cast the expression to.</param>
216
void add_cast_operation(const reshadefx::type &type);
217
/// <summary>
218
/// Adds a structure member lookup to the current access chain.
219
/// </summary>
220
/// <param name="index">Index of the member to dereference.</param>
221
/// <param name="type">Value type of the member.</param>
222
void add_member_access(unsigned int index, const reshadefx::type &type);
223
/// <summary>
224
/// Adds an index operation to the current access chain.
225
/// </summary>
226
/// <param name="index_expression">SSA ID of the indexing value.</param>
227
void add_dynamic_index_access(uint32_t index_expression);
228
/// <summary>
229
/// Adds an constant index operation to the current access chain.
230
/// </summary>
231
/// <param name="index">Constant indexing value.</param>
232
void add_constant_index_access(unsigned int index);
233
/// <summary>
234
/// Adds a swizzle operation to the current access chain.
235
/// </summary>
236
/// <param name="swizzle">Swizzle for each component. -1 = unused, 0 = x, 1 = y, 2 = z, 3 = w.</param>
237
/// <param name="length">Number of components in the swizzle. The maximum is 4.</param>
238
void add_swizzle_access(const signed char swizzle[4], unsigned int length);
239
240
/// <summary>
241
/// Applies an unary operation to this constant expression.
242
/// </summary>
243
/// <param name="op">Unary operator to apply.</param>
244
bool evaluate_constant_expression(reshadefx::tokenid op);
245
/// <summary>
246
/// Applies a binary operation to this constant expression.
247
/// </summary>
248
/// <param name="op">Binary operator to apply.</param>
249
/// <param name="rhs">Constant value to use as right-hand side of the binary operation.</param>
250
bool evaluate_constant_expression(reshadefx::tokenid op, const reshadefx::constant &rhs);
251
};
252
}
253
254