Declare shadow arguments.

This commit is contained in:
Hans-Kristian Arntzen 2016-09-11 12:54:08 +02:00
parent 948930b171
commit 313cb5f820
3 changed files with 97 additions and 70 deletions

View File

@ -2438,18 +2438,26 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR
if (itr == end(caller.combined_parameters))
{
uint32_t id = compiler.increase_bound_by(2);
uint32_t id = compiler.increase_bound_by(3);
auto type_id = id + 0;
auto combined_id = id + 1;
auto &base = compiler.expression_type(sampler_id);
auto ptr_type_id = id + 1;
auto combined_id = id + 2;
auto &base = compiler.expression_type(texture_id);
auto &type = compiler.set<SPIRType>(type_id);
auto &ptr_type = compiler.set<SPIRType>(ptr_type_id);
type = base;
type.pointer = true;
type.storage = StorageClassUniformConstant;
type.self = type_id;
type.basetype = SPIRType::SampledImage;
type.pointer = false;
type.storage = StorageClassGeneric;
ptr_type = type;
ptr_type.pointer = true;
ptr_type.storage = StorageClassUniformConstant;
// Build new variable.
compiler.set<SPIRVariable>(combined_id, type_id, StorageClassFunction, 0);
compiler.set<SPIRVariable>(combined_id, ptr_type_id, StorageClassFunction, 0);
// Inherit RelaxedPrecision (and potentially other useful flags if deemed relevant).
auto &new_flags = compiler.meta[combined_id].decoration.decoration_flags;
@ -2462,7 +2470,7 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR
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 });
caller.shadow_arguments.push_back({ ptr_type_id, combined_id, 0u, 0u });
}
}
@ -2599,6 +2607,7 @@ void Compiler::build_combined_image_samplers()
{
auto &func = id.get<SPIRFunction>();
func.combined_parameters.clear();
func.shadow_arguments.clear();
func.do_combined_parameters = true;
}
}

View File

@ -1876,6 +1876,66 @@ void CompilerGLSL::emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left,
emit_trinary_func_op(result_type, id, left, right, lerp, "mix");
}
string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_id)
{
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);
auto *samp = maybe_get_backing_variable(samp_id);
if (image)
image_id = image->self;
if (samp)
samp_id = samp->self;
auto image_itr = find_if(begin(args), end(args),
[image_id](const SPIRFunction::Parameter &param) { return param.id == image_id; });
auto sampler_itr = find_if(begin(args), end(args),
[samp_id](const SPIRFunction::Parameter &param) { return param.id == samp_id; });
if (image_itr != end(args) || sampler_itr != end(args))
{
// If any parameter originates from a parameter, we will find it in our argument list.
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))
return to_expression(itr->id);
else
{
throw CompilerError(
"Cannot find mapping for combined sampler parameter, was build_combined_image_samplers() used "
"before compile() was called?");
}
}
else
{
// 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))
return to_expression(itr->combined_id);
else
{
throw CompilerError("Cannot find mapping for combined sampler, was build_combined_image_samplers() used "
"before compile() was called?");
}
}
}
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 && combined_image_samplers.empty())
@ -1884,68 +1944,7 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i
type_to_glsl(get<SPIRType>(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);
auto *samp = maybe_get_backing_variable(samp_id);
if (image)
image_id = image->self;
if (samp)
samp_id = samp->self;
auto image_itr = find_if(begin(args), end(args),
[image_id](const SPIRFunction::Parameter &param) { return param.id == image_id; });
auto sampler_itr = find_if(begin(args), end(args),
[samp_id](const SPIRFunction::Parameter &param) { return param.id == samp_id; });
if (image_itr != end(args) || sampler_itr != end(args))
{
// If any parameter originates from a parameter, we will find it in our argument list.
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))
{
emit_op(result_type, result_id, to_expression(itr->id), true, false);
}
else
{
throw CompilerError(
"Cannot find mapping for combined sampler parameter, was build_combined_image_samplers() used "
"before compile() was called?");
}
}
else
{
// 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?");
}
}
}
emit_op(result_type, result_id, to_combined_image_sampler(image_id, samp_id), true, false);
}
void CompilerGLSL::emit_texture_op(const Instruction &i)
@ -4672,7 +4671,25 @@ void CompilerGLSL::emit_function_prototype(SPIRFunction &func, uint64_t return_f
add_local_variable_name(arg.id);
decl += argument_decl(arg);
if (&arg != &func.arguments.back())
if (&arg != &func.arguments.back() || !func.shadow_arguments.empty())
decl += ", ";
// Hold a pointer to the parameter so we can invalidate the readonly field if needed.
auto *var = maybe_get<SPIRVariable>(arg.id);
if (var)
var->parameter = &arg;
}
for (auto &arg : func.shadow_arguments)
{
// Might change the variable name if it already exists in this function.
// SPIRV OpName doesn't have any semantic effect, so it's valid for an implementation
// to use same name for variables.
// Since we want to make the GLSL debuggable and somewhat sane, use fallback names for variables which are duplicates.
add_local_variable_name(arg.id);
decl += argument_decl(arg);
if (&arg != &func.shadow_arguments.back())
decl += ", ";
// Hold a pointer to the parameter so we can invalidate the readonly field if needed.

View File

@ -291,6 +291,7 @@ protected:
std::string layout_for_member(const SPIRType &type, uint32_t index);
uint64_t combined_decoration_for_member(const SPIRType &type, uint32_t index);
std::string layout_for_variable(const SPIRVariable &variable);
std::string to_combined_image_sampler(uint32_t image_id, uint32_t samp_id);
bool ssbo_is_std430_packing(const SPIRType &type);
uint32_t type_to_std430_base_size(const SPIRType &type);