From bcb5560109d881090fbc1ae8a3c01a17e7034b48 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Sat, 10 Sep 2016 13:56:36 +0200 Subject: [PATCH] Sketch out interface for combined image samplers. --- main.cpp | 16 ++++++++++++++++ spirv_cross.cpp | 4 ++++ spirv_cross.hpp | 34 ++++++++++++++++++++++++++++++++++ spirv_glsl.cpp | 6 ++++++ 4 files changed, 60 insertions(+) diff --git a/main.cpp b/main.cpp index 10fda4b4..f623d12e 100644 --- a/main.cpp +++ b/main.cpp @@ -554,6 +554,8 @@ int main(int argc, char *argv[]) unique_ptr compiler; + bool combined_image_samplers = false; + if (args.cpp) { compiler = unique_ptr(new CompilerCPP(read_spirv_file(args.input))); @@ -563,7 +565,10 @@ int main(int argc, char *argv[]) else if (args.metal) compiler = unique_ptr(new CompilerMSL(read_spirv_file(args.input))); else + { + combined_image_samplers = !args.vulkan_semantics; compiler = unique_ptr(new CompilerGLSL(read_spirv_file(args.input))); + } if (!args.entry.empty()) compiler->set_entry_point(args.entry); @@ -622,6 +627,17 @@ int main(int argc, char *argv[]) print_push_constant_resources(*compiler, res.push_constant_buffers); } + if (combined_image_samplers) + { + compiler->build_combined_image_samplers(); + // Give the remapped combined samplers new names. + for (auto &remap : compiler->get_combined_image_samplers()) + { + compiler->set_name(remap.combined_id, join("_Combined_", compiler->get_name(remap.image_id), "_", + compiler->get_name(remap.sampler_id))); + } + } + string glsl; for (uint32_t i = 0; i < args.iterations; i++) glsl = compiler->compile(); diff --git a/spirv_cross.cpp b/spirv_cross.cpp index 8fdff0cf..97eec838 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -2290,3 +2290,7 @@ bool Compiler::interface_variable_exists_in_entry_point(uint32_t id) const return find(begin(execution.interface_variables), end(execution.interface_variables), id) != end(execution.interface_variables); } + +void Compiler::build_combined_image_samplers() +{ +} diff --git a/spirv_cross.hpp b/spirv_cross.hpp index e583705d..34b8ad21 100644 --- a/spirv_cross.hpp +++ b/spirv_cross.hpp @@ -80,6 +80,16 @@ struct ShaderResources std::vector separate_samplers; }; +struct CombinedImageSampler +{ + // The ID of the sampler2D variable. + uint32_t combined_id; + // The ID of the texture2D variable. + uint32_t image_id; + // The ID of the sampler variable. + uint32_t sampler_id; +}; + struct BufferRange { unsigned index; @@ -239,6 +249,28 @@ public: uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const; spv::ExecutionModel get_execution_model() const; + // Analyzes all separate image and samplers used from the currently selected entry point, + // and re-routes them all to a combined image sampler instead. + // This is required to "support" separate image samplers in targets which do not natively support + // this feature, like GLSL/ESSL. + // + // This must be called before compile() if such remapping is desired. + // This call will add new sampled images to the SPIR-V, + // so it will appear in reflection if get_shader_resources() is called after build_combined_image_samplers. + // + // If any image/sampler remapping was found, no separate image/samplers will appear in the decompiled output, + // but will still appear in reflection. + // + // The resulting samplers will be void of any decorations like name, descriptor sets and binding points, + // so this can be added before compile() if desired. + void build_combined_image_samplers(); + + // Gets a remapping for the combined image samplers. + const std::vector &get_combined_image_samplers() const + { + return combined_image_samplers; + } + protected: const uint32_t *stream(const Instruction &instr) const { @@ -395,6 +427,8 @@ protected: // variable is part of that entry points interface. bool interface_variable_exists_in_entry_point(uint32_t id) const; + std::vector combined_image_samplers; + private: void parse(); void parse(const Instruction &i); diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index ac55cff1..4402aab2 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -1013,6 +1013,12 @@ void CompilerGLSL::emit_uniform(const SPIRVariable &var) throw CompilerError("At least ESSL 3.10 required for shader image load store."); } + // If we're remapping, only emit combined samplers. + bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; + bool separate_sampler = type.basetype == SPIRType::Sampler; + if (!combined_image_samplers.empty() && separate_image && separate_sampler) + return; + add_resource_name(var.self); statement(layout_for_variable(var), "uniform ", variable_decl(var), ";"); }