Basic support for specialization constant reflection.

This commit is contained in:
Hans-Kristian Arntzen 2016-09-17 15:16:07 +02:00
parent 48ca43c8e0
commit 6bd545bc6b
4 changed files with 81 additions and 0 deletions

View File

@ -347,6 +347,16 @@ static void print_push_constant_resources(const Compiler &compiler, const vector
}
}
static void print_spec_constants(const Compiler &compiler)
{
auto spec_constants = compiler.get_specialization_constants();
fprintf(stderr, "Specialization constants\n");
fprintf(stderr, "==================\n\n");
for (auto &c : spec_constants)
fprintf(stderr, "ID: %u, Spec ID: %u\n", c.id, c.constant_id);
fprintf(stderr, "==================\n\n");
}
struct PLSArg
{
PlsFormat format;
@ -650,6 +660,7 @@ int main(int argc, char *argv[])
{
print_resources(*compiler, res);
print_push_constant_resources(*compiler, res.push_constant_buffers);
print_spec_constants(*compiler);
}
if (combined_image_samplers)

View File

@ -826,6 +826,7 @@ struct Meta
uint32_t offset = 0;
uint32_t array_stride = 0;
uint32_t input_attachment = 0;
uint32_t spec_id = 0;
bool builtin = false;
bool per_instance = false;
};

View File

@ -814,6 +814,10 @@ void Compiler::set_member_decoration(uint32_t id, uint32_t index, Decoration dec
dec.offset = argument;
break;
case DecorationSpecId:
dec.spec_id = argument;
break;
default:
break;
}
@ -855,6 +859,8 @@ uint32_t Compiler::get_member_decoration(uint32_t id, uint32_t index, Decoration
return dec.location;
case DecorationOffset:
return dec.offset;
case DecorationSpecId:
return dec.spec_id;
default:
return 0;
}
@ -892,6 +898,10 @@ void Compiler::unset_member_decoration(uint32_t id, uint32_t index, Decoration d
dec.offset = 0;
break;
case DecorationSpecId:
dec.spec_id = 0;
break;
default:
break;
}
@ -933,6 +943,10 @@ void Compiler::set_decoration(uint32_t id, Decoration decoration, uint32_t argum
dec.input_attachment = argument;
break;
case DecorationSpecId:
dec.spec_id = argument;
break;
default:
break;
}
@ -974,6 +988,8 @@ uint32_t Compiler::get_decoration(uint32_t id, Decoration decoration) const
return dec.set;
case DecorationInputAttachmentIndex:
return dec.input_attachment;
case DecorationSpecId:
return dec.spec_id;
default:
return 0;
}
@ -1005,6 +1021,14 @@ void Compiler::unset_decoration(uint32_t id, Decoration decoration)
dec.set = 0;
break;
case DecorationInputAttachmentIndex:
dec.input_attachment = 0;
break;
case DecorationSpecId:
dec.spec_id = 0;
break;
default:
break;
}
@ -2616,3 +2640,30 @@ void Compiler::build_combined_image_samplers()
CombinedImageSamplerHandler handler(*this);
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
}
vector<SpecializationConstant> Compiler::get_specialization_constants() const
{
vector<SpecializationConstant> spec_consts;
for (auto &id : ids)
{
if (id.get_type() == TypeConstant)
{
auto &c = id.get<SPIRConstant>();
if (c.specialization)
{
spec_consts.push_back({ c.self, get_decoration(c.self, DecorationSpecId) });
}
}
}
return spec_consts;
}
SPIRConstant &Compiler::get_constant(uint32_t id)
{
return get<SPIRConstant>(id);
}
const SPIRConstant &Compiler::get_constant(uint32_t id) const
{
return get<SPIRConstant>(id);
}

View File

@ -91,6 +91,14 @@ struct CombinedImageSampler
uint32_t sampler_id;
};
struct SpecializationConstant
{
// The ID of the specialization constant.
uint32_t id;
// The constant ID of the constant, used in Vulkan during pipeline creation.
uint32_t constant_id;
};
struct BufferRange
{
unsigned index;
@ -288,6 +296,16 @@ public:
variable_remap_callback = std::move(cb);
}
// API for querying which specialization constants exist.
// To modify a specialization constant before compile(), use get_constant(constant.id),
// then update constants directly in the SPIRConstant data structure.
// For composite types, the subconstants can be iterated over and modified.
// constant_type is the SPIRType for the specialization constant,
// which can be queried to determine which fields in the unions should be poked at.
std::vector<SpecializationConstant> get_specialization_constants() const;
SPIRConstant &get_constant(uint32_t id);
const SPIRConstant &get_constant(uint32_t id) const;
protected:
const uint32_t *stream(const Instruction &instr) const
{