Path: blob/master/dep/reshadefx/include/effect_expression.hpp
4246 views
/*1* Copyright (C) 2014 Patrick Mours2* SPDX-License-Identifier: BSD-3-Clause3*/45#pragma once67#include "effect_token.hpp"8#include <cstdint>910namespace reshadefx11{12/// <summary>13/// Structure which encapsulates a parsed value type14/// </summary>15struct type16{17enum datatype : uint32_t18{19t_void,20t_bool,21t_min16int,22t_int,23t_min16uint,24t_uint,25t_min16float,26t_float,27t_string,28t_struct,29t_texture1d,30t_texture2d,31t_texture3d,32t_sampler1d_int,33t_sampler2d_int,34t_sampler3d_int,35t_sampler1d_uint,36t_sampler2d_uint,37t_sampler3d_uint,38t_sampler1d_float,39t_sampler2d_float,40t_sampler3d_float,41t_storage1d_int,42t_storage2d_int,43t_storage3d_int,44t_storage1d_uint,45t_storage2d_uint,46t_storage3d_uint,47t_storage1d_float,48t_storage2d_float,49t_storage3d_float,50t_function,51};52enum qualifier : uint32_t53{54q_extern = 1 << 0,55q_static = 1 << 1,56q_uniform = 1 << 2,57q_volatile = 1 << 3,58q_precise = 1 << 4,59q_groupshared = 1 << 14,60q_in = 1 << 5,61q_out = 1 << 6,62q_inout = q_in | q_out,63q_const = 1 << 8,64q_linear = 1 << 10,65q_noperspective = 1 << 11,66q_centroid = 1 << 12,67q_nointerpolation = 1 << 13,68};6970/// <summary>71/// Gets the result type of an operation involving the two input types.72/// </summary>73static type merge(const type &lhs, const type &rhs);7475/// <summary>76/// 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.77/// </summary>78static unsigned int rank(const type &src, const type &dst);7980/// <summary>81/// Returns a human-readable description of this type definition.82/// </summary>83std::string description() const;8485bool has(qualifier x) const { return (qualifiers & x) == x; }8687bool is_void() const { return base == t_void; }88bool is_boolean() const { return base == t_bool; }89bool is_numeric() const { return base >= t_bool && base <= t_float; }90bool 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); }91bool 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); }92bool 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(); }93bool 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); }9495bool is_struct() const { return base == t_struct; }96bool is_object() const { return is_texture() || is_sampler() || is_storage(); }97bool is_texture() const { return base >= t_texture1d && base <= t_texture3d; }98bool is_sampler() const { return base >= t_sampler1d_int && base <= t_sampler3d_float; }99bool is_storage() const { return base >= t_storage1d_int && base <= t_storage3d_float; }100bool is_function() const { return base == t_function; }101102bool is_array() const { return array_length != 0; }103bool is_bounded_array() const { return is_array() && array_length != 0xFFFFFFFF; }104bool is_unbounded_array() const { return array_length == 0xFFFFFFFF; }105bool is_scalar() const { return is_numeric() && !is_matrix() && !is_vector() && !is_array(); }106bool is_vector() const { return is_numeric() && rows > 1 && cols == 1; }107bool is_matrix() const { return is_numeric() && rows >= 1 && cols > 1; }108109unsigned int precision() const { return base == t_min16int || base == t_min16uint || base == t_min16float ? 16 : 32; }110unsigned int components() const { return rows * cols; }111unsigned int texture_dimension() const { return base >= t_texture1d && base <= t_storage3d_float ? ((base - t_texture1d) % 3) + 1 : 0; }112113friend bool operator==(const type &lhs, const type &rhs)114{115return lhs.base == rhs.base && lhs.rows == rhs.rows && lhs.cols == rhs.cols && lhs.array_length == rhs.array_length && lhs.struct_definition == rhs.struct_definition;116}117friend bool operator!=(const type &lhs, const type &rhs)118{119return !operator==(lhs, rhs);120}121122// Underlying base type ('int', 'float', ...)123datatype base : 8;124// Number of rows if this is a vector type125uint32_t rows : 4;126// Number of columns if this is a matrix type127uint32_t cols : 4;128// Bit mask of all the qualifiers decorating the type129uint32_t qualifiers : 16;130// Number of elements if this is an array type, 0xFFFFFFFF if it is an unsized array131uint32_t array_length;132// ID of the matching struct if this is a struct type133uint32_t struct_definition;134};135136/// <summary>137/// Structure which encapsulates a parsed constant value138/// </summary>139struct constant140{141union142{143float as_float[16];144int32_t as_int[16];145uint32_t as_uint[16];146};147148// Optional string associated with this constant149std::string string_data;150// Optional additional elements if this is an array constant151std::vector<constant> array_data;152};153154/// <summary>155/// Structures which keeps track of the access chain of an expression156/// </summary>157struct expression158{159struct operation160{161enum op_type162{163op_cast,164op_member,165op_dynamic_index,166op_constant_index,167op_swizzle,168};169170op_type op;171reshadefx::type from, to;172uint32_t index;173signed char swizzle[4];174};175176uint32_t base = 0;177reshadefx::type type = {};178reshadefx::constant constant = {};179bool is_lvalue = false;180bool is_constant = false;181reshadefx::location location;182std::vector<operation> chain;183184/// <summary>185/// Initializes the expression to a l-value.186/// </summary>187/// <param name="loc">Code location of the expression.</param>188/// <param name="base">SSA ID of the l-value.</param>189/// <param name="type">Value type of the expression result.</param>190void reset_to_lvalue(const reshadefx::location &loc, uint32_t base, const reshadefx::type &type);191/// <summary>192/// Initializes the expression to a r-value.193/// </summary>194/// <param name="loc">Code location of the expression.</param>195/// <param name="base">SSA ID of the r-value.</param>196/// <param name="type">Value type of the expression result.</param>197void reset_to_rvalue(const reshadefx::location &loc, uint32_t base, const reshadefx::type &type);198199/// <summary>200/// Initializes the expression to a constant value.201/// </summary>202/// <param name="loc">Code location of the constant expression.</param>203/// <param name="data">Constant value to initialize to.</param>204void reset_to_rvalue_constant(const reshadefx::location &loc, bool data);205void reset_to_rvalue_constant(const reshadefx::location &loc, float data);206void reset_to_rvalue_constant(const reshadefx::location &loc, int32_t data);207void reset_to_rvalue_constant(const reshadefx::location &loc, uint32_t data);208void reset_to_rvalue_constant(const reshadefx::location &loc, std::string data);209void reset_to_rvalue_constant(const reshadefx::location &loc, reshadefx::constant data, const reshadefx::type &type);210211/// <summary>212/// Adds a cast operation to the current access chain.213/// </summary>214/// <param name="type">Type to cast the expression to.</param>215void add_cast_operation(const reshadefx::type &type);216/// <summary>217/// Adds a structure member lookup to the current access chain.218/// </summary>219/// <param name="index">Index of the member to dereference.</param>220/// <param name="type">Value type of the member.</param>221void add_member_access(unsigned int index, const reshadefx::type &type);222/// <summary>223/// Adds an index operation to the current access chain.224/// </summary>225/// <param name="index_expression">SSA ID of the indexing value.</param>226void add_dynamic_index_access(uint32_t index_expression);227/// <summary>228/// Adds an constant index operation to the current access chain.229/// </summary>230/// <param name="index">Constant indexing value.</param>231void add_constant_index_access(unsigned int index);232/// <summary>233/// Adds a swizzle operation to the current access chain.234/// </summary>235/// <param name="swizzle">Swizzle for each component. -1 = unused, 0 = x, 1 = y, 2 = z, 3 = w.</param>236/// <param name="length">Number of components in the swizzle. The maximum is 4.</param>237void add_swizzle_access(const signed char swizzle[4], unsigned int length);238239/// <summary>240/// Applies an unary operation to this constant expression.241/// </summary>242/// <param name="op">Unary operator to apply.</param>243bool evaluate_constant_expression(reshadefx::tokenid op);244/// <summary>245/// Applies a binary operation to this constant expression.246/// </summary>247/// <param name="op">Binary operator to apply.</param>248/// <param name="rhs">Constant value to use as right-hand side of the binary operation.</param>249bool evaluate_constant_expression(reshadefx::tokenid op, const reshadefx::constant &rhs);250};251}252253254