From 948930b171b4d99ba424a979951769f9ef7a6b29 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Sun, 11 Sep 2016 12:36:12 +0200 Subject: [PATCH] Build new IDs for shadow arguments. --- spirv_common.hpp | 6 ++++++ spirv_cross.cpp | 31 ++++++++++++++++++++++++++++--- spirv_glsl.cpp | 4 +--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/spirv_common.hpp b/spirv_common.hpp index aab75d75..836993e7 100644 --- a/spirv_common.hpp +++ b/spirv_common.hpp @@ -448,6 +448,7 @@ struct SPIRFunction : IVariant // or a global ID. struct CombinedImageSamplerParameter { + uint32_t id; uint32_t texture_id; uint32_t sampler_id; bool global_texture; @@ -457,6 +458,11 @@ struct SPIRFunction : IVariant uint32_t return_type; uint32_t function_type; std::vector arguments; + + // Can be used by backends to add magic arguments. + // Currently used by combined image/sampler implementation. + + std::vector shadow_arguments; std::vector local_variables; uint32_t entry_block = 0; std::vector blocks; diff --git a/spirv_cross.cpp b/spirv_cross.cpp index 998a03b7..0249bbfe 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -2407,7 +2407,7 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR // or a parameter in our own function. If both are global, they will not need a parameter, // otherwise, add it to our list. SPIRFunction::CombinedImageSamplerParameter param = { - texture_id, sampler_id, true, true, + 0u, texture_id, sampler_id, true, true, }; auto texture_itr = find_if(begin(caller.arguments), end(caller.arguments), @@ -2437,7 +2437,33 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR }); if (itr == end(caller.combined_parameters)) + { + uint32_t id = compiler.increase_bound_by(2); + auto type_id = id + 0; + auto combined_id = id + 1; + auto &base = compiler.expression_type(sampler_id); + auto &type = compiler.set(type_id); + + type = base; + type.pointer = true; + type.storage = StorageClassUniformConstant; + + // Build new variable. + compiler.set(combined_id, type_id, StorageClassFunction, 0); + + // Inherit RelaxedPrecision (and potentially other useful flags if deemed relevant). + auto &new_flags = compiler.meta[combined_id].decoration.decoration_flags; + auto old_flags = compiler.meta[sampler_id].decoration.decoration_flags; + new_flags = old_flags & (1ull << DecorationRelaxedPrecision); + + param.id = combined_id; + + compiler.set_name(combined_id, + join("SPIRV_Cross_Combined", compiler.to_name(texture_id), compiler.to_name(sampler_id))); + caller.combined_parameters.push_back(param); + caller.shadow_arguments.push_back({ type_id, combined_id, 0u, 0u }); + } } bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *args, uint32_t length) @@ -2552,8 +2578,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar type.storage = StorageClassUniformConstant; // Build new variable. - auto &var = compiler.set(combined_id, type_id, StorageClassUniformConstant, 0); - var.storage = StorageClassUniformConstant; + compiler.set(combined_id, type_id, StorageClassUniformConstant, 0); // Inherit RelaxedPrecision (and potentially other useful flags if deemed relevant). auto &new_flags = compiler.meta[combined_id].decoration.decoration_flags; diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 7a735de6..0c8c2a2e 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -1905,7 +1905,6 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i if (image_itr != end(args) || sampler_itr != end(args)) { // If any parameter originates from a parameter, we will find it in our argument list. - uint32_t param_index = 0; bool global_texture = image_itr == end(args); bool global_sampler = sampler_itr == end(args); uint32_t texture_id = global_texture ? image_id : (image_itr - begin(args)); @@ -1920,8 +1919,7 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i if (itr != end(combined)) { - param_index = itr - begin(combined); - emit_op(result_type, result_id, join("PARAMETER", param_index), true, false); + emit_op(result_type, result_id, to_expression(itr->id), true, false); } else {