From dfb6597ee45a4f09de707d4f547b1d4ecb95cdf0 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Sun, 11 Sep 2016 12:05:20 +0200 Subject: [PATCH] Begin redirecting separate params to other params. --- spirv_cross.cpp | 26 +++++++++++++++++++-- spirv_glsl.cpp | 62 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/spirv_cross.cpp b/spirv_cross.cpp index f9ee3231..998a03b7 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -2502,12 +2502,34 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar if (length < 4) return false; + // Registers sampler2D calls used in case they are parameters so + // that their callees know which combined image samplers to propagate down the call stack. + if (!functions.empty()) + { + auto &callee = *functions.top(); + if (callee.do_combined_parameters) + { + uint32_t image_id = args[2]; + + auto *image = compiler.maybe_get_backing_variable(image_id); + if (image) + image_id = image->self; + + uint32_t sampler_id = args[3]; + auto *sampler = compiler.maybe_get_backing_variable(sampler_id); + if (sampler) + sampler_id = sampler->self; + + register_combined_image_sampler(callee, image_id, sampler_id); + } + } + // For function calls, we need to remap IDs which are function parameters into global variables. // This information is statically known from the current place in the call stack. // Function parameters are not necessarily pointers, so if we don't have a backing variable, remapping will know // which backing variable the image/sample came from. - auto image_id = remap_parameter(args[2]); - auto sampler_id = remap_parameter(args[3]); + uint32_t image_id = remap_parameter(args[2]); + uint32_t sampler_id = remap_parameter(args[3]); auto itr = find_if(begin(compiler.combined_image_samplers), end(compiler.combined_image_samplers), [image_id, sampler_id](const CombinedImageSampler &combined) { diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 33f542c5..7a735de6 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -1878,11 +1878,15 @@ void CompilerGLSL::emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left, void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) { - if (options.vulkan_semantics) + if (options.vulkan_semantics && combined_image_samplers.empty()) + { emit_binary_func_op(result_type, result_id, image_id, samp_id, type_to_glsl(get(result_type)).c_str()); + } else { + auto &args = current_function->arguments; + // For GLSL and ESSL targets, we must enumerate all possible combinations for sampler2D(texture2D, sampler) and redirect // all possible combinations into new sampler2D uniforms. auto *image = maybe_get_backing_variable(image_id); @@ -1892,20 +1896,56 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i if (samp) samp_id = samp->self; - // FIXME: This must be context-dependent. - auto &mapping = combined_image_samplers; + auto image_itr = find_if(begin(args), end(args), + [image_id](const SPIRFunction::Parameter ¶m) { return param.id == image_id; }); - auto itr = find_if(begin(mapping), end(mapping), [image_id, samp_id](const CombinedImageSampler &combined) { - return combined.image_id == image_id && combined.sampler_id == samp_id; - }); + auto sampler_itr = find_if(begin(args), end(args), + [samp_id](const SPIRFunction::Parameter ¶m) { return param.id == samp_id; }); - if (itr != end(combined_image_samplers)) - emit_op(result_type, result_id, to_expression(itr->combined_id), true, false); + 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)); + uint32_t sampler_id = global_sampler ? samp_id : (sampler_itr - begin(args)); + + auto &combined = current_function->combined_parameters; + auto itr = + find_if(begin(combined), end(combined), [=](const SPIRFunction::CombinedImageSamplerParameter &p) { + return p.global_texture == global_texture && p.global_sampler == global_sampler && + p.texture_id == texture_id && p.sampler_id == sampler_id; + }); + + if (itr != end(combined)) + { + param_index = itr - begin(combined); + emit_op(result_type, result_id, join("PARAMETER", param_index), true, false); + } + else + { + throw CompilerError( + "Cannot find mapping for combined sampler parameter, was build_combined_image_samplers() used " + "before compile() was called?"); + } + } else { - //throw CompilerError("Cannot find mapping for combined sampler, was build_combined_image_samplers() used " - // "before compile() was called?"); - emit_op(result_type, result_id, "DUMMY", true, false); + // For global sampler2D, look directly at the global remapping table. + auto &mapping = combined_image_samplers; + auto itr = find_if(begin(mapping), end(mapping), [image_id, samp_id](const CombinedImageSampler &combined) { + return combined.image_id == image_id && combined.sampler_id == samp_id; + }); + + if (itr != end(combined_image_samplers)) + emit_op(result_type, result_id, to_expression(itr->combined_id), true, false); + else + { + throw CompilerError( + "Cannot find mapping for combined sampler, was build_combined_image_samplers() used " + "before compile() was called?"); + } } } }