mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
v3dv/pipeline: support for specialization constants
That it is justconvert VkSpecializationInfo to nir_spirv_specialization and pass it to spirv_to_nir. The code is also basically the same used by anv, tu, and radv Eventually it would make sense to move it to a common place. Note that we are using calloc there to allocate the temporary spec_entries. Trying to use vk_alloc2 causes some problems with the nir_validate. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
parent
03f5fae88f
commit
e7232252b7
1 changed files with 46 additions and 2 deletions
|
|
@ -357,6 +357,48 @@ preprocess_nir(nir_shader *nir,
|
|||
nir_optimize(nir, stage, false);
|
||||
}
|
||||
|
||||
/* FIXME: This is basically the same code at anv, tu and radv. Move to common
|
||||
* place?
|
||||
*/
|
||||
static struct nir_spirv_specialization*
|
||||
vk_spec_info_to_nir_spirv(const VkSpecializationInfo *spec_info,
|
||||
uint32_t *out_num_spec_entries)
|
||||
{
|
||||
if (spec_info == NULL || spec_info->mapEntryCount == 0)
|
||||
return NULL;
|
||||
|
||||
uint32_t num_spec_entries = spec_info->mapEntryCount;
|
||||
struct nir_spirv_specialization *spec_entries = calloc(num_spec_entries, sizeof(*spec_entries));
|
||||
|
||||
for (uint32_t i = 0; i < num_spec_entries; i++) {
|
||||
VkSpecializationMapEntry entry = spec_info->pMapEntries[i];
|
||||
const void *data = spec_info->pData + entry.offset;
|
||||
assert(data + entry.size <= spec_info->pData + spec_info->dataSize);
|
||||
|
||||
spec_entries[i].id = spec_info->pMapEntries[i].constantID;
|
||||
switch (entry.size) {
|
||||
case 8:
|
||||
spec_entries[i].value.u64 = *(const uint64_t *)data;
|
||||
break;
|
||||
case 4:
|
||||
spec_entries[i].value.u32 = *(const uint32_t *)data;
|
||||
break;
|
||||
case 2:
|
||||
spec_entries[i].value.u16 = *(const uint16_t *)data;
|
||||
break;
|
||||
case 1:
|
||||
spec_entries[i].value.u8 = *(const uint8_t *)data;
|
||||
break;
|
||||
default:
|
||||
assert(!"Invalid spec constant size");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*out_num_spec_entries = num_spec_entries;
|
||||
return spec_entries;
|
||||
}
|
||||
|
||||
static nir_shader *
|
||||
shader_module_compile_to_nir(struct v3dv_device *device,
|
||||
struct v3dv_pipeline_stage *stage)
|
||||
|
|
@ -372,8 +414,8 @@ shader_module_compile_to_nir(struct v3dv_device *device,
|
|||
v3dv_print_spirv(stage->module->data, stage->module->size, stderr);
|
||||
|
||||
uint32_t num_spec_entries = 0;
|
||||
struct nir_spirv_specialization *spec_entries = NULL;
|
||||
|
||||
struct nir_spirv_specialization *spec_entries =
|
||||
vk_spec_info_to_nir_spirv(stage->spec_info, &num_spec_entries);
|
||||
const struct spirv_to_nir_options spirv_options = default_spirv_options;
|
||||
nir = spirv_to_nir(spirv, stage->module->size / 4,
|
||||
spec_entries, num_spec_entries,
|
||||
|
|
@ -1070,6 +1112,7 @@ pipeline_stage_create_vs_bin(const struct v3dv_pipeline_stage *src,
|
|||
p_stage->entrypoint = src->entrypoint;
|
||||
p_stage->module = src->module;
|
||||
p_stage->nir = nir_shader_clone(NULL, src->nir);
|
||||
p_stage->spec_info = src->spec_info;
|
||||
|
||||
/* Technically we could share the hash_table, but having their own makes
|
||||
* destroy p_stage more straightforward
|
||||
|
|
@ -1366,6 +1409,7 @@ pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
|
|||
p_stage->is_coord = false;
|
||||
p_stage->entrypoint = sinfo->pName;
|
||||
p_stage->module = v3dv_shader_module_from_handle(sinfo->module);
|
||||
p_stage->spec_info = sinfo->pSpecializationInfo;
|
||||
|
||||
pipeline->active_stages |= sinfo->stage;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue