typedef image(dimensions=2[], shadow, sampled) float sampler2DArrayShadow;
typedef image(dimensions=cube, shadow, sampled) float samplerCubeShadow;
typedef image(dimensions=cube[], shadow, sampled) float samplerCubeArrayShadow;
+typedef image(dimensions=2, sampled, multisample) float sampler2DMS;
+typedef image(dimensions=2[], sampled, multisample) float sampler2DMSArray;
const float PI = 3.1415926535;
ivec2 textureSize(sampler1DArrayShadow sampler, int lod);
ivec3 textureSize(sampler2DArrayShadow sampler, int lod);
ivec3 textureSize(samplerCubeArrayShadow sampler, int lod);
+ivec2 textureSize(sampler2DMS sampler, int lod);
+ivec3 textureSize(sampler2DMSArray sampler, int lod);
vec2 textureQueryLod(sampler1D sampler, float P);
vec2 textureQueryLod(sampler2D sampler, vec2 P);
vec2 textureQueryLod(sampler3D sampler, vec3 P);
int textureQueryLevels(sampler1DArrayShadow sampler);
int textureQueryLevels(sampler2DArrayShadow sampler);
int textureQueryLevels(samplerCubeArrayShadow sampler);
+int textureSamples(sampler2DMS sampler);
+int textureSamples(sampler2DMSArray sampler);
vec4 texture(sampler1D sampler, float P);
vec4 texture(sampler2D sampler, vec2 P);
vec4 texture(sampler3D sampler, vec3 P);
vec4 texelFetch(sampler3D sampler, ivec3 P, int lod);
vec4 texelFetch(sampler1DArray sampler, ivec2 P, int lod);
vec4 texelFetch(sampler2DArray sampler, ivec3 P, int lod);
+vec4 texelFetch(sampler2DMS sampler, ivec2 P, int sample);
+vec4 texelFetch(sampler2DMSArray sampler, ivec3 P, int sample);
// END BUILTIN FUNCTIONS
#pragma MSP stage(vertex)
"sampler1DArrayShadow": { "CDim": 3, "IDim": 2, "LDim": 1 },
"sampler2DArrayShadow": { "CDim": 4, "IDim": 3, "LDim": 2 },
"samplerCubeArrayShadow": { "IDim": 3, "LDim": 3 },
+ "sampler2DMS": { "CDim": 2, "IDim": 2, "LDim": 2 },
+ "sampler2DMSArray": { "CDim": 3, "IDim": 3, "LDim": 2 },
"float": { "Base": "float", "Dim": 1, "Vec": "vec", "Mat": "mat" },
"vec2": { "Base": "float", "Dim": 2 },
"vec3": { "Base": "float", "Dim": 3 },
flatsamplertypes = ("sampler1D", "sampler2D", "sampler3D", "sampler1DArray", "sampler2DArray")
colorsamplertypes = flatsamplertypes+("samplerCube", "samplerCubeArray")
shadowsamplertypes = ("sampler1DShadow", "sampler2DShadow", "samplerCubeShadow", "sampler1DArrayShadow", "sampler2DArrayShadow", "samplerCubeArrayShadow")
+mssamplertypes = ("sampler2DMS", "sampler2DMSArray")
samplertypes = colorsamplertypes+shadowsamplertypes
shared_funcs = [
# Trigonometric
("int[T::Dim] findMSB(T value)", int32types),
# Texture
- ("int[T::IDim] textureSize(T sampler, int lod)", samplertypes),
+ ("int[T::IDim] textureSize(T sampler, int lod)", samplertypes+mssamplertypes),
("vec2 textureQueryLod(T sampler, float[T::LDim] P)", samplertypes),
("int textureQueryLevels(T sampler)", samplertypes),
+ ("int textureSamples(T sampler)", mssamplertypes),
("vec4 texture(T sampler, float[T::CDim] P)", colorsamplertypes),
("float texture(T sampler, float[T::CDim] P)", tuple(s for s in shadowsamplertypes if "CubeArray" not in s)),
"float texture(samplerCubeArrayShadow sampler, vec4 P, float compare)",
("vec4 textureLod(T sampler, float[T::CDim] P, float lod)", colorsamplertypes),
- ("vec4 texelFetch(T sampler, int[T::CDim] P, int lod)", flatsamplertypes)
+ ("vec4 texelFetch(T sampler, int[T::CDim] P, int lod)", flatsamplertypes),
+ ("vec4 texelFetch(T sampler, int[T::CDim] P, int sample)", mssamplertypes)
]
fragment_funcs = [
branches.emplace_back(format("Element type: %s %s", get_label(*type.base_type), format_type(type.base_type->name)));
if(type.shadow)
branches.emplace_back("Shadow");
+ if(type.multisample)
+ branches.emplace_back("Multisample");
append_subtree(branches);
}
type->sampled = true;
else if(token=="shadow")
type->shadow = true;
+ else if(token=="multisample")
+ type->multisample = true;
else
throw parse_error(tokenizer.get_location(), token, "image type attribute");
{
if(image1->dimensions!=image.dimensions || image1->array!=image.array)
r_result = false;
- else if(image1->sampled!=image.sampled || image1->shadow!=image.shadow)
+ else if(image1->sampled!=image.sampled || image1->shadow!=image.shadow || image1->multisample!=image.multisample)
r_result = false;
else if(image1->base_type && image.base_type)
compare(*image1->base_type, *image.base_type);
{ "textureSize", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
{ "textureQueryLod", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
{ "textureQueryLevels", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
+ { "textureSamples", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
{ "texture", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture },
{ "textureLod", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture },
{ "texelFetch", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texel_fetch },
opcode = OP_IMAGE_QUERY_LOD;
else if(call.name=="textureQueryLevels")
opcode = OP_IMAGE_QUERY_LEVELS;
+ else if(call.name=="textureSamples")
+ opcode = OP_IMAGE_QUERY_SAMPLES;
else
throw internal_error("invalid texture query call");
if(argument_ids.size()!=3)
throw internal_error("invalid texelFetch call");
+ const ImageTypeDeclaration &image = dynamic_cast<const ImageTypeDeclaration &>(*call.arguments[0]->type);
+
r_expression_result_id = begin_expression(OP_IMAGE_FETCH, get_id(*call.type), 4);
for(unsigned i=0; i<2; ++i)
writer.write(argument_ids[i]);
- writer.write(2); // Lod
+ writer.write(image.multisample ? 0x40 : 0x02); // Sample or Lod
writer.write(argument_ids.back());
end_expression(OP_IMAGE_FETCH);
}
writer.write(image.dimensions-1);
writer.write(image.shadow);
writer.write(image.array);
- writer.write(false); // Multisample
+ writer.write(image.multisample);
writer.write(image.sampled ? 1 : 2);
writer.write(0); // Format (unknown)
writer.end_op(OP_TYPE_IMAGE);
OP_IMAGE_QUERY_SIZE_LOD = 103,
OP_IMAGE_QUERY_LOD = 105,
OP_IMAGE_QUERY_LEVELS = 106,
+ OP_IMAGE_QUERY_SAMPLES = 107,
OP_CONVERT_F_TO_U = 109,
OP_CONVERT_F_TO_S = 110,
OP_CONVERT_S_TO_F = 111,
bool array = false;
bool sampled = true;
bool shadow = false;
+ bool multisample = false;
std::string base;
TypeDeclaration *base_type = 0;