anv_shader_compile_to_nir(struct anv_device *device,
struct anv_shader_module *module,
const char *entrypoint_name,
- gl_shader_stage stage)
+ gl_shader_stage stage,
+ const VkSpecializationInfo *spec_info)
{
if (strcmp(entrypoint_name, "main") != 0) {
anv_finishme("Multiple shaders per module not really supported");
assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
assert(module->size % 4 == 0);
- entry_point = spirv_to_nir(spirv, module->size / 4, NULL, 0, stage,
- entrypoint_name, nir_options);
+ uint32_t num_spec_entries = 0;
+ struct nir_spirv_specialization *spec_entries = NULL;
+ if (spec_info && spec_info->mapEntryCount > 0) {
+ num_spec_entries = spec_info->mapEntryCount;
+ spec_entries = malloc(num_spec_entries * sizeof(*spec_entries));
+ for (uint32_t i = 0; i < num_spec_entries; i++) {
+ const uint32_t *data =
+ spec_info->pData + spec_info->pMapEntries[i].offset;
+ assert((const void *)(data + 1) <=
+ spec_info->pData + spec_info->dataSize);
+
+ spec_entries[i].id = spec_info->pMapEntries[i].constantID;
+ spec_entries[i].data = *data;
+ }
+ }
+
+ entry_point = spirv_to_nir(spirv, module->size / 4,
+ spec_entries, num_spec_entries,
+ stage, entrypoint_name, nir_options);
nir = entry_point->shader;
assert(nir->stage == stage);
nir_validate_shader(nir);
+ free(spec_entries);
+
nir_lower_returns(nir);
nir_validate_shader(nir);
struct anv_shader_module *module,
const char *entrypoint,
gl_shader_stage stage,
+ const VkSpecializationInfo *spec_info,
struct brw_stage_prog_data *prog_data)
{
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
nir_shader *nir = anv_shader_compile_to_nir(pipeline->device,
- module, entrypoint, stage);
+ module, entrypoint, stage,
+ spec_info);
if (nir == NULL)
return NULL;
struct anv_pipeline_cache *cache,
const VkGraphicsPipelineCreateInfo *info,
struct anv_shader_module *module,
- const char *entrypoint)
+ const char *entrypoint,
+ const VkSpecializationInfo *spec_info)
{
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
memset(prog_data, 0, sizeof(*prog_data));
nir_shader *nir = anv_pipeline_compile(pipeline, module, entrypoint,
- MESA_SHADER_VERTEX,
+ MESA_SHADER_VERTEX, spec_info,
&prog_data->base.base);
if (nir == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
struct anv_pipeline_cache *cache,
const VkGraphicsPipelineCreateInfo *info,
struct anv_shader_module *module,
- const char *entrypoint)
+ const char *entrypoint,
+ const VkSpecializationInfo *spec_info)
{
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
memset(prog_data, 0, sizeof(*prog_data));
nir_shader *nir = anv_pipeline_compile(pipeline, module, entrypoint,
- MESA_SHADER_GEOMETRY,
+ MESA_SHADER_GEOMETRY, spec_info,
&prog_data->base.base);
if (nir == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
struct anv_pipeline_cache *cache,
const VkGraphicsPipelineCreateInfo *info,
struct anv_shader_module *module,
- const char *entrypoint)
+ const char *entrypoint,
+ const VkSpecializationInfo *spec_info)
{
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
prog_data->binding_table.render_target_start = 0;
nir_shader *nir = anv_pipeline_compile(pipeline, module, entrypoint,
- MESA_SHADER_FRAGMENT,
+ MESA_SHADER_FRAGMENT, spec_info,
&prog_data->base);
if (nir == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
struct anv_pipeline_cache *cache,
const VkComputePipelineCreateInfo *info,
struct anv_shader_module *module,
- const char *entrypoint)
+ const char *entrypoint,
+ const VkSpecializationInfo *spec_info)
{
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
prog_data->binding_table.work_groups_start = 0;
nir_shader *nir = anv_pipeline_compile(pipeline, module, entrypoint,
- MESA_SHADER_COMPUTE,
+ MESA_SHADER_COMPUTE, spec_info,
&prog_data->base);
if (nir == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
ANV_FROM_HANDLE(anv_shader_module, module,
pCreateInfo->pStages[i].module);
- const char *entrypoint = pCreateInfo->pStages[i].pName;
switch (pCreateInfo->pStages[i].stage) {
case VK_SHADER_STAGE_VERTEX_BIT:
- anv_pipeline_compile_vs(pipeline, cache, pCreateInfo, module, entrypoint);
+ anv_pipeline_compile_vs(pipeline, cache, pCreateInfo, module,
+ pCreateInfo->pStages[i].pName,
+ pCreateInfo->pStages[i].pSpecializationInfo);
break;
case VK_SHADER_STAGE_GEOMETRY_BIT:
- anv_pipeline_compile_gs(pipeline, cache, pCreateInfo, module, entrypoint);
+ anv_pipeline_compile_gs(pipeline, cache, pCreateInfo, module,
+ pCreateInfo->pStages[i].pName,
+ pCreateInfo->pStages[i].pSpecializationInfo);
break;
case VK_SHADER_STAGE_FRAGMENT_BIT:
- anv_pipeline_compile_fs(pipeline, cache, pCreateInfo, module, entrypoint);
+ anv_pipeline_compile_fs(pipeline, cache, pCreateInfo, module,
+ pCreateInfo->pStages[i].pName,
+ pCreateInfo->pStages[i].pSpecializationInfo);
break;
default:
anv_finishme("Unsupported shader stage");