From 215d5bed27ad3de92557ae1b631695a036d29741 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 10 Apr 2022 13:03:20 +0300 Subject: [PATCH] Add multisampled texture types to the shader compiler --- builtin_data/_builtin.glsl | 8 ++++++++ scripts/builtin_funcs.py | 9 +++++++-- source/glsl/debug.cpp | 2 ++ source/glsl/parser.cpp | 2 ++ source/glsl/reflect.cpp | 2 +- source/glsl/spirv.cpp | 9 +++++++-- source/glsl/spirvconstants.h | 1 + source/glsl/syntax.h | 1 + 8 files changed, 29 insertions(+), 5 deletions(-) diff --git a/builtin_data/_builtin.glsl b/builtin_data/_builtin.glsl index 1bdfde13..b671f944 100644 --- a/builtin_data/_builtin.glsl +++ b/builtin_data/_builtin.glsl @@ -39,6 +39,8 @@ typedef image(dimensions=1[], shadow, sampled) float sampler1DArrayShadow; 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; @@ -473,6 +475,8 @@ ivec2 textureSize(samplerCubeShadow sampler, int lod); 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); @@ -499,6 +503,8 @@ int textureQueryLevels(samplerCubeShadow sampler); 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); @@ -524,6 +530,8 @@ vec4 texelFetch(sampler2D sampler, ivec2 P, int lod); 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) diff --git a/scripts/builtin_funcs.py b/scripts/builtin_funcs.py index bf5198f5..5ff3a57f 100755 --- a/scripts/builtin_funcs.py +++ b/scripts/builtin_funcs.py @@ -16,6 +16,8 @@ traits = { "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 }, @@ -62,6 +64,7 @@ matrixtypes = squarematrixtypes+("mat2x3", "mat3x2", "mat2x4", "mat4x2", "mat3x4 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 @@ -155,14 +158,16 @@ shared_funcs = [ ("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 = [ diff --git a/source/glsl/debug.cpp b/source/glsl/debug.cpp index 60b7c247..c741ed57 100644 --- a/source/glsl/debug.cpp +++ b/source/glsl/debug.cpp @@ -357,6 +357,8 @@ void DumpTree::visit(ImageTypeDeclaration &type) 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); } diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index ca1f3156..d210cee9 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -707,6 +707,8 @@ RefPtr Parser::parse_image_type_declaration() 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"); diff --git a/source/glsl/reflect.cpp b/source/glsl/reflect.cpp index 643c42e7..64dbbf6e 100644 --- a/source/glsl/reflect.cpp +++ b/source/glsl/reflect.cpp @@ -178,7 +178,7 @@ void TypeComparer::visit(ImageTypeDeclaration &image) { 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); diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index c6f15614..61e2d594 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -111,6 +111,7 @@ const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] = { "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 }, @@ -1295,6 +1296,8 @@ void SpirVGenerator::visit_builtin_texture_query(FunctionCall &call, const vecto 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"); @@ -1371,10 +1374,12 @@ void SpirVGenerator::visit_builtin_texel_fetch(FunctionCall &call, const vector< if(argument_ids.size()!=3) throw internal_error("invalid texelFetch call"); + const ImageTypeDeclaration &image = dynamic_cast(*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); } @@ -1492,7 +1497,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image) 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); diff --git a/source/glsl/spirvconstants.h b/source/glsl/spirvconstants.h index aa164b87..64daa9ff 100644 --- a/source/glsl/spirvconstants.h +++ b/source/glsl/spirvconstants.h @@ -68,6 +68,7 @@ enum SpirVOpcode 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, diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index bb002183..b6a118d6 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -366,6 +366,7 @@ struct ImageTypeDeclaration: TypeDeclaration bool array = false; bool sampled = true; bool shadow = false; + bool multisample = false; std::string base; TypeDeclaration *base_type = 0; -- 2.43.0