#include "anv_private.h"
#include "brw_nir.h"
#include "anv_nir.h"
-#include "glsl/nir/spirv/nir_spirv.h"
+#include "nir/spirv/nir_spirv.h"
/* Needed for SWIZZLE macros */
#include "program/prog_instruction.h"
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, 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);
nir_inline_functions(nir);
nir_validate_shader(nir);
+ /* Pick off the single entrypoint that we want */
+ foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
+ if (func != entry_point)
+ exec_node_remove(&func->node);
+ }
+ assert(exec_list_length(&nir->functions) == 1);
+ entry_point->name = ralloc_strdup(entry_point, "main");
+
+ nir_remove_dead_variables(nir, nir_var_shader_in);
+ nir_remove_dead_variables(nir, nir_var_shader_out);
+ nir_remove_dead_variables(nir, nir_var_system_value);
+ nir_validate_shader(nir);
+
+ nir_lower_outputs_to_temporaries(entry_point->shader, entry_point);
+
nir_lower_system_values(nir);
nir_validate_shader(nir);
}
/* Vulkan uses the separate-shader linking model */
nir->info.separate_shader = true;
- /* Pick off the single entrypoint that we want */
- foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
- if (func != entry_point)
- exec_node_remove(&func->node);
- }
- assert(exec_list_length(&nir->functions) == 1);
-
nir = brw_preprocess_nir(nir, compiler->scalar_stage[stage]);
nir_shader_gather_info(nir, entry_point->impl);
+ uint32_t indirect_mask = 0;
+ if (compiler->glsl_compiler_options[stage].EmitNoIndirectInput)
+ indirect_mask |= (1 << nir_var_shader_in);
+ if (compiler->glsl_compiler_options[stage].EmitNoIndirectTemp)
+ indirect_mask |= 1 << nir_var_local;
+
+ nir_lower_indirect_derefs(nir, indirect_mask);
+
return nir;
}
static void
populate_wm_prog_key(const struct brw_device_info *devinfo,
const VkGraphicsPipelineCreateInfo *info,
+ const struct anv_graphics_pipeline_create_info *extra,
struct brw_wm_prog_key *key)
{
ANV_FROM_HANDLE(anv_render_pass, render_pass, info->renderPass);
key->drawable_height = 0;
key->render_to_fbo = false;
- key->nr_color_regions = render_pass->subpasses[info->subpass].color_count;
+ if (extra && extra->color_attachment_count >= 0) {
+ key->nr_color_regions = extra->color_attachment_count;
+ } else {
+ key->nr_color_regions =
+ render_pass->subpasses[info->subpass].color_count;
+ }
key->replicate_alpha = key->nr_color_regions > 1 &&
info->pMultisampleState &&
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);
ralloc_steal(mem_ctx, nir);
prog_data->inputs_read = nir->info.inputs_read;
- pipeline->writes_point_size = nir->info.outputs_written & VARYING_SLOT_PSIZ;
+ if (nir->info.outputs_written & (1ull << VARYING_SLOT_PSIZ))
+ pipeline->writes_point_size = true;
brw_compute_vue_map(&pipeline->device->info,
&prog_data->base.vue_map,
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);
if (module->nir == NULL)
ralloc_steal(mem_ctx, nir);
+ if (nir->info.outputs_written & (1ull << VARYING_SLOT_PSIZ))
+ pipeline->writes_point_size = true;
+
brw_compute_vue_map(&pipeline->device->info,
&prog_data->base.vue_map,
nir->info.outputs_written,
anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
struct anv_pipeline_cache *cache,
const VkGraphicsPipelineCreateInfo *info,
+ const struct anv_graphics_pipeline_create_info *extra,
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;
struct brw_wm_prog_data *prog_data = &pipeline->wm_prog_data;
struct brw_wm_prog_key key;
- populate_wm_prog_key(&pipeline->device->info, info, &key);
+ populate_wm_prog_key(&pipeline->device->info, info, extra, &key);
if (pipeline->use_repclear)
key.nr_color_regions = 1;
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);
+ prog_data->base.total_shared = nir->num_shared;
+
void *mem_ctx = ralloc_context(NULL);
if (module->nir == NULL)
if (pCreateInfo->pTessellationState)
anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
- if (pCreateInfo->pMultisampleState &&
- pCreateInfo->pMultisampleState->rasterizationSamples > 1)
- anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
pipeline->use_repclear = extra && extra->use_repclear;
pipeline->writes_point_size = false;
pipeline->vs_simd8 = NO_KERNEL;
pipeline->vs_vec4 = NO_KERNEL;
pipeline->gs_kernel = NO_KERNEL;
+ pipeline->ps_ksp0 = NO_KERNEL;
pipeline->active_stages = 0;
pipeline->total_scratch = 0;
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, extra, module,
+ pCreateInfo->pStages[i].pName,
+ pCreateInfo->pStages[i].pSpecializationInfo);
break;
default:
anv_finishme("Unsupported shader stage");
if (extra && extra->use_rectlist)
pipeline->topology = _3DPRIM_RECTLIST;
+ while (anv_block_pool_size(&device->scratch_block_pool) <
+ pipeline->total_scratch)
+ anv_block_pool_alloc(&device->scratch_block_pool);
+
return VK_SUCCESS;
}