NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS_V(nir, nir_lower_returns);
NIR_PASS_V(nir, nir_inline_functions);
+ NIR_PASS_V(nir, nir_copy_prop);
NIR_PASS_V(nir, nir_opt_deref);
/* Pick off the single entrypoint that we want */
NIR_PASS_V(nir, nir_split_per_member_structs);
NIR_PASS_V(nir, nir_remove_dead_variables,
- nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
+ nir_var_shader_in | nir_var_shader_out | nir_var_system_value,
+ NULL);
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_lower_io_to_temporaries,
return nir;
}
+VkResult
+anv_pipeline_init(struct anv_pipeline *pipeline,
+ struct anv_device *device,
+ enum anv_pipeline_type type,
+ VkPipelineCreateFlags flags,
+ const VkAllocationCallbacks *pAllocator)
+{
+ VkResult result;
+
+ memset(pipeline, 0, sizeof(*pipeline));
+
+ vk_object_base_init(&device->vk, &pipeline->base,
+ VK_OBJECT_TYPE_PIPELINE);
+ pipeline->device = device;
+
+ /* It's the job of the child class to provide actual backing storage for
+ * the batch by setting batch.start, batch.next, and batch.end.
+ */
+ pipeline->batch.alloc = pAllocator ? pAllocator : &device->vk.alloc;
+ pipeline->batch.relocs = &pipeline->batch_relocs;
+ pipeline->batch.status = VK_SUCCESS;
+
+ result = anv_reloc_list_init(&pipeline->batch_relocs,
+ pipeline->batch.alloc);
+ if (result != VK_SUCCESS)
+ return result;
+
+ pipeline->mem_ctx = ralloc_context(NULL);
+
+ pipeline->type = type;
+ pipeline->flags = flags;
+
+ util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
+
+ return VK_SUCCESS;
+}
+
+void
+anv_pipeline_finish(struct anv_pipeline *pipeline,
+ struct anv_device *device,
+ const VkAllocationCallbacks *pAllocator)
+{
+ anv_reloc_list_finish(&pipeline->batch_relocs,
+ pAllocator ? pAllocator : &device->vk.alloc);
+ ralloc_free(pipeline->mem_ctx);
+ vk_object_base_finish(&pipeline->base);
+}
+
void anv_DestroyPipeline(
VkDevice _device,
VkPipeline _pipeline,
if (!pipeline)
return;
- anv_reloc_list_finish(&pipeline->batch_relocs,
- pAllocator ? pAllocator : &device->vk.alloc);
-
- ralloc_free(pipeline->mem_ctx);
-
switch (pipeline->type) {
case ANV_PIPELINE_GRAPHICS: {
struct anv_graphics_pipeline *gfx_pipeline =
unreachable("invalid pipeline type");
}
- vk_object_base_finish(&pipeline->base);
+ anv_pipeline_finish(pipeline, device, pAllocator);
vk_free2(&device->vk.alloc, pAllocator, pipeline);
}
/* XXX Vulkan doesn't appear to specify */
key->clamp_fragment_color = false;
+ key->ignore_sample_mask_out = false;
+
assert(subpass->color_count <= MAX_RTS);
for (uint32_t i = 0; i < subpass->color_count; i++) {
if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED)
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS_V(nir, nir_lower_wpos_center,
anv_pipeline_to_graphics(pipeline)->sample_shading_enable);
- NIR_PASS_V(nir, nir_lower_input_attachments, true);
+ NIR_PASS_V(nir, nir_lower_input_attachments,
+ &(nir_input_attachment_options) {
+ .use_fragcoord_sysval = true,
+ .use_layer_id_sysval = true,
+ });
}
NIR_PASS_V(nir, anv_nir_lower_ycbcr_textures, layout);
*/
nir_function_impl *impl = nir_shader_get_entrypoint(stage->nir);
bool deleted_output = false;
- nir_foreach_variable_safe(var, &stage->nir->outputs) {
+ nir_foreach_shader_out_variable_safe(var, stage->nir) {
/* TODO: We don't delete depth/stencil writes. We probably could if the
* subpass doesn't have a depth/stencil attachment.
*/
}
}
+ if (info->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)
+ return VK_PIPELINE_COMPILE_REQUIRED_EXT;
+
void *pipeline_ctx = ralloc_context(NULL);
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
void *stage_ctx = ralloc_context(NULL);
+ anv_pipeline_lower_nir(&pipeline->base, stage_ctx, &stages[s], layout);
+
+ if (prev_stage && compiler->glsl_compiler_options[s].NirOptions->unify_interfaces) {
+ prev_stage->nir->info.outputs_written |= stages[s].nir->info.inputs_read &
+ ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+ stages[s].nir->info.inputs_read |= prev_stage->nir->info.outputs_written &
+ ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+ prev_stage->nir->info.patch_outputs_written |= stages[s].nir->info.patch_inputs_read;
+ stages[s].nir->info.patch_inputs_read |= prev_stage->nir->info.patch_outputs_written;
+ }
+
+ ralloc_free(stage_ctx);
+
+ stages[s].feedback.duration += os_time_get_nano() - stage_start;
+
+ prev_stage = &stages[s];
+ }
+
+ prev_stage = NULL;
+ for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
+ if (!stages[s].entrypoint)
+ continue;
+
+ int64_t stage_start = os_time_get_nano();
+
+ void *stage_ctx = ralloc_context(NULL);
+
nir_xfb_info *xfb_info = NULL;
if (s == MESA_SHADER_VERTEX ||
s == MESA_SHADER_TESS_EVAL ||
s == MESA_SHADER_GEOMETRY)
xfb_info = nir_gather_xfb_info(stages[s].nir, stage_ctx);
- anv_pipeline_lower_nir(&pipeline->base, stage_ctx, &stages[s], layout);
-
switch (s) {
case MESA_SHADER_VERTEX:
anv_pipeline_compile_vs(compiler, stage_ctx, pipeline,
&cache_hit);
}
+ if (bin == NULL &&
+ (info->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT))
+ return VK_PIPELINE_COMPILE_REQUIRED_EXT;
+
void *mem_ctx = ralloc_context(NULL);
if (bin == NULL) {
int64_t stage_start = os_time_get_nano();
return VK_SUCCESS;
}
-uint32_t
-anv_cs_workgroup_size(const struct anv_compute_pipeline *pipeline)
+struct anv_cs_parameters
+anv_cs_parameters(const struct anv_compute_pipeline *pipeline)
{
const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
- return cs_prog_data->local_size[0] *
- cs_prog_data->local_size[1] *
- cs_prog_data->local_size[2];
-}
-uint32_t
-anv_cs_threads(const struct anv_compute_pipeline *pipeline)
-{
- const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
- return DIV_ROUND_UP(anv_cs_workgroup_size(pipeline),
- cs_prog_data->simd_size);
+ struct anv_cs_parameters cs_params = {};
+
+ cs_params.group_size = cs_prog_data->local_size[0] *
+ cs_prog_data->local_size[1] *
+ cs_prog_data->local_size[2];
+ cs_params.simd_size =
+ brw_cs_simd_size_for_group_size(&pipeline->base.device->info,
+ cs_prog_data, cs_params.group_size);
+ cs_params.threads = DIV_ROUND_UP(cs_params.group_size, cs_params.simd_size);
+
+ return cs_params;
}
/**
pCreateInfo->pRasterizationState->depthBiasSlopeFactor;
}
+ if (states & ANV_CMD_DIRTY_DYNAMIC_CULL_MODE) {
+ assert(pCreateInfo->pRasterizationState);
+ dynamic->cull_mode =
+ pCreateInfo->pRasterizationState->cullMode;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE) {
+ assert(pCreateInfo->pRasterizationState);
+ dynamic->front_face =
+ pCreateInfo->pRasterizationState->frontFace;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ assert(pCreateInfo->pInputAssemblyState);
+ bool has_tess = false;
+ for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+ const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
+ gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
+ if (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL)
+ has_tess = true;
+ }
+ if (has_tess) {
+ const VkPipelineTessellationStateCreateInfo *tess_info =
+ pCreateInfo->pTessellationState;
+ dynamic->primitive_topology = _3DPRIM_PATCHLIST(tess_info->patchControlPoints);
+ } else {
+ dynamic->primitive_topology = pCreateInfo->pInputAssemblyState->topology;
+ }
+ }
+
/* Section 9.2 of the Vulkan 1.0.15 spec says:
*
* pColorBlendState is [...] NULL if the pipeline has rasterization
dynamic->stencil_reference.back =
pCreateInfo->pDepthStencilState->back.reference;
}
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE) {
+ dynamic->depth_test_enable =
+ pCreateInfo->pDepthStencilState->depthTestEnable;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE) {
+ dynamic->depth_write_enable =
+ pCreateInfo->pDepthStencilState->depthWriteEnable;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP) {
+ dynamic->depth_compare_op =
+ pCreateInfo->pDepthStencilState->depthCompareOp;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE) {
+ dynamic->depth_bounds_test_enable =
+ pCreateInfo->pDepthStencilState->depthBoundsTestEnable;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE) {
+ dynamic->stencil_test_enable =
+ pCreateInfo->pDepthStencilState->stencilTestEnable;
+ }
+
+ if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP) {
+ const VkPipelineDepthStencilStateCreateInfo *info =
+ pCreateInfo->pDepthStencilState;
+ memcpy(&dynamic->stencil_op.front, &info->front,
+ sizeof(dynamic->stencil_op.front));
+ memcpy(&dynamic->stencil_op.back, &info->back,
+ sizeof(dynamic->stencil_op.back));
+ }
}
const VkPipelineRasterizationLineStateCreateInfoEXT *line_state =
}
VkResult
-anv_pipeline_init(struct anv_graphics_pipeline *pipeline,
- struct anv_device *device,
- struct anv_pipeline_cache *cache,
- const VkGraphicsPipelineCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *alloc)
+anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
+ struct anv_device *device,
+ struct anv_pipeline_cache *cache,
+ const VkGraphicsPipelineCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *alloc)
{
VkResult result;
anv_pipeline_validate_create_info(pCreateInfo);
- if (alloc == NULL)
- alloc = &device->vk.alloc;
+ result = anv_pipeline_init(&pipeline->base, device,
+ ANV_PIPELINE_GRAPHICS, pCreateInfo->flags,
+ alloc);
+ if (result != VK_SUCCESS)
+ return result;
- vk_object_base_init(&device->vk, &pipeline->base.base,
- VK_OBJECT_TYPE_PIPELINE);
- pipeline->base.device = device;
- pipeline->base.type = ANV_PIPELINE_GRAPHICS;
+ anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
+ pipeline->batch_data, sizeof(pipeline->batch_data));
ANV_FROM_HANDLE(anv_render_pass, render_pass, pCreateInfo->renderPass);
assert(pCreateInfo->subpass < render_pass->subpass_count);
pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
- result = anv_reloc_list_init(&pipeline->base.batch_relocs, alloc);
- if (result != VK_SUCCESS)
- return result;
-
- pipeline->base.batch.alloc = alloc;
- pipeline->base.batch.next = pipeline->base.batch.start = pipeline->batch_data;
- pipeline->base.batch.end = pipeline->base.batch.start + sizeof(pipeline->batch_data);
- pipeline->base.batch.relocs = &pipeline->base.batch_relocs;
- pipeline->base.batch.status = VK_SUCCESS;
-
- pipeline->base.mem_ctx = ralloc_context(NULL);
- pipeline->base.flags = pCreateInfo->flags;
-
assert(pCreateInfo->pRasterizationState);
copy_non_dynamic_state(pipeline, pCreateInfo);
*/
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
- util_dynarray_init(&pipeline->base.executables, pipeline->base.mem_ctx);
-
result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo);
if (result != VK_SUCCESS) {
- ralloc_free(pipeline->base.mem_ctx);
- anv_reloc_list_finish(&pipeline->base.batch_relocs, alloc);
+ anv_pipeline_finish(&pipeline->base, device, alloc);
return result;
}