typedef vector(3) int ivec3;
typedef vector(4) int ivec4;
+typedef vector(2) uint uvec2;
+typedef vector(3) uint uvec3;
+typedef vector(4) uint uvec4;
+
typedef vector(2) bool bvec2;
typedef vector(3) bool bvec3;
typedef vector(4) bool bvec4;
ivec2 min(ivec2 x, ivec2 y);
ivec3 min(ivec3 x, ivec3 y);
ivec4 min(ivec4 x, ivec4 y);
+uint min(uint x, uint y);
+uvec2 min(uvec2 x, uvec2 y);
+uvec3 min(uvec3 x, uvec3 y);
+uvec4 min(uvec4 x, uvec4 y);
vec2 min(vec2 x, float y) { return min(x, vec2(y)); }
vec3 min(vec3 x, float y) { return min(x, vec3(y)); }
vec4 min(vec4 x, float y) { return min(x, vec4(y)); }
ivec2 min(ivec2 x, int y) { return min(x, ivec2(y)); }
ivec3 min(ivec3 x, int y) { return min(x, ivec3(y)); }
ivec4 min(ivec4 x, int y) { return min(x, ivec4(y)); }
+uvec2 min(uvec2 x, uint y) { return min(x, uvec2(y)); }
+uvec3 min(uvec3 x, uint y) { return min(x, uvec3(y)); }
+uvec4 min(uvec4 x, uint y) { return min(x, uvec4(y)); }
float max(float x, float y);
vec2 max(vec2 x, vec2 y);
vec3 max(vec3 x, vec3 y);
ivec2 max(ivec2 x, ivec2 y);
ivec3 max(ivec3 x, ivec3 y);
ivec4 max(ivec4 x, ivec4 y);
+uint max(uint x, uint y);
+uvec2 max(uvec2 x, uvec2 y);
+uvec3 max(uvec3 x, uvec3 y);
+uvec4 max(uvec4 x, uvec4 y);
vec2 max(vec2 x, float y) { return max(x, vec2(y)); }
vec3 max(vec3 x, float y) { return max(x, vec3(y)); }
vec4 max(vec4 x, float y) { return max(x, vec4(y)); }
ivec2 max(ivec2 x, int y) { return max(x, ivec2(y)); }
ivec3 max(ivec3 x, int y) { return max(x, ivec3(y)); }
ivec4 max(ivec4 x, int y) { return max(x, ivec4(y)); }
+uvec2 max(uvec2 x, uint y) { return max(x, uvec2(y)); }
+uvec3 max(uvec3 x, uint y) { return max(x, uvec3(y)); }
+uvec4 max(uvec4 x, uint y) { return max(x, uvec4(y)); }
float clamp(float x, float minVal, float maxVal);
vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);
vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);
ivec2 clamp(ivec2 x, ivec2 minVal, ivec2 maxVal);
ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal);
ivec4 clamp(ivec4 x, ivec4 minVal, ivec4 maxVal);
+uint clamp(uint x, uint minVal, uint maxVal);
+uvec2 clamp(uvec2 x, uvec2 minVal, uvec2 maxVal);
+uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal);
+uvec4 clamp(uvec4 x, uvec4 minVal, uvec4 maxVal);
vec2 clamp(vec2 x, float minVal, float maxVal) { return clamp(x, vec2(minVal), vec2(maxVal)); }
vec3 clamp(vec3 x, float minVal, float maxVal) { return clamp(x, vec3(minVal), vec3(maxVal)); }
vec4 clamp(vec4 x, float minVal, float maxVal) { return clamp(x, vec4(minVal), vec4(maxVal)); }
ivec2 clamp(ivec2 x, int minVal, int maxVal) { return clamp(x, ivec2(minVal), ivec2(maxVal)); }
ivec3 clamp(ivec3 x, int minVal, int maxVal) { return clamp(x, ivec3(minVal), ivec3(maxVal)); }
ivec4 clamp(ivec4 x, int minVal, int maxVal) { return clamp(x, ivec4(minVal), ivec4(maxVal)); }
+uvec2 clamp(uvec2 x, uint minVal, uint maxVal) { return clamp(x, uvec2(minVal), uvec2(maxVal)); }
+uvec3 clamp(uvec3 x, uint minVal, uint maxVal) { return clamp(x, uvec3(minVal), uvec3(maxVal)); }
+uvec4 clamp(uvec4 x, uint minVal, uint maxVal) { return clamp(x, uvec4(minVal), uvec4(maxVal)); }
float mix(float x, float y, float a);
vec2 mix(vec2 x, vec2 y, vec2 a);
vec3 mix(vec3 x, vec3 y, vec3 a);
ivec2 mix(ivec2 x, ivec2 y, bvec2 a);
ivec3 mix(ivec3 x, ivec3 y, bvec3 a);
ivec4 mix(ivec4 x, ivec4 y, bvec4 a);
+uint mix(uint x, uint y, bool a);
+uvec2 mix(uvec2 x, uvec2 y, bvec2 a);
+uvec3 mix(uvec3 x, uvec3 y, bvec3 a);
+uvec4 mix(uvec4 x, uvec4 y, bvec4 a);
float step(float edge, float x);
vec2 step(vec2 edge, vec2 x);
vec3 step(vec3 edge, vec3 x);
bvec2 lessThan(ivec2 x, ivec2 y);
bvec3 lessThan(ivec3 x, ivec3 y);
bvec4 lessThan(ivec4 x, ivec4 y);
+bvec2 lessThan(uvec2 x, uvec2 y);
+bvec3 lessThan(uvec3 x, uvec3 y);
+bvec4 lessThan(uvec4 x, uvec4 y);
bvec2 lessThanEqual(vec2 x, vec2 y);
bvec3 lessThanEqual(vec3 x, vec3 y);
bvec4 lessThanEqual(vec4 x, vec4 y);
bvec2 lessThanEqual(ivec2 x, ivec2 y);
bvec3 lessThanEqual(ivec3 x, ivec3 y);
bvec4 lessThanEqual(ivec4 x, ivec4 y);
+bvec2 lessThanEqual(uvec2 x, uvec2 y);
+bvec3 lessThanEqual(uvec3 x, uvec3 y);
+bvec4 lessThanEqual(uvec4 x, uvec4 y);
bvec2 greaterThan(vec2 x, vec2 y);
bvec3 greaterThan(vec3 x, vec3 y);
bvec4 greaterThan(vec4 x, vec4 y);
bvec2 greaterThan(ivec2 x, ivec2 y);
bvec3 greaterThan(ivec3 x, ivec3 y);
bvec4 greaterThan(ivec4 x, ivec4 y);
+bvec2 greaterThan(uvec2 x, uvec2 y);
+bvec3 greaterThan(uvec3 x, uvec3 y);
+bvec4 greaterThan(uvec4 x, uvec4 y);
bvec2 greaterThanEqual(vec2 x, vec2 y);
bvec3 greaterThanEqual(vec3 x, vec3 y);
bvec4 greaterThanEqual(vec4 x, vec4 y);
bvec2 greaterThanEqual(ivec2 x, ivec2 y);
bvec3 greaterThanEqual(ivec3 x, ivec3 y);
bvec4 greaterThanEqual(ivec4 x, ivec4 y);
+bvec2 greaterThanEqual(uvec2 x, uvec2 y);
+bvec3 greaterThanEqual(uvec3 x, uvec3 y);
+bvec4 greaterThanEqual(uvec4 x, uvec4 y);
bvec2 equal(vec2 x, vec2 y);
bvec3 equal(vec3 x, vec3 y);
bvec4 equal(vec4 x, vec4 y);
bvec2 equal(ivec2 x, ivec2 y);
bvec3 equal(ivec3 x, ivec3 y);
bvec4 equal(ivec4 x, ivec4 y);
+bvec2 equal(uvec2 x, uvec2 y);
+bvec3 equal(uvec3 x, uvec3 y);
+bvec4 equal(uvec4 x, uvec4 y);
bvec2 notEqual(vec2 x, vec2 y);
bvec3 notEqual(vec3 x, vec3 y);
bvec4 notEqual(vec4 x, vec4 y);
bvec2 notEqual(ivec2 x, ivec2 y);
bvec3 notEqual(ivec3 x, ivec3 y);
bvec4 notEqual(ivec4 x, ivec4 y);
+bvec2 notEqual(uvec2 x, uvec2 y);
+bvec3 notEqual(uvec3 x, uvec3 y);
+bvec4 notEqual(uvec4 x, uvec4 y);
bool any(bvec2 x);
bool any(bvec3 x);
bool any(bvec4 x);
ivec2 bitfieldExtract(ivec2 value, int offset, int bits);
ivec3 bitfieldExtract(ivec3 value, int offset, int bits);
ivec4 bitfieldExtract(ivec4 value, int offset, int bits);
+uint bitfieldExtract(uint value, int offset, int bits);
+uvec2 bitfieldExtract(uvec2 value, int offset, int bits);
+uvec3 bitfieldExtract(uvec3 value, int offset, int bits);
+uvec4 bitfieldExtract(uvec4 value, int offset, int bits);
int bitfieldInsert(int value, int insert, int offset, int bits);
ivec2 bitfieldInsert(ivec2 value, ivec2 insert, int offset, int bits);
ivec3 bitfieldInsert(ivec3 value, ivec3 insert, int offset, int bits);
ivec4 bitfieldInsert(ivec4 value, ivec4 insert, int offset, int bits);
+uint bitfieldInsert(uint value, uint insert, int offset, int bits);
+uvec2 bitfieldInsert(uvec2 value, uvec2 insert, int offset, int bits);
+uvec3 bitfieldInsert(uvec3 value, uvec3 insert, int offset, int bits);
+uvec4 bitfieldInsert(uvec4 value, uvec4 insert, int offset, int bits);
int bitfieldReverse(int value);
ivec2 bitfieldReverse(ivec2 value);
ivec3 bitfieldReverse(ivec3 value);
ivec4 bitfieldReverse(ivec4 value);
+uint bitfieldReverse(uint value);
+uvec2 bitfieldReverse(uvec2 value);
+uvec3 bitfieldReverse(uvec3 value);
+uvec4 bitfieldReverse(uvec4 value);
int bitCount(int value);
ivec2 bitCount(ivec2 value);
ivec3 bitCount(ivec3 value);
ivec4 bitCount(ivec4 value);
+uint bitCount(uint value);
+uvec2 bitCount(uvec2 value);
+uvec3 bitCount(uvec3 value);
+uvec4 bitCount(uvec4 value);
int findLSB(int value);
ivec2 findLSB(ivec2 value);
ivec3 findLSB(ivec3 value);
ivec4 findLSB(ivec4 value);
+int findLSB(uint value);
+ivec2 findLSB(uvec2 value);
+ivec3 findLSB(uvec3 value);
+ivec4 findLSB(uvec4 value);
int findMSB(int value);
ivec2 findMSB(ivec2 value);
ivec3 findMSB(ivec3 value);
ivec4 findMSB(ivec4 value);
+int findMSB(uint value);
+ivec2 findMSB(uvec2 value);
+ivec3 findMSB(uvec3 value);
+ivec4 findMSB(uvec4 value);
int textureSize(sampler1D sampler, int lod);
ivec2 textureSize(sampler2D sampler, int lod);
ivec3 textureSize(sampler3D sampler, int lod);
"ivec2": { "Base": "int", "Dim": 2 },
"ivec3": { "Base": "int", "Dim": 3 },
"ivec4": { "Base": "int", "Dim": 4 },
+ "uint": { "Base": "uint", "Dim": 1, "Vec": "uvec" },
+ "uvec2": { "Base": "uint", "Dim": 2 },
+ "uvec3": { "Base": "uint", "Dim": 3 },
+ "uvec4": { "Base": "uint", "Dim": 4 },
"bool": { "Base": "bool", "Dim": 1, "Vec": "bvec" },
"bvec2": { "Base": "bool", "Dim": 2 },
"bvec3": { "Base": "bool", "Dim": 3 },
float32types = ("float",)+float32vectypes
floatvectypes = float32vectypes
floattypes = float32types
-int32vectypes = ("ivec2", "ivec3", "ivec4")
-int32types = ("int",)+int32vectypes
-signedtypes = floattypes+int32types
-arithmetictypes = signedtypes
-arithmeticvectypes = float32vectypes+int32vectypes
+sint32vectypes = ("ivec2", "ivec3", "ivec4")
+sint32types = ("int",)+sint32vectypes
+signedtypes = floattypes+sint32types
+uint32vectypes = ("uvec2", "uvec3", "uvec4")
+uint32types = ("uint",)+uint32vectypes
+int32types = sint32types+uint32types
+unsignedtypes = uint32types
+arithmetictypes = signedtypes+unsignedtypes
+arithmeticvectypes = float32vectypes+sint32vectypes+uint32vectypes
boolvectypes = ("bvec2", "bvec3", "bvec4")
squarematrixtypes = ("mat2", "mat3", "mat4")
matrixtypes = squarematrixtypes+("mat2x3", "mat3x2", "mat2x4", "mat4x2", "mat3x4", "mat4x3")
type->kind = BasicTypeDeclaration::INT;
shared_body.insert(insert_point, type);
+ type = new BasicTypeDeclaration;
+ type->source = BUILTIN_SOURCE;
+ type->name = "uint";
+ type->size = 32;
+ type->sign = false;
+ type->kind = BasicTypeDeclaration::INT;
+ shared_body.insert(insert_point, type);
+
type = new BasicTypeDeclaration;
type->source = BUILTIN_SOURCE;
type->name = "float";
set_result(static_cast<T>(value.value<bool>()));
else if(value.check_type<int>())
set_result(static_cast<T>(value.value<int>()));
+ else if(value.check_type<unsigned>())
+ set_result(static_cast<T>(value.value<unsigned>()));
else if(value.check_type<float>())
set_result(static_cast<T>(value.value<float>()));
}
literal->token = (r_constant_value.value<bool>() ? "true" : "false");
else if(r_constant_value.check_type<int>())
literal->token = lexical_cast<string>(r_constant_value.value<int>());
+ else if(r_constant_value.check_type<unsigned>())
+ literal->token = lexical_cast<string>(r_constant_value.value<unsigned>())+"u";
else if(r_constant_value.check_type<float>())
{
literal->token = lexical_cast<string>(r_constant_value.value<float>());
set_result(evaluate_logical(oper, left_value.value<bool>(), r_constant_value.value<bool>()));
else if(!oper2 && left_value.check_type<int>())
set_result(evaluate_logical(oper, left_value.value<int>(), r_constant_value.value<int>()));
+ else if(!oper2 && left_value.check_type<unsigned>())
+ set_result(evaluate_logical(oper, left_value.value<unsigned>(), r_constant_value.value<unsigned>()));
}
else if((oper=='<' || oper=='>') && oper2!=oper)
{
if(left_value.check_type<int>())
set_result(evaluate_relation(binary.oper->token, left_value.value<int>(), r_constant_value.value<int>()));
+ else if(left_value.check_type<unsigned>())
+ set_result(evaluate_relation(binary.oper->token, left_value.value<unsigned>(), r_constant_value.value<unsigned>()));
else if(left_value.check_type<float>())
set_result(evaluate_relation(binary.oper->token, left_value.value<float>(), r_constant_value.value<float>()));
}
{
if(left_value.check_type<int>())
set_result((left_value.value<int>()==r_constant_value.value<int>()) == (oper=='='));
- if(left_value.check_type<float>())
+ else if(left_value.check_type<unsigned>())
+ set_result((left_value.value<unsigned>()==r_constant_value.value<unsigned>()) == (oper=='='));
+ else if(left_value.check_type<float>())
set_result((left_value.value<float>()==r_constant_value.value<float>()) == (oper=='='));
}
else if(oper=='+' || oper=='-' || oper=='*' || oper=='/')
{
if(left_value.check_type<int>())
set_result(evaluate_arithmetic(oper, left_value.value<int>(), r_constant_value.value<int>()));
+ else if(left_value.check_type<unsigned>())
+ set_result(evaluate_arithmetic(oper, left_value.value<unsigned>(), r_constant_value.value<unsigned>()));
else if(left_value.check_type<float>())
set_result(evaluate_arithmetic(oper, left_value.value<float>(), r_constant_value.value<float>()));
}
{
if(left_value.check_type<int>())
set_result(evaluate_int_special_op(oper, left_value.value<int>(), r_constant_value.value<int>()));
+ else if(left_value.check_type<unsigned>())
+ set_result(evaluate_int_special_op(oper, left_value.value<unsigned>(), r_constant_value.value<unsigned>()));
}
}
if(basic->kind==BasicTypeDeclaration::BOOL)
convert_to_result<bool>(r_constant_value);
- else if(basic->kind==BasicTypeDeclaration::INT && basic->size==32)
+ else if(basic->kind==BasicTypeDeclaration::INT && basic->size==32 && basic->sign)
convert_to_result<int>(r_constant_value);
+ else if(basic->kind==BasicTypeDeclaration::INT && basic->size==32 && !basic->sign)
+ convert_to_result<unsigned>(r_constant_value);
else if(basic->kind==BasicTypeDeclaration::FLOAT && basic->size==32)
convert_to_result<float>(r_constant_value);
declared_types.insert("void");
declared_types.insert("bool");
declared_types.insert("int");
+ declared_types.insert("uint");
declared_types.insert("float");
}
if(isdigit(literal->token[0]))
{
// TODO have the tokenizer return the type of the token
- if(literal->token.back()=='f')
+ if(literal->token.back()=='u')
+ literal->value = lexical_cast<unsigned>(literal->token.substr(0, literal->token.size()-1));
+ else if(literal->token.back()=='f')
literal->value = lexical_cast<float>(literal->token.substr(0, literal->token.size()-1));
else if(literal->token.find('.')!=string::npos)
literal->value = lexical_cast<float>(literal->token);
return from.size<=to.size;
else if(from.kind!=to.kind)
return false;
+ else if(from.kind==BasicTypeDeclaration::INT && from.sign!=to.sign)
+ return from.sign && from.size<=to.size;
else if(is_vector_or_matrix(from) && from.size==to.size)
{
BasicTypeDeclaration *from_base = dynamic_cast<BasicTypeDeclaration *>(from.base_type);
{
if(BasicTypeDeclaration *basic1 = multi_visit(basic))
{
- if(basic1->kind!=basic.kind || basic1->size!=basic.size)
+ if(basic1->kind!=basic.kind || basic1->size!=basic.size || basic1->sign!=basic.sign)
r_result = false;
else if(basic1->base_type && basic.base_type)
compare(*basic1->base_type, *basic.base_type);
return NOT_COMPATIBLE;
}
-BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration::Kind kind, unsigned size)
+BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration::Kind kind, unsigned size, bool sign)
{
for(vector<BasicTypeDeclaration *>::const_iterator i=basic_types.begin(); i!=basic_types.end(); ++i)
- if((*i)->kind==kind && (*i)->size==size)
+ if((*i)->kind==kind && (*i)->size==size && (*i)->sign==sign)
return *i;
return 0;
}
if(literal.value.check_type<bool>())
resolve(literal, find_type(BasicTypeDeclaration::BOOL, 1), false);
else if(literal.value.check_type<int>())
- resolve(literal, find_type(BasicTypeDeclaration::INT, 32), false);
+ resolve(literal, find_type(BasicTypeDeclaration::INT, 32, true), false);
+ else if(literal.value.check_type<unsigned>())
+ resolve(literal, find_type(BasicTypeDeclaration::INT, 32, false), false);
else if(literal.value.check_type<float>())
resolve(literal, find_type(BasicTypeDeclaration::FLOAT, 32), false);
}
private:
static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
- BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
+ BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned, bool = true);
BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
{ "mod", "f", "", OP_F_MOD, { 1, 2 }, 0 },
{ "min", "ff", "GLSL.std.450", GLSL450_F_MIN, { 1, 2 }, 0 },
{ "min", "ii", "GLSL.std.450", GLSL450_S_MIN, { 1, 2 }, 0 },
+ { "min", "uu", "GLSL.std.450", GLSL450_U_MIN, { 1, 2 }, 0 },
{ "max", "ff", "GLSL.std.450", GLSL450_F_MAX, { 1, 2 }, 0 },
{ "max", "ii", "GLSL.std.450", GLSL450_S_MAX, { 1, 2 }, 0 },
+ { "max", "uu", "GLSL.std.450", GLSL450_U_MAX, { 1, 2 }, 0 },
{ "clamp", "fff", "GLSL.std.450", GLSL450_F_CLAMP, { 1, 2, 3 }, 0 },
{ "clamp", "iii", "GLSL.std.450", GLSL450_S_CLAMP, { 1, 2, 3 }, 0 },
+ { "clamp", "uuu", "GLSL.std.450", GLSL450_U_CLAMP, { 1, 2, 3 }, 0 },
{ "mix", "fff", "GLSL.std.450", GLSL450_F_MIX, { 1, 2, 3 }, 0 },
{ "mix", "ffb", "", OP_SELECT, { 3, 2, 1 }, 0 },
{ "mix", "iib", "", OP_SELECT, { 3, 2, 1 }, 0 },
+ { "mix", "uub", "", OP_SELECT, { 3, 2, 1 }, 0 },
{ "step", "ff", "GLSL.std.450", GLSL450_F_STEP, { 1, 2 }, 0 },
{ "smoothstep", "fff", "GLSL.std.450", GLSL450_F_SMOOTH_STEP, { 1, 2, 3 }, 0 },
{ "isnan", "f", "", OP_IS_NAN, { 1 }, 0 },
{ "inverse", "f", "GLSL.std.450", GLSL450_MATRIX_INVERSE, { 1 }, 0 },
{ "lessThan", "ff", "", OP_F_ORD_LESS_THAN, { 1, 2 }, 0 },
{ "lessThan", "ii", "", OP_S_LESS_THAN, { 1, 2 }, 0 },
+ { "lessThan", "uu", "", OP_U_LESS_THAN, { 1, 2 }, 0 },
{ "lessThanEqual", "ff", "", OP_F_ORD_LESS_THAN_EQUAL, { 1, 2 }, 0 },
{ "lessThanEqual", "ii", "", OP_S_LESS_THAN_EQUAL, { 1, 2 }, 0 },
+ { "lessThanEqual", "uu", "", OP_U_LESS_THAN_EQUAL, { 1, 2 }, 0 },
{ "greaterThan", "ff", "", OP_F_ORD_GREATER_THAN, { 1, 2 }, 0 },
{ "greaterThan", "ii", "", OP_S_GREATER_THAN, { 1, 2 }, 0 },
+ { "greaterThan", "uu", "", OP_U_GREATER_THAN, { 1, 2 }, 0 },
{ "greaterThanEqual", "ff", "", OP_F_ORD_GREATER_THAN_EQUAL, { 1, 2 }, 0 },
{ "greaterThanEqual", "ii", "", OP_S_GREATER_THAN_EQUAL, { 1, 2 }, 0 },
+ { "greaterThanEqual", "uu", "", OP_U_GREATER_THAN_EQUAL, { 1, 2 }, 0 },
{ "equal", "ff", "", OP_F_ORD_EQUAL, { 1, 2 }, 0 },
{ "equal", "ii", "", OP_I_EQUAL, { 1, 2 }, 0 },
+ { "equal", "uu", "", OP_I_EQUAL, { 1, 2 }, 0 },
{ "notEqual", "ff", "", OP_F_ORD_NOT_EQUAL, { 1, 2 }, 0 },
{ "notEqual", "ii", "", OP_I_NOT_EQUAL, { 1, 2 }, 0 },
+ { "notEqual", "uu", "", OP_I_NOT_EQUAL, { 1, 2 }, 0 },
{ "any", "b", "", OP_ANY, { 1 }, 0 },
{ "all", "b", "", OP_ALL, { 1 }, 0 },
{ "not", "b", "", OP_LOGICAL_NOT, { 1 }, 0 },
{ "bitfieldExtract", "iii", "", OP_BIT_FIELD_S_EXTRACT, { 1, 2, 3 }, 0 },
+ { "bitfieldExtract", "uii", "", OP_BIT_FIELD_U_EXTRACT, { 1, 2, 3 }, 0 },
{ "bitfieldInsert", "iiii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0 },
+ { "bitfieldInsert", "uuii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0 },
{ "bitfieldReverse", "i", "", OP_BIT_REVERSE, { 1 }, 0 },
+ { "bitfieldReverse", "u", "", OP_BIT_REVERSE, { 1 }, 0 },
{ "bitCount", "i", "", OP_BIT_COUNT, { 1 }, 0 },
{ "findLSB", "i", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0 },
+ { "findLSB", "u", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0 },
{ "findMSB", "i", "GLSL.std.450", GLSL450_FIND_S_MSB, { 1 }, 0 },
+ { "findMSB", "u", "GLSL.std.450", GLSL450_FIND_U_MSB, { 1 }, 0 },
{ "textureSize", "", "", OP_IMAGE_QUERY_SIZE_LOD, { 1, 2 }, 0 },
{ "texture", "", "", 0, { }, &SpirVGenerator::visit_builtin_texture },
{ "textureLod", "", "", 0, { }, &SpirVGenerator::visit_builtin_texture },
return ConstantKey(type_id, value.value<bool>());
else if(value.check_type<int>())
return ConstantKey(type_id, value.value<int>());
+ else if(value.check_type<unsigned>())
+ return ConstantKey(type_id, value.value<unsigned>());
else if(value.check_type<float>())
return ConstantKey(type_id, value.value<float>());
else
return const_id;
}
-SpirVGenerator::Id SpirVGenerator::get_standard_type_id(BasicTypeDeclaration::Kind kind, unsigned size)
+SpirVGenerator::Id SpirVGenerator::get_standard_type_id(BasicTypeDeclaration::Kind kind, unsigned size, bool sign)
{
- Id base_id = (size>1 ? get_standard_type_id(kind, 1) : 0);
- Id &type_id = standard_type_ids[TypeKey(base_id, (size>1 ? size : static_cast<unsigned>(kind)))];
+ Id base_id = (size>1 ? get_standard_type_id(kind, 1, sign) : 0);
+ Id &type_id = standard_type_ids[base_id ? TypeKey(base_id, size) : TypeKey(kind, sign)];
if(!type_id)
{
type_id = next_id++;
else if(kind==BasicTypeDeclaration::BOOL)
writer.write_op(content.globals, OP_TYPE_BOOL, type_id);
else if(kind==BasicTypeDeclaration::INT)
- writer.write_op(content.globals, OP_TYPE_INT, type_id, 32, 1);
+ writer.write_op(content.globals, OP_TYPE_INT, type_id, 32, sign);
else if(kind==BasicTypeDeclaration::FLOAT)
writer.write_op(content.globals, OP_TYPE_FLOAT, type_id, 32);
else
bool SpirVGenerator::is_scalar_type(Id type_id, BasicTypeDeclaration::Kind kind) const
{
- map<TypeKey, Id>::const_iterator i = standard_type_ids.find(TypeKey(0, kind));
+ map<TypeKey, Id>::const_iterator i = standard_type_ids.find(TypeKey(kind, true));
return (i!=standard_type_ids.end() && i->second==type_id);
}
if((oper=='<' || oper=='>') && oper2!=oper)
{
if(basic_left.kind==BasicTypeDeclaration::INT)
- opcode = (oper=='<' ? (oper2=='=' ? OP_S_LESS_THAN_EQUAL : OP_S_LESS_THAN) :
- (oper2=='=' ? OP_S_GREATER_THAN_EQUAL : OP_S_GREATER_THAN));
+ {
+ if(basic_left.sign)
+ opcode = (oper=='<' ? (oper2=='=' ? OP_S_LESS_THAN_EQUAL : OP_S_LESS_THAN) :
+ (oper2=='=' ? OP_S_GREATER_THAN_EQUAL : OP_S_GREATER_THAN));
+ else
+ opcode = (oper=='<' ? (oper2=='=' ? OP_U_LESS_THAN_EQUAL : OP_U_LESS_THAN) :
+ (oper2=='=' ? OP_U_GREATER_THAN_EQUAL : OP_U_GREATER_THAN));
+ }
else if(basic_left.kind==BasicTypeDeclaration::FLOAT)
opcode = (oper=='<' ? (oper2=='=' ? OP_F_ORD_LESS_THAN_EQUAL : OP_F_ORD_LESS_THAN) :
(oper2=='=' ? OP_F_ORD_GREATER_THAN_EQUAL : OP_F_ORD_GREATER_THAN));
else if(oper=='>' && oper2==oper && elem.kind==BasicTypeDeclaration::INT)
opcode = OP_SHIFT_RIGHT_ARITHMETIC;
else if(oper=='%' && elem.kind==BasicTypeDeclaration::INT)
- opcode = OP_S_MOD;
+ opcode = (elem.sign ? OP_S_MOD : OP_U_MOD);
else if(oper=='+' || oper=='-' || oper=='*' || oper=='/')
{
Opcode elem_op = OP_NOP;
if(elem.kind==BasicTypeDeclaration::INT)
- elem_op = (oper=='+' ? OP_I_ADD : oper=='-' ? OP_I_SUB : oper=='*' ? OP_I_MUL : OP_S_DIV);
+ {
+ if(oper=='/')
+ elem_op = (elem.sign ? OP_S_DIV : OP_U_DIV);
+ else
+ elem_op = (oper=='+' ? OP_I_ADD : oper=='-' ? OP_I_SUB : OP_I_MUL);
+ }
else if(elem.kind==BasicTypeDeclaration::FLOAT)
elem_op = (oper=='+' ? OP_F_ADD : oper=='-' ? OP_F_SUB : oper=='*' ? OP_F_MUL : OP_F_DIV);
switch(elem_arg.kind)
{
case BasicTypeDeclaration::BOOL: arg_types += 'b'; break;
- case BasicTypeDeclaration::INT: arg_types += 'i'; break;
+ case BasicTypeDeclaration::INT: arg_types += (elem_arg.sign ? 'i' : 'u'); break;
case BasicTypeDeclaration::FLOAT: arg_types += 'f'; break;
default: arg_types += '?';
}
// Scalar or vector conversion between types of equal size.
Opcode opcode;
if(elem.kind==BasicTypeDeclaration::INT && elem_arg0.kind==BasicTypeDeclaration::FLOAT)
- opcode = OP_CONVERT_F_TO_S;
+ opcode = (elem.sign ? OP_CONVERT_F_TO_S : OP_CONVERT_F_TO_U);
else if(elem.kind==BasicTypeDeclaration::FLOAT && elem_arg0.kind==BasicTypeDeclaration::INT)
- opcode = OP_CONVERT_S_TO_F;
+ opcode = (elem_arg0.sign ? OP_CONVERT_S_TO_F : OP_CONVERT_U_TO_F);
+ else if(elem.kind==BasicTypeDeclaration::INT && elem_arg0.kind==BasicTypeDeclaration::INT)
+ opcode = OP_BITCAST;
else
throw internal_error("invalid conversion");
if((elem->kind==BasicTypeDeclaration::INT || elem->kind==BasicTypeDeclaration::FLOAT) && elem->size!=32)
return false;
- Id standard_id = get_standard_type_id(elem->kind, (basic.kind==BasicTypeDeclaration::VECTOR ? basic.size : 1));
+ Id standard_id = get_standard_type_id(elem->kind, (basic.kind==BasicTypeDeclaration::VECTOR ? basic.size : 1), elem->sign);
insert_unique(declared_ids, &basic, Declaration(standard_id, 0));
writer.write_op_name(standard_id, basic.name);
switch(basic.kind)
{
case BasicTypeDeclaration::INT:
- writer.write_op(content.globals, OP_TYPE_INT, type_id, basic.size, 1);
+ writer.write_op(content.globals, OP_TYPE_INT, type_id, basic.size, basic.sign);
break;
case BasicTypeDeclaration::FLOAT:
writer.write_op(content.globals, OP_TYPE_FLOAT, type_id, basic.size);
}
+SpirVGenerator::TypeKey::TypeKey(BasicTypeDeclaration::Kind kind, bool sign):
+ type_id(0)
+{
+ switch(kind)
+ {
+ case BasicTypeDeclaration::VOID: detail = 'v'; break;
+ case BasicTypeDeclaration::BOOL: detail = 'b'; break;
+ case BasicTypeDeclaration::INT: detail = (sign ? 'i' : 'u'); break;
+ case BasicTypeDeclaration::FLOAT: detail = 'f'; break;
+ default: throw invalid_argument("TypeKey::TypeKey");
+ }
+}
+
bool SpirVGenerator::TypeKey::operator<(const TypeKey &other) const
{
if(type_id!=other.type_id)
unsigned detail;
TypeKey(Id i, unsigned d): type_id(i), detail(d) { }
+ TypeKey(BasicTypeDeclaration::Kind, bool);
bool operator<(const TypeKey &) const;
};
};
ConstantKey(Id t, int i): type_id(t), int_value(i) { }
+ ConstantKey(Id t, unsigned u): type_id(t), int_value(u) { }
ConstantKey(Id t, float f): type_id(t), float_value(f) { }
bool operator<(const ConstantKey &) const;
static ConstantKey get_constant_key(Id, const Variant &value);
Id get_constant_id(Id, const Variant &value);
Id get_vector_constant_id(Id, unsigned, Id);
- Id get_standard_type_id(BasicTypeDeclaration::Kind, unsigned);
+ Id get_standard_type_id(BasicTypeDeclaration::Kind, unsigned, bool = true);
bool is_scalar_type(Id, BasicTypeDeclaration::Kind) const;
Id get_array_type_id(TypeDeclaration &, unsigned);
Id get_pointer_type_id(Id, StorageClass);
OP_IMAGE_SAMPLE_DREF_EXPLICIT_LOD = 89,
OP_IMAGE_FETCH = 95,
OP_IMAGE_QUERY_SIZE_LOD = 103,
+ OP_CONVERT_F_TO_U = 109,
OP_CONVERT_F_TO_S = 110,
OP_CONVERT_S_TO_F = 111,
+ OP_CONVERT_U_TO_F = 112,
+ OP_BITCAST = 124,
OP_S_NEGATE = 126,
OP_F_NEGATE = 127,
OP_I_ADD = 128,
OP_F_SUB = 131,
OP_I_MUL = 132,
OP_F_MUL = 133,
+ OP_U_DIV = 134,
OP_S_DIV = 135,
OP_F_DIV = 136,
+ OP_U_MOD = 137,
OP_S_MOD = 139,
OP_F_MOD = 141,
OP_VECTOR_TIMES_SCALAR = 142,
OP_SELECT = 169,
OP_I_EQUAL = 170,
OP_I_NOT_EQUAL = 171,
+ OP_U_GREATER_THAN = 172,
OP_S_GREATER_THAN = 173,
+ OP_U_GREATER_THAN_EQUAL = 174,
OP_S_GREATER_THAN_EQUAL = 175,
+ OP_U_LESS_THAN = 176,
OP_S_LESS_THAN = 177,
+ OP_U_LESS_THAN_EQUAL = 178,
OP_S_LESS_THAN_EQUAL = 179,
OP_F_ORD_EQUAL = 180,
OP_F_ORD_NOT_EQUAL = 182,
OP_NOT = 200,
OP_BIT_FIELD_INSERT = 201,
OP_BIT_FIELD_S_EXTRACT = 202,
+ OP_BIT_FIELD_U_EXTRACT = 203,
OP_BIT_REVERSE = 204,
OP_BIT_COUNT = 205,
OP_DP_DX = 207,
GLSL450_DETERMINANT = 33,
GLSL450_MATRIX_INVERSE = 33,
GLSL450_F_MIN = 37,
+ GLSL450_U_MIN = 38,
GLSL450_S_MIN = 39,
GLSL450_F_MAX = 40,
+ GLSL450_U_MAX = 41,
GLSL450_S_MAX = 42,
GLSL450_F_CLAMP = 43,
+ GLSL450_U_CLAMP = 44,
GLSL450_S_CLAMP = 45,
GLSL450_F_MIX = 46,
GLSL450_F_STEP = 48,
GLSL450_REFRACT = 72,
GLSL450_FIND_I_LSB = 73,
GLSL450_FIND_S_MSB = 74,
+ GLSL450_FIND_U_MSB = 75,
GLSL450_INTERPOLATE_AT_CENTROID = 76,
GLSL450_INTERPOLATE_AT_SAMPLE = 77,
GLSL450_INTERPOLATE_AT_OFFSET = 78
BasicTypeDeclaration::BasicTypeDeclaration():
kind(ALIAS),
size(0),
+ sign(true),
base_type(0)
{ }
TypeDeclaration(other),
kind(other.kind),
size(other.size),
+ sign(other.sign),
base(other.base),
base_type(0)
{ }
Kind kind;
unsigned size;
+ bool sign;
std::string base;
TypeDeclaration *base_type;
if(!require_digit && iter!=source_end && *iter=='f')
number += *iter++;
}
- else if(*iter=='f')
+ else if(*iter=='u' || *iter=='f')
number += *iter++;
if(require_digit)
--- /dev/null
+uniform sampler2D tex;
+vec2 hammersley(uint i, uint count)
+{
+ float y = bitfieldReverse(i)*2.3283064e-10;
+ return vec2(float(i)/count, y);
+}
+const uint sample_count = 128;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+ gl_Position = position;
+ out vec2 texcoord = position.xy*0.5+0.5;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+ vec4 sum = vec4(0.0);
+ for(int i=0; i<sample_count; ++i)
+ sum += texture(tex, texcoord+pow(hammersley(i, sample_count), vec2(2.0)));
+ frag_color = sum/sample_count;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=0) out vec2 texcoord;
+void main()
+{
+ gl_Position = position;
+ texcoord = position.xy*0.5+0.5;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0, binding=71) uniform sampler2D tex;
+layout(location=0) out vec4 frag_color;
+layout(location=0) in vec2 texcoord;
+void main()
+{
+ vec4 sum = vec4(0.0);
+ for(int i=0; uint(i)<128u; ++i)
+ {
+ uint i_1 = uint(i);
+ sum += texture(tex, texcoord+pow(vec2(float(i_1)/128.0, float(bitfieldReverse(i_1))*2.3283064e-10), vec2(2.0)));
+ }
+ frag_color = sum/128.0;
+}
+*/