From ece3438c6a1630ada39cc01ae3d54b27aacdd663 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 28 Apr 2021 14:38:55 +0300 Subject: [PATCH] Implement textureSize as a visitor function in the SPIR-V generator It requires an image as an operand, not a sampled image. --- source/glsl/spirv.cpp | 33 ++++++++++++++++++++++++++++++++- source/glsl/spirv.h | 2 ++ source/glsl/spirvconstants.h | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 33da0d5c..186521c5 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -107,7 +107,7 @@ const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] = { "findLSB", "u", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0, 0 }, { "findMSB", "i", "GLSL.std.450", GLSL450_FIND_S_MSB, { 1 }, 0, 0 }, { "findMSB", "u", "GLSL.std.450", GLSL450_FIND_U_MSB, { 1 }, 0, 0 }, - { "textureSize", "", "", OP_IMAGE_QUERY_SIZE_LOD, { 1, 2 }, CAP_IMAGE_QUERY, 0 }, + { "textureSize", "", "", 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 }, @@ -1284,6 +1284,36 @@ void SpirVGenerator::visit_builtin_matrix_comp_mult(FunctionCall &call, const ve r_expression_result_id = write_construct(get_id(*call.type), column_ids, n_columns); } +void SpirVGenerator::visit_builtin_texture_query(FunctionCall &call, const vector &argument_ids) +{ + if(argument_ids.size()<1) + throw internal_error("invalid texture query call"); + + Opcode opcode; + if(call.name=="textureSize") + opcode = OP_IMAGE_QUERY_SIZE_LOD; + else + throw internal_error("invalid texture query call"); + + ImageTypeDeclaration &image_arg0 = dynamic_cast(*call.arguments[0]->type); + + Id image_id; + if(image_arg0.sampled) + { + Id image_type_id = get_item(image_type_ids, get_id(image_arg0)); + image_id = write_expression(OP_IMAGE, image_type_id, argument_ids[0]); + } + else + image_id = argument_ids[0]; + + Id result_type_id = get_id(*call.type); + r_expression_result_id = begin_expression(opcode, result_type_id, argument_ids.size()); + writer.write(image_id); + for(unsigned i=1; i &argument_ids) { if(argument_ids.size()<2) @@ -1468,6 +1498,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image) { writer.write_op_name(type_id, image.name); writer.write_op(content.globals, OP_TYPE_SAMPLED_IMAGE, type_id, image_id); + insert_unique(image_type_ids, type_id, image_id); } if(image.dimensions==ImageTypeDeclaration::ONE) diff --git a/source/glsl/spirv.h b/source/glsl/spirv.h index c023adae..f18bf61c 100644 --- a/source/glsl/spirv.h +++ b/source/glsl/spirv.h @@ -80,6 +80,7 @@ private: std::map declared_ids; std::map declared_uniform_ids; std::map standard_type_ids; + std::map image_type_ids; std::map array_type_ids; std::map pointer_type_ids; std::map function_type_ids; @@ -149,6 +150,7 @@ private: virtual void visit(FunctionCall &); void visit_constructor(FunctionCall &, const std::vector &, bool); void visit_builtin_matrix_comp_mult(FunctionCall &, const std::vector &); + void visit_builtin_texture_query(FunctionCall &, const std::vector &); void visit_builtin_texture(FunctionCall &, const std::vector &); void visit_builtin_texel_fetch(FunctionCall &, const std::vector &); void visit_builtin_interpolate(FunctionCall &, const std::vector &); diff --git a/source/glsl/spirvconstants.h b/source/glsl/spirvconstants.h index 04d28349..3d424844 100644 --- a/source/glsl/spirvconstants.h +++ b/source/glsl/spirvconstants.h @@ -64,6 +64,7 @@ enum SpirVOpcode OP_IMAGE_SAMPLE_DREF_IMPLICIT_LOD = 89, OP_IMAGE_SAMPLE_DREF_EXPLICIT_LOD = 89, OP_IMAGE_FETCH = 95, + OP_IMAGE = 100, OP_IMAGE_QUERY_SIZE_LOD = 103, OP_CONVERT_F_TO_U = 109, OP_CONVERT_F_TO_S = 110, -- 2.43.0