Declare shadow arguments.
This commit is contained in:
parent
948930b171
commit
313cb5f820
@ -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;
|
||||
}
|
||||
}
|
||||
|
143
spirv_glsl.cpp
143
spirv_glsl.cpp
@ -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 ¶m) { return param.id == image_id; });
|
||||
|
||||
auto sampler_itr = find_if(begin(args), end(args),
|
||||
[samp_id](const SPIRFunction::Parameter ¶m) { 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 ¶m) { return param.id == image_id; });
|
||||
|
||||
auto sampler_itr = find_if(begin(args), end(args),
|
||||
[samp_id](const SPIRFunction::Parameter ¶m) { 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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user