Sketch out interface for combined image samplers.

This commit is contained in:
Hans-Kristian Arntzen 2016-09-10 13:56:36 +02:00
parent e92020819e
commit bcb5560109
4 changed files with 60 additions and 0 deletions

View File

@ -554,6 +554,8 @@ int main(int argc, char *argv[])
unique_ptr<CompilerGLSL> compiler;
bool combined_image_samplers = false;
if (args.cpp)
{
compiler = unique_ptr<CompilerGLSL>(new CompilerCPP(read_spirv_file(args.input)));
@ -563,7 +565,10 @@ int main(int argc, char *argv[])
else if (args.metal)
compiler = unique_ptr<CompilerMSL>(new CompilerMSL(read_spirv_file(args.input)));
else
{
combined_image_samplers = !args.vulkan_semantics;
compiler = unique_ptr<CompilerGLSL>(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();

View File

@ -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()
{
}

View File

@ -80,6 +80,16 @@ struct ShaderResources
std::vector<Resource> 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<CombinedImageSampler> &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<CombinedImageSampler> combined_image_samplers;
private:
void parse();
void parse(const Instruction &i);

View File

@ -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), ";");
}