diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index 928b2b88b13..0df5f8219d8 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -171,9 +171,7 @@ genX(raster_polygon_mode)(struct anv_graphics_pipeline *pipeline, void genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const VkPipelineRenderingCreateInfo *rendering_info, - const VkRenderingSelfDependencyInfoMESA *rsd_info); + const struct vk_graphics_pipeline_state *state); void genX(compute_pipeline_emit)(struct anv_compute_pipeline *pipeline); diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index cf9f17f2962..99833ba935b 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -374,8 +374,8 @@ populate_gs_prog_key(const struct anv_device *device, static bool pipeline_has_coarse_pixel(const struct anv_graphics_pipeline *pipeline, - const VkPipelineMultisampleStateCreateInfo *ms_info, - const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info) + const struct vk_multisample_state *ms, + const struct vk_fragment_shading_rate_state *fsr) { /* The Vulkan 1.2.199 spec says: * @@ -407,21 +407,21 @@ pipeline_has_coarse_pixel(const struct anv_graphics_pipeline *pipeline, * here. Note that this sample shading being enabled has nothing to do * with minSampleShading. */ - if (ms_info && ms_info->sampleShadingEnable) + if (ms != NULL && ms->sample_shading_enable) return false; /* Not dynamic & not specified for the pipeline. */ - if ((pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) == 0 && !fsr_info) + if ((pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) == 0 && fsr == NULL) return false; /* Not dynamic & pipeline has a 1x1 fragment shading rate with no * possibility for element of the pipeline to change the value. */ if ((pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) == 0 && - fsr_info->fragmentSize.width <= 1 && - fsr_info->fragmentSize.height <= 1 && - fsr_info->combinerOps[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && - fsr_info->combinerOps[1] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR) + fsr->fragment_size.width <= 1 && + fsr->fragment_size.height <= 1 && + fsr->combiner_ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && + fsr->combiner_ops[1] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR) return false; return true; @@ -450,9 +450,9 @@ populate_mesh_prog_key(const struct anv_device *device, static void populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline, bool robust_buffer_acccess, - const VkPipelineMultisampleStateCreateInfo *ms_info, - const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info, - const VkPipelineRenderingCreateInfo *rendering_info, + const struct vk_multisample_state *ms, + const struct vk_fragment_shading_rate_state *fsr, + const struct vk_render_pass_state *rp, struct brw_wm_prog_key *key) { const struct anv_device *device = pipeline->base.device; @@ -471,28 +471,28 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline, key->ignore_sample_mask_out = false; - assert(rendering_info->colorAttachmentCount <= MAX_RTS); + assert(rp->color_attachment_count <= MAX_RTS); /* Consider all inputs as valid until look at the NIR variables. */ - key->color_outputs_valid = (1u << rendering_info->colorAttachmentCount) - 1; - key->nr_color_regions = rendering_info->colorAttachmentCount; + key->color_outputs_valid = (1u << rp->color_attachment_count) - 1; + key->nr_color_regions = rp->color_attachment_count; /* To reduce possible shader recompilations we would need to know if * there is a SampleMask output variable to compute if we should emit * code to workaround the issue that hardware disables alpha to coverage * when there is SampleMask output. */ - key->alpha_to_coverage = ms_info && ms_info->alphaToCoverageEnable; + key->alpha_to_coverage = ms != NULL && ms->alpha_to_coverage_enable; /* Vulkan doesn't support fixed-function alpha test */ key->alpha_test_replicate_alpha = false; - if (ms_info) { + if (ms != NULL) { /* We should probably pull this out of the shader, but it's fairly * harmless to compute it and then let dead-code take care of it. */ - if (ms_info->rasterizationSamples > 1) { - key->persample_interp = ms_info->sampleShadingEnable && - (ms_info->minSampleShading * ms_info->rasterizationSamples) > 1; + if (ms->rasterization_samples > 1) { + key->persample_interp = ms->sample_shading_enable && + (ms->min_sample_shading * ms->rasterization_samples) > 1; key->multisample_fbo = true; } @@ -503,7 +503,7 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline, key->coarse_pixel = !key->persample_interp && device->vk.enabled_extensions.KHR_fragment_shading_rate && - pipeline_has_coarse_pixel(pipeline, ms_info, fsr_info); + pipeline_has_coarse_pixel(pipeline, ms, fsr); } static void @@ -1081,7 +1081,7 @@ anv_pipeline_compile_mesh(const struct brw_compiler *compiler, static void anv_pipeline_link_fs(const struct brw_compiler *compiler, struct anv_pipeline_stage *stage, - const VkPipelineRenderingCreateInfo *rendering_info) + const struct vk_render_pass_state *rp) { /* Initially the valid outputs value is set to all possible render targets * valid (see populate_wm_prog_key()), before we look at the shader @@ -1101,7 +1101,7 @@ anv_pipeline_link_fs(const struct brw_compiler *compiler, stage->key.wm.color_outputs_valid |= BITFIELD_RANGE(rt, array_len); } stage->key.wm.color_outputs_valid &= - (1u << rendering_info->colorAttachmentCount) - 1; + (1u << rp->color_attachment_count) - 1; stage->key.wm.nr_color_regions = util_last_bit(stage->key.wm.color_outputs_valid); @@ -1333,8 +1333,7 @@ anv_pipeline_init_from_cached_graphics(struct anv_graphics_pipeline *pipeline) static void anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline, - const VkGraphicsPipelineCreateInfo *info, - const VkPipelineRenderingCreateInfo *rendering_info, + const struct vk_graphics_pipeline_state *state, struct anv_pipeline_stage *stages) { for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) { @@ -1355,7 +1354,7 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline, case MESA_SHADER_TESS_CTRL: populate_tcs_prog_key(device, pipeline->base.device->robust_buffer_access, - info->pTessellationState->patchControlPoints, + state->ts->patch_control_points, &stages[s].key.tcs); break; case MESA_SHADER_TESS_EVAL: @@ -1369,15 +1368,9 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline, &stages[s].key.gs); break; case MESA_SHADER_FRAGMENT: { - const bool raster_enabled = - !info->pRasterizationState->rasterizerDiscardEnable || - pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; populate_wm_prog_key(pipeline, pipeline->base.device->robust_buffer_access, - raster_enabled ? info->pMultisampleState : NULL, - vk_find_struct_const(info->pNext, - PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR), - rendering_info, + state->ms, state->fsr, state->rp, &stages[s].key.wm); break; } @@ -1529,7 +1522,7 @@ static VkResult anv_graphics_pipeline_compile(struct anv_graphics_pipeline *pipeline, struct vk_pipeline_cache *cache, const VkGraphicsPipelineCreateInfo *info, - const VkPipelineRenderingCreateInfo *rendering_info) + const struct vk_graphics_pipeline_state *state) { ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout); VkResult result; @@ -1547,7 +1540,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_pipeline *pipeline, stages[stage].info = &info->pStages[i]; } - anv_graphics_pipeline_init_keys(pipeline, info, rendering_info, stages); + anv_graphics_pipeline_init_keys(pipeline, state, stages); unsigned char sha1[20]; anv_pipeline_hash_graphics(pipeline, layout, stages, sha1); @@ -1607,7 +1600,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_pipeline *pipeline, anv_pipeline_link_mesh(compiler, &stages[s], next_stage); break; case MESA_SHADER_FRAGMENT: - anv_pipeline_link_fs(compiler, &stages[s], rendering_info); + anv_pipeline_link_fs(compiler, &stages[s], state->rp); break; default: unreachable("Invalid graphics shader stage"); @@ -1969,16 +1962,6 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline, return VK_SUCCESS; } -static bool -anv_rendering_uses_color_attachment(const VkPipelineRenderingCreateInfo *rendering_info) -{ - for (unsigned i = 0; i < rendering_info->colorAttachmentCount; i++) { - if (rendering_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED) - return true; - } - return false; -} - static VkResult anv_compute_pipeline_create(struct anv_device *device, struct vk_pipeline_cache *cache, @@ -2077,8 +2060,7 @@ VkResult anv_CreateComputePipelines( */ static void copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const VkPipelineRenderingCreateInfo *rendering_info) + const struct vk_graphics_pipeline_state *state) { anv_cmd_dirty_mask_t states = ANV_CMD_DIRTY_DYNAMIC_ALL; @@ -2088,255 +2070,152 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline, struct anv_dynamic_state *dynamic = &pipeline->non_dynamic_state; - bool raster_discard = - pCreateInfo->pRasterizationState->rasterizerDiscardEnable && - !(pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE); - /* Section 9.2 of the Vulkan 1.0.15 spec says: * * pViewportState is [...] NULL if the pipeline * has rasterization disabled. */ - if (!raster_discard) { - assert(pCreateInfo->pViewportState); + if (state->vp) { + pipeline->negative_one_to_one = state->vp->negative_one_to_one; - const VkPipelineViewportDepthClipControlCreateInfoEXT *ccontrol = - vk_find_struct_const(pCreateInfo->pViewportState, - PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT); - - if (ccontrol) - pipeline->negative_one_to_one = ccontrol->negativeOneToOne; - - dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount; + dynamic->viewport.count = state->vp->viewport_count; if (states & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) { typed_memcpy(dynamic->viewport.viewports, - pCreateInfo->pViewportState->pViewports, - pCreateInfo->pViewportState->viewportCount); + state->vp->viewports, state->vp->viewport_count); } - dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount; + dynamic->scissor.count = state->vp->scissor_count; if (states & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) { typed_memcpy(dynamic->scissor.scissors, - pCreateInfo->pViewportState->pScissors, - pCreateInfo->pViewportState->scissorCount); + state->vp->scissors, state->vp->scissor_count); } } - if (states & ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH) { - assert(pCreateInfo->pRasterizationState); - dynamic->line_width = pCreateInfo->pRasterizationState->lineWidth; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH) + dynamic->line_width = state->rs->line.width; if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS) { - assert(pCreateInfo->pRasterizationState); - dynamic->depth_bias.bias = - pCreateInfo->pRasterizationState->depthBiasConstantFactor; - dynamic->depth_bias.clamp = - pCreateInfo->pRasterizationState->depthBiasClamp; - dynamic->depth_bias.slope = - pCreateInfo->pRasterizationState->depthBiasSlopeFactor; + dynamic->depth_bias.bias = state->rs->depth_bias.constant; + dynamic->depth_bias.clamp = state->rs->depth_bias.clamp; + dynamic->depth_bias.slope = state->rs->depth_bias.slope; } - if (states & ANV_CMD_DIRTY_DYNAMIC_CULL_MODE) { - assert(pCreateInfo->pRasterizationState); - dynamic->cull_mode = - pCreateInfo->pRasterizationState->cullMode; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_CULL_MODE) + dynamic->cull_mode = state->rs->cull_mode; - if (states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE) { - assert(pCreateInfo->pRasterizationState); - dynamic->front_face = - pCreateInfo->pRasterizationState->frontFace; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE) + dynamic->front_face = state->rs->front_face; if ((states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) && - (pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT)) { - assert(pCreateInfo->pInputAssemblyState); - dynamic->primitive_topology = pCreateInfo->pInputAssemblyState->topology; - } + (pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT)) + dynamic->primitive_topology = state->ia->primitive_topology; - if (states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE) { - assert(pCreateInfo->pRasterizationState); - dynamic->raster_discard = - pCreateInfo->pRasterizationState->rasterizerDiscardEnable; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE) + dynamic->raster_discard = state->rs->rasterizer_discard_enable; - if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE) { - assert(pCreateInfo->pRasterizationState); - dynamic->depth_bias_enable = - pCreateInfo->pRasterizationState->depthBiasEnable; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE) + dynamic->depth_bias_enable = state->rs->depth_bias.enable; if ((states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE) && - (pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT)) { - assert(pCreateInfo->pInputAssemblyState); - dynamic->primitive_restart_enable = - pCreateInfo->pInputAssemblyState->primitiveRestartEnable; - } + (pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT)) + dynamic->primitive_restart_enable = state->ia->primitive_restart_enable; - /* Section 9.2 of the Vulkan 1.0.15 spec says: - * - * pColorBlendState is [...] NULL if the pipeline has rasterization - * disabled or if the subpass of the render pass the pipeline is - * created against does not use any color attachments. - */ - bool uses_color_att = anv_rendering_uses_color_attachment(rendering_info); - - if (uses_color_att && !raster_discard) { - assert(pCreateInfo->pColorBlendState); - - if (states & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) - typed_memcpy(dynamic->blend_constants, - pCreateInfo->pColorBlendState->blendConstants, 4); - } - - /* If there is no depthstencil attachment, then don't read - * pDepthStencilState. The Vulkan spec states that pDepthStencilState may - * be NULL in this case. Even if pDepthStencilState is non-NULL, there is - * no need to override the depthstencil defaults in - * anv_pipeline::dynamic_state when there is no depthstencil attachment. - * - * Section 9.2 of the Vulkan 1.0.15 spec says: - * - * pDepthStencilState is [...] NULL if the pipeline has rasterization - * disabled or if the subpass of the render pass the pipeline is created - * against does not use a depth/stencil attachment. - */ - if (!raster_discard && - (rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED || - rendering_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)) { - assert(pCreateInfo->pDepthStencilState); + if (state->cb != NULL && (states & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS)) + typed_memcpy(dynamic->blend_constants, state->cb->blend_constants, 4); + if (state->ds != NULL) { if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) { - dynamic->depth_bounds.min = - pCreateInfo->pDepthStencilState->minDepthBounds; - dynamic->depth_bounds.max = - pCreateInfo->pDepthStencilState->maxDepthBounds; + dynamic->depth_bounds.min = state->ds->depth.bounds_test.min; + dynamic->depth_bounds.max = state->ds->depth.bounds_test.max; } if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK) { dynamic->stencil_compare_mask.front = - pCreateInfo->pDepthStencilState->front.compareMask; + state->ds->stencil.front.compare_mask; dynamic->stencil_compare_mask.back = - pCreateInfo->pDepthStencilState->back.compareMask; + state->ds->stencil.back.compare_mask; } if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK) { dynamic->stencil_write_mask.front = - pCreateInfo->pDepthStencilState->front.writeMask; + state->ds->stencil.front.write_mask; dynamic->stencil_write_mask.back = - pCreateInfo->pDepthStencilState->back.writeMask; + state->ds->stencil.back.write_mask; } if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE) { dynamic->stencil_reference.front = - pCreateInfo->pDepthStencilState->front.reference; + state->ds->stencil.front.reference; dynamic->stencil_reference.back = - pCreateInfo->pDepthStencilState->back.reference; + state->ds->stencil.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_TEST_ENABLE) + dynamic->depth_test_enable = state->ds->depth.test_enable; - if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE) { - dynamic->depth_write_enable = - pCreateInfo->pDepthStencilState->depthWriteEnable; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE) + dynamic->depth_write_enable = state->ds->depth.write_enable; - if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP) { - dynamic->depth_compare_op = - pCreateInfo->pDepthStencilState->depthCompareOp; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP) + dynamic->depth_compare_op = state->ds->depth.compare_op; if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE) { dynamic->depth_bounds_test_enable = - pCreateInfo->pDepthStencilState->depthBoundsTestEnable; + state->ds->depth.bounds_test.enable; } - if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE) { - dynamic->stencil_test_enable = - pCreateInfo->pDepthStencilState->stencilTestEnable; - } + if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE) + dynamic->stencil_test_enable = state->ds->stencil.test_enable; 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)); + dynamic->stencil_op.front.fail_op = state->ds->stencil.front.op.fail; + dynamic->stencil_op.front.pass_op = state->ds->stencil.front.op.pass; + dynamic->stencil_op.front.depth_fail_op = state->ds->stencil.front.op.depth_fail; + dynamic->stencil_op.front.compare_op = state->ds->stencil.front.op.compare; + + dynamic->stencil_op.back.fail_op = state->ds->stencil.back.op.fail; + dynamic->stencil_op.back.pass_op = state->ds->stencil.back.op.pass; + dynamic->stencil_op.back.depth_fail_op = state->ds->stencil.back.op.depth_fail; + dynamic->stencil_op.back.compare_op = state->ds->stencil.back.op.compare; } } - const VkPipelineRasterizationLineStateCreateInfoEXT *line_state = - vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, - PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT); - if (!raster_discard && line_state && line_state->stippledLineEnable) { + if (state->rs != NULL) { if (states & ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) { - dynamic->line_stipple.factor = line_state->lineStippleFactor; - dynamic->line_stipple.pattern = line_state->lineStipplePattern; + dynamic->line_stipple.factor = state->rs->line.stipple.factor; + dynamic->line_stipple.pattern = state->rs->line.stipple.pattern; } } - const VkPipelineMultisampleStateCreateInfo *ms_info = - raster_discard ? NULL : pCreateInfo->pMultisampleState; if (states & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) { - const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = ms_info ? - vk_find_struct_const(ms_info, PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT) : NULL; - uint32_t samples = MAX2(1, ms_info ? ms_info->rasterizationSamples : 1); - if (sl_info && sl_info->sampleLocationsEnable) { - const VkSampleLocationEXT *positions = - sl_info->sampleLocationsInfo.pSampleLocations; + if (state->ms != NULL) { + uint32_t samples = state->ms->rasterization_samples; for (uint32_t i = 0; i < samples; i++) { - dynamic->sample_locations.locations[i].x = positions[i].x; - dynamic->sample_locations.locations[i].y = positions[i].y; + dynamic->sample_locations.locations[i].x = + state->ms->sample_locations->locations[i].x; + dynamic->sample_locations.locations[i].y = + state->ms->sample_locations->locations[i].y; } + dynamic->sample_locations.samples = samples; } else { - const struct intel_sample_position *positions = - intel_get_sample_positions(samples); - for (uint32_t i = 0; i < samples; i++) { - dynamic->sample_locations.locations[i].x = positions[i].x; - dynamic->sample_locations.locations[i].y = positions[i].y; - } - } - dynamic->sample_locations.samples = samples; - } - - if (states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) { - if (!raster_discard && uses_color_att) { - assert(pCreateInfo->pColorBlendState); - const VkPipelineColorWriteCreateInfoEXT *color_write_info = - vk_find_struct_const(pCreateInfo->pColorBlendState->pNext, - PIPELINE_COLOR_WRITE_CREATE_INFO_EXT); - - if (color_write_info) { - dynamic->color_writes = (1u << MAX_RTS) - 1; - for (uint32_t i = 0; i < color_write_info->attachmentCount; i++) { - if (color_write_info->pColorWriteEnables[i]) - dynamic->color_writes |= BITFIELD_BIT(i); - else - dynamic->color_writes &= ~BITFIELD_BIT(i); - } - } + dynamic->sample_locations.samples = 1; + dynamic->sample_locations.locations[0].x = 0.5; + dynamic->sample_locations.locations[0].y = 0.5; } } - if (states & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP) { - if (!raster_discard && anv_rendering_uses_color_attachment(rendering_info)) - dynamic->logic_op = pCreateInfo->pColorBlendState->logicOp; + if (state->cb != NULL) { + if (states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) + dynamic->color_writes = state->cb->color_write_enables; + + if (states & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP) + dynamic->logic_op = state->cb->logic_op; } - const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_state = - vk_find_struct_const(pCreateInfo->pNext, - PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR); - if (fsr_state) { - if (states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) { - dynamic->fragment_shading_rate.rate = fsr_state->fragmentSize; - memcpy(dynamic->fragment_shading_rate.ops, fsr_state->combinerOps, - sizeof(dynamic->fragment_shading_rate.ops)); - } + if (states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) { + dynamic->fragment_shading_rate.rate = state->fsr->fragment_size; + memcpy(dynamic->fragment_shading_rate.ops, state->fsr->combiner_ops, + sizeof(dynamic->fragment_shading_rate.ops)); } /* When binding a mesh pipeline into a command buffer, it should not affect the @@ -2373,31 +2252,12 @@ anv_pipeline_setup_l3_config(struct anv_pipeline *pipeline, bool needs_slm) pipeline->l3_config = intel_get_l3_config(devinfo, w); } -static VkLineRasterizationModeEXT -vk_line_rasterization_mode(const VkPipelineRasterizationLineStateCreateInfoEXT *line_info, - const VkPipelineMultisampleStateCreateInfo *ms_info) -{ - VkLineRasterizationModeEXT line_mode = - line_info ? line_info->lineRasterizationMode : - VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; - - if (line_mode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) { - if (ms_info && ms_info->rasterizationSamples > 1) { - return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; - } else { - return VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT; - } - } - - return line_mode; -} - static VkResult anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, struct anv_device *device, struct vk_pipeline_cache *cache, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const VkPipelineRenderingCreateInfo *rendering_info, + const struct VkGraphicsPipelineCreateInfo *pCreateInfo, + const struct vk_graphics_pipeline_state *state, const VkAllocationCallbacks *alloc) { VkResult result; @@ -2411,14 +2271,11 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS, pipeline->batch_data, sizeof(pipeline->batch_data)); - assert(pCreateInfo->pRasterizationState); - - if (pCreateInfo->pDynamicState) { - uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; - for (uint32_t s = 0; s < count; s++) { - pipeline->dynamic_states |= anv_cmd_dirty_bit_for_vk_dynamic_state( - pCreateInfo->pDynamicState->pDynamicStates[s]); - } + enum mesa_vk_dynamic_graphics_state s; + BITSET_FOREACH_SET(s, state->dynamic, + MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) { + pipeline->dynamic_states |= + anv_cmd_dirty_bit_for_mesa_vk_dynamic_graphics_state(s); } pipeline->active_stages = 0; @@ -2431,23 +2288,13 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, if (anv_pipeline_is_mesh(pipeline)) assert(device->physical->vk.supported_extensions.NV_mesh_shader); - copy_non_dynamic_state(pipeline, pCreateInfo, rendering_info); + copy_non_dynamic_state(pipeline, state); - pipeline->depth_clamp_enable = pCreateInfo->pRasterizationState->depthClampEnable; - pipeline->view_mask = rendering_info->viewMask; + pipeline->depth_clamp_enable = state->rs->depth_clamp_enable; + pipeline->depth_clip_enable = state->rs->depth_clip_enable; + pipeline->view_mask = state->rp->view_mask; - /* Previously we enabled depth clipping when !depthClampEnable. - * DepthClipStateCreateInfo now makes depth clipping explicit so if the - * clipping info is available, use its enable value to determine clipping, - * otherwise fallback to the previous !depthClampEnable logic. - */ - const VkPipelineRasterizationDepthClipStateCreateInfoEXT *clip_info = - vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, - PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); - pipeline->depth_clip_enable = clip_info ? clip_info->depthClipEnable : !pipeline->depth_clamp_enable; - - result = anv_graphics_pipeline_compile(pipeline, cache, pCreateInfo, - rendering_info); + result = anv_graphics_pipeline_compile(pipeline, cache, pCreateInfo, state); if (result != VK_SUCCESS) { anv_pipeline_finish(&pipeline->base, device, alloc); return result; @@ -2456,51 +2303,18 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, anv_pipeline_setup_l3_config(&pipeline->base, false); if (anv_pipeline_is_primitive(pipeline)) { - const VkPipelineVertexInputStateCreateInfo *vi_info = - pCreateInfo->pVertexInputState; - const uint64_t inputs_read = get_vs_prog_data(pipeline)->inputs_read; - for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) { - const VkVertexInputAttributeDescription *desc = - &vi_info->pVertexAttributeDescriptions[i]; - - if (inputs_read & (1ull << (VERT_ATTRIB_GENERIC0 + desc->location))) - pipeline->vb_used |= 1 << desc->binding; + u_foreach_bit(a, state->vi->attributes_valid) { + if (inputs_read & BITFIELD64_BIT(VERT_ATTRIB_GENERIC0 + a)) + pipeline->vb_used |= BITFIELD64_BIT(state->vi->attributes[a].binding); } - for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) { - const VkVertexInputBindingDescription *desc = - &vi_info->pVertexBindingDescriptions[i]; - - pipeline->vb[desc->binding].stride = desc->stride; - - /* Step rate is programmed per vertex element (attribute), not - * binding. Set up a map of which bindings step per instance, for - * reference by vertex element setup. */ - switch (desc->inputRate) { - default: - case VK_VERTEX_INPUT_RATE_VERTEX: - pipeline->vb[desc->binding].instanced = false; - break; - case VK_VERTEX_INPUT_RATE_INSTANCE: - pipeline->vb[desc->binding].instanced = true; - break; - } - - pipeline->vb[desc->binding].instance_divisor = 1; - } - - const VkPipelineVertexInputDivisorStateCreateInfoEXT *vi_div_state = - vk_find_struct_const(vi_info->pNext, - PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); - if (vi_div_state) { - for (uint32_t i = 0; i < vi_div_state->vertexBindingDivisorCount; i++) { - const VkVertexInputBindingDivisorDescriptionEXT *desc = - &vi_div_state->pVertexBindingDivisors[i]; - - pipeline->vb[desc->binding].instance_divisor = desc->divisor; - } + u_foreach_bit(b, state->vi->bindings_valid) { + pipeline->vb[b].stride = state->vi->bindings[b].stride; + pipeline->vb[b].instanced = state->vi->bindings[b].input_rate == + VK_VERTEX_INPUT_RATE_INSTANCE; + pipeline->vb[b].instance_divisor = state->vi->bindings[b].divisor; } /* Our implementation of VK_KHR_multiview uses instancing to draw the @@ -2512,50 +2326,39 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, if (pipeline->view_mask && !pipeline->use_primitive_replication) pipeline->instance_multiplier = util_bitcount(pipeline->view_mask); - const VkPipelineInputAssemblyStateCreateInfo *ia_info = - pCreateInfo->pInputAssemblyState; - const VkPipelineTessellationStateCreateInfo *tess_info = - pCreateInfo->pTessellationState; - - if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) - pipeline->topology = _3DPRIM_PATCHLIST(tess_info->patchControlPoints); - else - pipeline->topology = vk_to_intel_primitive_type[ia_info->topology]; + if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) { + pipeline->topology = + _3DPRIM_PATCHLIST(state->ts->patch_control_points); + } else { + pipeline->topology = + vk_to_intel_primitive_type[state->ia->primitive_topology]; + } } else { assert(anv_pipeline_is_mesh(pipeline)); /* TODO(mesh): Mesh vs. Multiview with Instancing. */ } - /* If rasterization is not enabled, ms_info must be ignored. */ - const bool raster_enabled = - !pCreateInfo->pRasterizationState->rasterizerDiscardEnable || - (pipeline->dynamic_states & - ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE); - - const VkPipelineMultisampleStateCreateInfo *ms_info = - raster_enabled ? pCreateInfo->pMultisampleState : NULL; - - const VkPipelineRasterizationLineStateCreateInfoEXT *line_info = - vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, - PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT); - /* Store line mode, polygon mode and rasterization samples, these are used * for dynamic primitive topology. */ - pipeline->line_mode = vk_line_rasterization_mode(line_info, ms_info); - pipeline->polygon_mode = pCreateInfo->pRasterizationState->polygonMode; + pipeline->polygon_mode = state->rs->polygon_mode; pipeline->rasterization_samples = - ms_info ? ms_info->rasterizationSamples : 1; + state->ms != NULL ? state->ms->rasterization_samples : 1; + pipeline->line_mode = state->rs->line.mode; + if (pipeline->line_mode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) { + if (pipeline->rasterization_samples > 1) { + pipeline->line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; + } else { + pipeline->line_mode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT; + } + } /* Store the color write masks, to be merged with color write enable if * dynamic. */ - if (raster_enabled && anv_rendering_uses_color_attachment(rendering_info)) { - for (unsigned i = 0; i < pCreateInfo->pColorBlendState->attachmentCount; i++) { - const VkPipelineColorBlendAttachmentState *a = - &pCreateInfo->pColorBlendState->pAttachments[i]; - pipeline->color_comp_writes[i] = a->colorWriteMask; - } + if (state->cb != NULL) { + for (unsigned i = 0; i < state->cb->attachment_count; i++) + pipeline->color_comp_writes[i] = state->cb->attachments[i].write_mask; } return VK_SUCCESS; @@ -2578,40 +2381,24 @@ anv_graphics_pipeline_create(struct anv_device *device, if (pipeline == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - /* We'll use these as defaults if we don't have pipeline rendering or - * self-dependency structs. Saves us some NULL checks. - */ - VkRenderingSelfDependencyInfoMESA rsd_info_tmp = { - .sType = VK_STRUCTURE_TYPE_RENDERING_SELF_DEPENDENCY_INFO_MESA, - }; - VkPipelineRenderingCreateInfo rendering_info_tmp = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .pNext = &rsd_info_tmp, - }; - - const VkPipelineRenderingCreateInfo *rendering_info = - vk_get_pipeline_rendering_create_info(pCreateInfo); - if (rendering_info == NULL) - rendering_info = &rendering_info_tmp; - - const VkRenderingSelfDependencyInfoMESA *rsd_info = - vk_find_struct_const(rendering_info->pNext, - RENDERING_SELF_DEPENDENCY_INFO_MESA); - if (rsd_info == NULL) - rsd_info = &rsd_info_tmp; - - result = anv_graphics_pipeline_init(pipeline, device, cache, - pCreateInfo, rendering_info, - pAllocator); + struct vk_graphics_pipeline_all_state all; + struct vk_graphics_pipeline_state state = { }; + result = vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo, + NULL /* sp_info */, + &all, NULL, 0, NULL); if (result != VK_SUCCESS) { vk_free2(&device->vk.alloc, pAllocator, pipeline); return result; } - anv_genX(&device->info, graphics_pipeline_emit)(pipeline, - pCreateInfo, - rendering_info, - rsd_info); + result = anv_graphics_pipeline_init(pipeline, device, cache, + pCreateInfo, &state, pAllocator); + if (result != VK_SUCCESS) { + vk_free2(&device->vk.alloc, pAllocator, pipeline); + return result; + } + + anv_genX(&device->info, graphics_pipeline_emit)(pipeline, &state); *pPipeline = anv_pipeline_to_handle(&pipeline->base); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 477d5db7d95..77aef4722d7 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -76,6 +76,7 @@ #include "vk_drm_syncobj.h" #include "vk_enum_defines.h" #include "vk_framebuffer.h" +#include "vk_graphics_state.h" #include "vk_image.h" #include "vk_instance.h" #include "vk_pipeline_cache.h" @@ -2262,64 +2263,65 @@ typedef enum anv_cmd_dirty_bits anv_cmd_dirty_mask_t; ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE) static inline enum anv_cmd_dirty_bits -anv_cmd_dirty_bit_for_vk_dynamic_state(VkDynamicState vk_state) +anv_cmd_dirty_bit_for_mesa_vk_dynamic_graphics_state( + enum mesa_vk_dynamic_graphics_state state) { - switch (vk_state) { - case VK_DYNAMIC_STATE_VIEWPORT: - case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: + switch (state) { + case MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT: + case MESA_VK_DYNAMIC_VP_VIEWPORTS: return ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; - case VK_DYNAMIC_STATE_SCISSOR: - case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: + case MESA_VK_DYNAMIC_VP_SCISSOR_COUNT: + case MESA_VK_DYNAMIC_VP_SCISSORS: return ANV_CMD_DIRTY_DYNAMIC_SCISSOR; - case VK_DYNAMIC_STATE_LINE_WIDTH: + case MESA_VK_DYNAMIC_RS_LINE_WIDTH: return ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; - case VK_DYNAMIC_STATE_DEPTH_BIAS: + case MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; - case VK_DYNAMIC_STATE_BLEND_CONSTANTS: + case MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS: return ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; - case VK_DYNAMIC_STATE_DEPTH_BOUNDS: + case MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; - case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: + case MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK: return ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; - case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: + case MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK: return ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; - case VK_DYNAMIC_STATE_STENCIL_REFERENCE: + case MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE: return ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; - case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: + case MESA_VK_DYNAMIC_RS_LINE_STIPPLE: return ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE; - case VK_DYNAMIC_STATE_CULL_MODE: + case MESA_VK_DYNAMIC_RS_CULL_MODE: return ANV_CMD_DIRTY_DYNAMIC_CULL_MODE; - case VK_DYNAMIC_STATE_FRONT_FACE: + case MESA_VK_DYNAMIC_RS_FRONT_FACE: return ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE; - case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY: + case MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY: return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY; - case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE: + case MESA_VK_DYNAMIC_VI_BINDING_STRIDES: return ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE; - case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE: + case MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE; - case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE: + case MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE; - case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP: + case MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP; - case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE: + case MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE; - case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE: + case MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE; - case VK_DYNAMIC_STATE_STENCIL_OP: + case MESA_VK_DYNAMIC_DS_STENCIL_OP: return ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP; - case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: + case MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS: return ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS; - case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT: + case MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES: return ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE; - case VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR: + case MESA_VK_DYNAMIC_FSR: return ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE; - case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE: + case MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; - case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE: + case MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE; - case VK_DYNAMIC_STATE_LOGIC_OP_EXT: + case MESA_VK_DYNAMIC_CB_LOGIC_OP: return ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP; - case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE: + case MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE: return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE; default: assert(!"Unsupported dynamic state"); diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index a201b55e7a2..e44ef626d08 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -89,7 +89,7 @@ vertex_element_comp_control(enum isl_format format, unsigned comp) static void emit_vertex_input(struct anv_graphics_pipeline *pipeline, - const VkPipelineVertexInputStateCreateInfo *info) + const struct vk_vertex_input_state *vi) { const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); @@ -147,30 +147,29 @@ emit_vertex_input(struct anv_graphics_pipeline *pipeline, GENX(VERTEX_ELEMENT_STATE_pack)(NULL, &p[1 + i * 2], &element); } - for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) { - const VkVertexInputAttributeDescription *desc = - &info->pVertexAttributeDescriptions[i]; + u_foreach_bit(a, vi->attributes_valid) { enum isl_format format = anv_get_isl_format(&pipeline->base.device->info, - desc->format, + vi->attributes[a].format, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_TILING_LINEAR); - assert(desc->binding < MAX_VBS); + uint32_t binding = vi->attributes[a].binding; + assert(binding < MAX_VBS); - if ((elements & (1 << desc->location)) == 0) + if ((elements & (1 << a)) == 0) continue; /* Binding unused */ uint32_t slot = - __builtin_popcount(elements & ((1 << desc->location) - 1)) - + __builtin_popcount(elements & ((1 << a) - 1)) - DIV_ROUND_UP(__builtin_popcount(elements_double & - ((1 << desc->location) -1)), 2); + ((1 << a) -1)), 2); struct GENX(VERTEX_ELEMENT_STATE) element = { - .VertexBufferIndex = desc->binding, + .VertexBufferIndex = vi->attributes[a].binding, .Valid = true, .SourceElementFormat = format, .EdgeFlagEnable = false, - .SourceElementOffset = desc->offset, + .SourceElementOffset = vi->attributes[a].offset, .Component0Control = vertex_element_comp_control(format, 0), .Component1Control = vertex_element_comp_control(format, 1), .Component2Control = vertex_element_comp_control(format, 2), @@ -184,8 +183,8 @@ emit_vertex_input(struct anv_graphics_pipeline *pipeline, * VERTEX_BUFFER_STATE which we emit later. */ anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_VF_INSTANCING), vfi) { - bool per_instance = pipeline->vb[desc->binding].instanced; - uint32_t divisor = pipeline->vb[desc->binding].instance_divisor * + bool per_instance = pipeline->vb[binding].instanced; + uint32_t divisor = pipeline->vb[binding].instance_divisor * pipeline->instance_multiplier; vfi.InstancingEnable = per_instance; @@ -666,16 +665,6 @@ genX(ms_rasterization_mode)(struct anv_graphics_pipeline *pipeline, #endif } -static VkProvokingVertexModeEXT -vk_provoking_vertex_mode(const VkPipelineRasterizationStateCreateInfo *rs_info) -{ - const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *rs_pv_info = - vk_find_struct_const(rs_info, PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT); - - return rs_pv_info == NULL ? VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT : - rs_pv_info->provokingVertexMode; -} - const uint32_t genX(vk_to_intel_cullmode)[] = { [VK_CULL_MODE_NONE] = CULLMODE_NONE, [VK_CULL_MODE_FRONT_BIT] = CULLMODE_FRONT, @@ -694,18 +683,6 @@ const uint32_t genX(vk_to_intel_front_face)[] = { [VK_FRONT_FACE_CLOCKWISE] = 0 }; -#if GFX_VER >= 9 -static VkConservativeRasterizationModeEXT -vk_conservative_rasterization_mode(const VkPipelineRasterizationStateCreateInfo *rs_info) -{ - const VkPipelineRasterizationConservativeStateCreateInfoEXT *cr = - vk_find_struct_const(rs_info, PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT); - - return cr ? cr->conservativeRasterizationMode : - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; -} -#endif - void genX(rasterization_mode)(VkPolygonMode raster_mode, VkLineRasterizationModeEXT line_mode, @@ -761,11 +738,10 @@ genX(rasterization_mode)(VkPolygonMode raster_mode, static void emit_rs_state(struct anv_graphics_pipeline *pipeline, - const VkPipelineInputAssemblyStateCreateInfo *ia_info, - const VkPipelineRasterizationStateCreateInfo *rs_info, - const VkPipelineMultisampleStateCreateInfo *ms_info, - const VkPipelineRasterizationLineStateCreateInfoEXT *line_info, - const VkPipelineRenderingCreateInfo *rendering_info, + const struct vk_input_assembly_state *ia, + const struct vk_rasterization_state *rs, + const struct vk_multisample_state *ms, + const struct vk_render_pass_state *rp, enum intel_urb_deref_block_size urb_deref_block_size) { struct GENX(3DSTATE_SF) sf = { @@ -777,7 +753,7 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline, sf.VertexSubPixelPrecisionSelect = _8Bit; sf.AALineDistanceMode = true; - switch (vk_provoking_vertex_mode(rs_info)) { + switch (rs->provoking_vertex) { case VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT: sf.TriangleStripListProvokingVertexSelect = 0; sf.LineStripListProvokingVertexSelect = 0; @@ -795,7 +771,7 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline, } #if GFX_VERx10 == 75 - sf.LineStippleEnable = line_info && line_info->stippledLineEnable; + sf.LineStippleEnable = rs->line.stipple.enable; #endif #if GFX_VER >= 12 @@ -840,8 +816,8 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline, raster.ForceMultisampling = false; #endif - raster.FrontFaceFillMode = genX(vk_to_intel_fillmode)[rs_info->polygonMode]; - raster.BackFaceFillMode = genX(vk_to_intel_fillmode)[rs_info->polygonMode]; + raster.FrontFaceFillMode = genX(vk_to_intel_fillmode)[rs->polygon_mode]; + raster.BackFaceFillMode = genX(vk_to_intel_fillmode)[rs->polygon_mode]; raster.ScissorRectangleEnable = true; #if GFX_VER >= 9 @@ -854,20 +830,19 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline, #if GFX_VER >= 9 raster.ConservativeRasterizationEnable = - vk_conservative_rasterization_mode(rs_info) != - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; + rs->conservative_mode != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; #endif #if GFX_VER == 7 /* Gfx7 requires that we provide the depth format in 3DSTATE_SF so that it * can get the depth offsets correct. */ - if (rendering_info != NULL && - rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) { - assert(vk_format_has_depth(rendering_info->depthAttachmentFormat)); + if (rp != NULL && + rp->depth_attachment_format != VK_FORMAT_UNDEFINED) { + assert(vk_format_has_depth(rp->depth_attachment_format)); enum isl_format isl_format = anv_get_isl_format(&pipeline->base.device->info, - rendering_info->depthAttachmentFormat, + rp->depth_attachment_format, VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_TILING_OPTIMAL); sf.DepthBufferSurfaceFormat = @@ -886,7 +861,7 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline, static void emit_ms_state(struct anv_graphics_pipeline *pipeline, - const VkPipelineMultisampleStateCreateInfo *info) + const struct vk_multisample_state *ms) { #if GFX_VER >= 8 /* On Gfx8+ 3DSTATE_MULTISAMPLE only holds the number of samples. */ @@ -907,8 +882,8 @@ emit_ms_state(struct anv_graphics_pipeline *pipeline, uint32_t sample_mask = 0xff; #endif - if (info && info->pSampleMask) - sample_mask &= info->pSampleMask[0]; + if (ms != NULL) + sample_mask &= ms->sample_mask; anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_SAMPLE_MASK), sm) { sm.SampleMask = sample_mask; @@ -999,141 +974,10 @@ const uint32_t genX(vk_to_intel_primitive_type)[] = { [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ, }; -/* This function sanitizes the VkStencilOpState by looking at the compare ops - * and trying to determine whether or not a given stencil op can ever actually - * occur. Stencil ops which can never occur are set to VK_STENCIL_OP_KEEP. - * This function returns true if, after sanitation, any of the stencil ops are - * set to something other than VK_STENCIL_OP_KEEP. - */ -static bool -sanitize_stencil_face(VkStencilOpState *face, - VkCompareOp depthCompareOp) -{ - /* If compareOp is ALWAYS then the stencil test will never fail and failOp - * will never happen. Set failOp to KEEP in this case. - */ - if (face->compareOp == VK_COMPARE_OP_ALWAYS) - face->failOp = VK_STENCIL_OP_KEEP; - - /* If compareOp is NEVER or depthCompareOp is NEVER then one of the depth - * or stencil tests will fail and passOp will never happen. - */ - if (face->compareOp == VK_COMPARE_OP_NEVER || - depthCompareOp == VK_COMPARE_OP_NEVER) - face->passOp = VK_STENCIL_OP_KEEP; - - /* If compareOp is NEVER or depthCompareOp is ALWAYS then either the - * stencil test will fail or the depth test will pass. In either case, - * depthFailOp will never happen. - */ - if (face->compareOp == VK_COMPARE_OP_NEVER || - depthCompareOp == VK_COMPARE_OP_ALWAYS) - face->depthFailOp = VK_STENCIL_OP_KEEP; - - return face->failOp != VK_STENCIL_OP_KEEP || - face->depthFailOp != VK_STENCIL_OP_KEEP || - face->passOp != VK_STENCIL_OP_KEEP; -} - -/* Intel hardware is fairly sensitive to whether or not depth/stencil writes - * are enabled. In the presence of discards, it's fairly easy to get into the - * non-promoted case which means a fairly big performance hit. From the Iron - * Lake PRM, Vol 2, pt. 1, section 8.4.3.2, "Early Depth Test Cases": - * - * "Non-promoted depth (N) is active whenever the depth test can be done - * early but it cannot determine whether or not to write source depth to - * the depth buffer, therefore the depth write must be performed post pixel - * shader. This includes cases where the pixel shader can kill pixels, - * including via sampler chroma key, as well as cases where the alpha test - * function is enabled, which kills pixels based on a programmable alpha - * test. In this case, even if the depth test fails, the pixel cannot be - * killed if a stencil write is indicated. Whether or not the stencil write - * happens depends on whether or not the pixel is killed later. In these - * cases if stencil test fails and stencil writes are off, the pixels can - * also be killed early. If stencil writes are enabled, the pixels must be - * treated as Computed depth (described above)." - * - * The same thing as mentioned in the stencil case can happen in the depth - * case as well if it thinks it writes depth but, thanks to the depth test - * being GL_EQUAL, the write doesn't actually matter. A little extra work - * up-front to try and disable depth and stencil writes can make a big - * difference. - * - * Unfortunately, the way depth and stencil testing is specified, there are - * many case where, regardless of depth/stencil writes being enabled, nothing - * actually gets written due to some other bit of state being set. This - * function attempts to "sanitize" the depth stencil state and disable writes - * and sometimes even testing whenever possible. - */ -static void -sanitize_ds_state(VkPipelineDepthStencilStateCreateInfo *state, - bool *stencilWriteEnable, - VkImageAspectFlags ds_aspects) -{ - *stencilWriteEnable = state->stencilTestEnable; - - /* If the depth test is disabled, we won't be writing anything. Make sure we - * treat the test as always passing later on as well. - * - * Also, the Vulkan spec requires that if either depth or stencil is not - * present, the pipeline is to act as if the test silently passes. In that - * case we won't write either. - */ - if (!state->depthTestEnable || !(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) { - state->depthWriteEnable = false; - state->depthCompareOp = VK_COMPARE_OP_ALWAYS; - } - - if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) { - *stencilWriteEnable = false; - state->front.compareOp = VK_COMPARE_OP_ALWAYS; - state->back.compareOp = VK_COMPARE_OP_ALWAYS; - } - - /* If the stencil test is enabled and always fails, then we will never get - * to the depth test so we can just disable the depth test entirely. - */ - if (state->stencilTestEnable && - state->front.compareOp == VK_COMPARE_OP_NEVER && - state->back.compareOp == VK_COMPARE_OP_NEVER) { - state->depthTestEnable = false; - state->depthWriteEnable = false; - } - - /* If depthCompareOp is EQUAL then the value we would be writing to the - * depth buffer is the same as the value that's already there so there's no - * point in writing it. - */ - if (state->depthCompareOp == VK_COMPARE_OP_EQUAL) - state->depthWriteEnable = false; - - /* If the stencil ops are such that we don't actually ever modify the - * stencil buffer, we should disable writes. - */ - if (!sanitize_stencil_face(&state->front, state->depthCompareOp) && - !sanitize_stencil_face(&state->back, state->depthCompareOp)) - *stencilWriteEnable = false; - - /* If the depth test always passes and we never write out depth, that's the - * same as if the depth test is disabled entirely. - */ - if (state->depthCompareOp == VK_COMPARE_OP_ALWAYS && - !state->depthWriteEnable) - state->depthTestEnable = false; - - /* If the stencil test always passes and we never write out stencil, that's - * the same as if the stencil test is disabled entirely. - */ - if (state->front.compareOp == VK_COMPARE_OP_ALWAYS && - state->back.compareOp == VK_COMPARE_OP_ALWAYS && - !*stencilWriteEnable) - state->stencilTestEnable = false; -} - static void emit_ds_state(struct anv_graphics_pipeline *pipeline, - const VkPipelineDepthStencilStateCreateInfo *pCreateInfo, - const VkPipelineRenderingCreateInfo *rendering_info) + const struct vk_depth_stencil_state *ds_in, + const struct vk_render_pass_state *rp) { #if GFX_VER == 7 # define depth_stencil_dw pipeline->gfx7.depth_stencil_state @@ -1143,7 +987,7 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline, # define depth_stencil_dw pipeline->gfx9.wm_depth_stencil #endif - if (pCreateInfo == NULL) { + if (ds_in == NULL) { /* We're going to OR this together with the dynamic state. We need * to make sure it's initialized to something useful. */ @@ -1157,19 +1001,20 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline, } VkImageAspectFlags ds_aspects = 0; - if (rendering_info != NULL) { - if (rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) + if (rp != NULL) { + if (rp->depth_attachment_format != VK_FORMAT_UNDEFINED) ds_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; - if (rendering_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) + if (rp->stencil_attachment_format != VK_FORMAT_UNDEFINED) ds_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; } - VkPipelineDepthStencilStateCreateInfo info = *pCreateInfo; - sanitize_ds_state(&info, &pipeline->writes_stencil, ds_aspects); - pipeline->stencil_test_enable = info.stencilTestEnable; - pipeline->writes_depth = info.depthWriteEnable; - pipeline->depth_test_enable = info.depthTestEnable; - pipeline->depth_bounds_test_enable = info.depthBoundsTestEnable; + struct vk_depth_stencil_state ds = *ds_in; + vk_optimize_depth_stencil_state(&ds, ds_aspects); + pipeline->writes_stencil = ds.stencil.write_enable; + pipeline->stencil_test_enable = ds.stencil.test_enable; + pipeline->writes_depth = ds.depth.write_enable; + pipeline->depth_test_enable = ds.depth.test_enable; + pipeline->depth_bounds_test_enable = ds.depth.bounds_test.enable; #if GFX_VER <= 7 struct GENX(DEPTH_STENCIL_STATE) depth_stencil = { @@ -1210,16 +1055,16 @@ write_disabled_blend(uint32_t *state) static void emit_cb_state(struct anv_graphics_pipeline *pipeline, - const VkPipelineColorBlendStateCreateInfo *info, - const VkPipelineMultisampleStateCreateInfo *ms_info) + const struct vk_color_blend_state *cb, + const struct vk_multisample_state *ms) { struct anv_device *device = pipeline->base.device; const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); struct GENX(BLEND_STATE) blend_state = { #if GFX_VER >= 8 - .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, - .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, + .AlphaToCoverageEnable = ms && ms->alpha_to_coverage_enable, + .AlphaToOneEnable = ms && ms->alpha_to_one_enable, #endif }; @@ -1249,20 +1094,20 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline, /* We can have at most 8 attachments */ assert(i < MAX_RTS); - if (info == NULL || binding->index >= info->attachmentCount) { + if (cb == NULL || binding->index >= cb->attachment_count) { state_pos = write_disabled_blend(state_pos); continue; } - const VkPipelineColorBlendAttachmentState *a = - &info->pAttachments[binding->index]; + const struct vk_color_blend_attachment_state *a = + &cb->attachments[binding->index]; struct GENX(BLEND_STATE_ENTRY) entry = { #if GFX_VER < 8 - .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, - .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, + .AlphaToCoverageEnable = ms && ms->alpha_to_coverage_enable, + .AlphaToOneEnable = ms && ms->alpha_to_one_enable, #endif - .LogicOpEnable = info->logicOpEnable, + .LogicOpEnable = cb->logic_op_enable, /* Vulkan specification 1.2.168, VkLogicOp: * @@ -1279,21 +1124,21 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline, * "Enabling LogicOp and Color Buffer Blending at the same time is * UNDEFINED" */ - .ColorBufferBlendEnable = !info->logicOpEnable && a->blendEnable, + .ColorBufferBlendEnable = !cb->logic_op_enable && a->blend_enable, .ColorClampRange = COLORCLAMP_RTFORMAT, .PreBlendColorClampEnable = true, .PostBlendColorClampEnable = true, - .SourceBlendFactor = vk_to_intel_blend[a->srcColorBlendFactor], - .DestinationBlendFactor = vk_to_intel_blend[a->dstColorBlendFactor], - .ColorBlendFunction = vk_to_intel_blend_op[a->colorBlendOp], - .SourceAlphaBlendFactor = vk_to_intel_blend[a->srcAlphaBlendFactor], - .DestinationAlphaBlendFactor = vk_to_intel_blend[a->dstAlphaBlendFactor], - .AlphaBlendFunction = vk_to_intel_blend_op[a->alphaBlendOp], + .SourceBlendFactor = vk_to_intel_blend[a->src_color_blend_factor], + .DestinationBlendFactor = vk_to_intel_blend[a->dst_color_blend_factor], + .ColorBlendFunction = vk_to_intel_blend_op[a->color_blend_op], + .SourceAlphaBlendFactor = vk_to_intel_blend[a->src_alpha_blend_factor], + .DestinationAlphaBlendFactor = vk_to_intel_blend[a->dst_alpha_blend_factor], + .AlphaBlendFunction = vk_to_intel_blend_op[a->alpha_blend_op], }; - if (a->srcColorBlendFactor != a->srcAlphaBlendFactor || - a->dstColorBlendFactor != a->dstAlphaBlendFactor || - a->colorBlendOp != a->alphaBlendOp) { + if (a->src_color_blend_factor != a->src_alpha_blend_factor || + a->dst_color_blend_factor != a->dst_alpha_blend_factor || + a->color_blend_op != a->alpha_blend_op) { #if GFX_VER >= 8 blend_state.IndependentAlphaBlendEnable = true; #else @@ -1313,10 +1158,10 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline, * so we just disable the blending to prevent possible issues. */ if (!wm_prog_data->dual_src_blend && - (is_dual_src_blend_factor(a->srcColorBlendFactor) || - is_dual_src_blend_factor(a->dstColorBlendFactor) || - is_dual_src_blend_factor(a->srcAlphaBlendFactor) || - is_dual_src_blend_factor(a->dstAlphaBlendFactor))) { + (is_dual_src_blend_factor(a->src_color_blend_factor) || + is_dual_src_blend_factor(a->dst_color_blend_factor) || + is_dual_src_blend_factor(a->src_alpha_blend_factor) || + is_dual_src_blend_factor(a->dst_alpha_blend_factor))) { vk_logw(VK_LOG_OBJS(&device->vk.base), "Enabled dual-src blend factors without writing both targets " "in the shader. Disabling blending to avoid GPU hangs."); @@ -1329,13 +1174,13 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline, * means that, for MIN and MAX, we have to stomp the blend factor to * ONE to make it a no-op. */ - if (a->colorBlendOp == VK_BLEND_OP_MIN || - a->colorBlendOp == VK_BLEND_OP_MAX) { + if (a->color_blend_op == VK_BLEND_OP_MIN || + a->color_blend_op == VK_BLEND_OP_MAX) { entry.SourceBlendFactor = BLENDFACTOR_ONE; entry.DestinationBlendFactor = BLENDFACTOR_ONE; } - if (a->alphaBlendOp == VK_BLEND_OP_MIN || - a->alphaBlendOp == VK_BLEND_OP_MAX) { + if (a->alpha_blend_op == VK_BLEND_OP_MIN || + a->alpha_blend_op == VK_BLEND_OP_MAX) { entry.SourceAlphaBlendFactor = BLENDFACTOR_ONE; entry.DestinationAlphaBlendFactor = BLENDFACTOR_ONE; } @@ -1368,9 +1213,9 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline, static void emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, - const VkPipelineInputAssemblyStateCreateInfo *ia_info, - const VkPipelineViewportStateCreateInfo *vp_info, - const VkPipelineRasterizationStateCreateInfo *rs_info) + const struct vk_input_assembly_state *ia, + const struct vk_viewport_state *vp, + const struct vk_rasterization_state *rs) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); (void) wm_prog_data; @@ -1390,7 +1235,7 @@ emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, #endif clip.ClipMode = CLIPMODE_NORMAL; - switch (vk_provoking_vertex_mode(rs_info)) { + switch (rs->provoking_vertex) { case VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT: clip.TriangleStripListProvokingVertexSelect = 0; clip.LineStripListProvokingVertexSelect = 0; @@ -1421,9 +1266,9 @@ emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, * interface does not include a variable decorated with * ViewportIndex, then the first viewport is used." */ - if (vp_info && (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT)) { - clip.MaximumVPIndex = vp_info->viewportCount > 0 ? - vp_info->viewportCount - 1 : 0; + if (vp && (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT)) { + clip.MaximumVPIndex = vp->viewport_count > 0 ? + vp->viewport_count - 1 : 0; } else { clip.MaximumVPIndex = 0; } @@ -1443,15 +1288,15 @@ emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, #endif } else if (anv_pipeline_is_mesh(pipeline)) { const struct brw_mesh_prog_data *mesh_prog_data = get_mesh_prog_data(pipeline); - if (vp_info && vp_info->viewportCount > 0 && - mesh_prog_data->map.start_dw[VARYING_SLOT_VIEWPORT] >= 0) { - clip.MaximumVPIndex = vp_info->viewportCount - 1; + if (vp && vp->viewport_count > 0 && + mesh_prog_data->map.start_dw[VARYING_SLOT_VIEWPORT] >= 0) { + clip.MaximumVPIndex = vp->viewport_count - 1; } } #if GFX_VER == 7 - clip.FrontWinding = genX(vk_to_intel_front_face)[rs_info->frontFace]; - clip.CullMode = genX(vk_to_intel_cullmode)[rs_info->cullMode]; + clip.FrontWinding = genX(vk_to_intel_front_face)[rs->front_face]; + clip.CullMode = genX(vk_to_intel_cullmode)[rs->cull_mode]; clip.ViewportZClipTestEnable = pipeline->depth_clip_enable; #else clip.NonPerspectiveBarycentricEnable = wm_prog_data ? @@ -1474,7 +1319,7 @@ emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, static void emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, - const VkPipelineRasterizationStateCreateInfo *rs_info) + const struct vk_rasterization_state *rs) { const struct brw_vue_prog_data *prog_data = anv_pipeline_get_last_vue_prog_data(pipeline); @@ -1614,7 +1459,7 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, so.SOFunctionEnable = true; so.SOStatisticsEnable = true; - switch (vk_provoking_vertex_mode(rs_info)) { + switch (rs->provoking_vertex) { case VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT: so.ReorderMode = LEADING; break; @@ -1627,10 +1472,7 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, unreachable("Invalid provoking vertex mode"); } - const VkPipelineRasterizationStateStreamCreateInfoEXT *stream_info = - vk_find_struct_const(rs_info, PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT); - so.RenderStreamSelect = stream_info ? - stream_info->rasterizationStream : 0; + so.RenderStreamSelect = rs->rasterization_stream; #if GFX_VER >= 8 so.Buffer0SurfacePitch = xfb_info->buffers[0].stride; @@ -1809,7 +1651,7 @@ emit_3dstate_vs(struct anv_graphics_pipeline *pipeline) static void emit_3dstate_hs_te_ds(struct anv_graphics_pipeline *pipeline, - const VkPipelineTessellationStateCreateInfo *tess_info) + const struct vk_tessellation_state *ts) { if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) { anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_HS), hs); @@ -1880,17 +1722,10 @@ emit_3dstate_hs_te_ds(struct anv_graphics_pipeline *pipeline, #endif } - const VkPipelineTessellationDomainOriginStateCreateInfo *domain_origin_state = - tess_info ? vk_find_struct_const(tess_info, PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO) : NULL; - - VkTessellationDomainOrigin uv_origin = - domain_origin_state ? domain_origin_state->domainOrigin : - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT; - anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_TE), te) { te.Partitioning = tes_prog_data->partitioning; - if (uv_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) { + if (ts->domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) { te.OutputTopology = tes_prog_data->output_topology; } else { /* When the origin is upper-left, we have to flip the winding order */ @@ -2039,44 +1874,13 @@ emit_3dstate_gs(struct anv_graphics_pipeline *pipeline) } } -static bool -has_color_buffer_write_enabled(const struct anv_graphics_pipeline *pipeline, - const VkPipelineColorBlendStateCreateInfo *blend) -{ - const struct anv_shader_bin *shader_bin = - pipeline->shaders[MESA_SHADER_FRAGMENT]; - if (!shader_bin) - return false; - - if (!pipeline->non_dynamic_state.color_writes) - return false; - - const struct anv_pipeline_bind_map *bind_map = &shader_bin->bind_map; - for (int i = 0; i < bind_map->surface_count; i++) { - struct anv_pipeline_binding *binding = &bind_map->surface_to_descriptor[i]; - - if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) - continue; - - if (binding->index == UINT32_MAX) - continue; - - if (blend && binding->index < blend->attachmentCount && - blend->pAttachments[binding->index].colorWriteMask != 0) - return true; - } - - return false; -} - static void emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, - const VkPipelineInputAssemblyStateCreateInfo *ia, - const VkPipelineRasterizationStateCreateInfo *raster, - const VkPipelineColorBlendStateCreateInfo *blend, - const VkPipelineMultisampleStateCreateInfo *multisample, - const VkPipelineRasterizationLineStateCreateInfoEXT *line, - const VkRenderingSelfDependencyInfoMESA *rsd) + const struct vk_input_assembly_state *ia, + const struct vk_rasterization_state *rs, + const struct vk_multisample_state *ms, + const struct vk_color_blend_state *cb, + const struct vk_render_pass_state *rp) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -2135,8 +1939,8 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, * may get the depth or stencil value from the current draw rather * than the previous one. */ - wm.PixelShaderKillsPixel = rsd->depthSelfDependency || - rsd->stencilSelfDependency || + wm.PixelShaderKillsPixel = rp->depth_self_dependency || + rp->stencil_self_dependency || wm_prog_data->uses_kill; pipeline->force_fragment_thread_dispatch = @@ -2144,7 +1948,7 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, wm_prog_data->has_side_effects || wm.PixelShaderKillsPixel; - if (multisample && multisample->rasterizationSamples > 1) { + if (ms != NULL && ms->rasterization_samples > 1) { if (wm_prog_data->persample_dispatch) { wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE; } else { @@ -2155,7 +1959,7 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, } #endif - wm.LineStippleEnable = line && line->stippledLineEnable; + wm.LineStippleEnable = rs->line.stipple.enable; } const struct intel_device_info *devinfo = &pipeline->base.device->info; @@ -2165,8 +1969,8 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, static void emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, - const VkPipelineColorBlendStateCreateInfo *blend, - const VkPipelineMultisampleStateCreateInfo *multisample) + const struct vk_multisample_state *ms, + const struct vk_color_blend_state *cb) { UNUSED const struct intel_device_info *devinfo = &pipeline->base.device->info; @@ -2192,16 +1996,16 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, * source blend factors. */ bool dual_src_blend = false; - if (wm_prog_data->dual_src_blend && blend) { - for (uint32_t i = 0; i < blend->attachmentCount; i++) { - const VkPipelineColorBlendAttachmentState *bstate = - &blend->pAttachments[i]; + if (wm_prog_data->dual_src_blend && cb) { + for (uint32_t i = 0; i < cb->attachment_count; i++) { + const struct vk_color_blend_attachment_state *a = + &cb->attachments[i]; - if (bstate->blendEnable && - (is_dual_src_blend_factor(bstate->srcColorBlendFactor) || - is_dual_src_blend_factor(bstate->dstColorBlendFactor) || - is_dual_src_blend_factor(bstate->srcAlphaBlendFactor) || - is_dual_src_blend_factor(bstate->dstAlphaBlendFactor))) { + if (a->blend_enable && + (is_dual_src_blend_factor(a->src_color_blend_factor) || + is_dual_src_blend_factor(a->dst_color_blend_factor) || + is_dual_src_blend_factor(a->src_alpha_blend_factor) || + is_dual_src_blend_factor(a->dst_alpha_blend_factor))) { dual_src_blend = true; break; } @@ -2223,7 +2027,7 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, * the workaround on any older hardware. */ if (GFX_VER >= 9 && !wm_prog_data->persample_dispatch && - multisample && multisample->rasterizationSamples == 16) { + ms != NULL && ms->rasterization_samples == 16) { assert(ps._8PixelDispatchEnable || ps._16PixelDispatchEnable); ps._32PixelDispatchEnable = false; } @@ -2286,8 +2090,8 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, #if GFX_VER >= 8 static void emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, - const VkPipelineRasterizationStateCreateInfo *rs_info, - const VkRenderingSelfDependencyInfoMESA *rsd_info) + const struct vk_rasterization_state *rs, + const struct vk_render_pass_state *rp) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -2311,8 +2115,8 @@ emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, * around to fetching from the input attachment and we may get the depth * or stencil value from the current draw rather than the previous one. */ - ps.PixelShaderKillsPixel = rsd_info->depthSelfDependency || - rsd_info->stencilSelfDependency || + ps.PixelShaderKillsPixel = rp->depth_self_dependency || + rp->stencil_self_dependency || wm_prog_data->uses_kill; #if GFX_VER >= 9 @@ -2358,8 +2162,8 @@ emit_3dstate_vf_statistics(struct anv_graphics_pipeline *pipeline) static void compute_kill_pixel(struct anv_graphics_pipeline *pipeline, - const VkPipelineMultisampleStateCreateInfo *ms_info, - const VkRenderingSelfDependencyInfoMESA *rsd_info) + const struct vk_multisample_state *ms, + const struct vk_render_pass_state *rp) { if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) { pipeline->kill_pixel = false; @@ -2383,25 +2187,24 @@ compute_kill_pixel(struct anv_graphics_pipeline *pipeline, * of an alpha test. */ pipeline->kill_pixel = - rsd_info->depthSelfDependency || - rsd_info->stencilSelfDependency || + rp->depth_self_dependency || + rp->stencil_self_dependency || wm_prog_data->uses_kill || wm_prog_data->uses_omask || - (ms_info && ms_info->alphaToCoverageEnable); + (ms && ms->alpha_to_coverage_enable); } #if GFX_VER == 12 static void emit_3dstate_primitive_replication(struct anv_graphics_pipeline *pipeline, - const VkPipelineRenderingCreateInfo *rendering_info) + const struct vk_render_pass_state *rp) { if (!pipeline->use_primitive_replication) { anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr); return; } - uint32_t view_mask = rendering_info != NULL ? rendering_info->viewMask : 0; - int view_count = util_bitcount(view_mask); + int view_count = util_bitcount(rp->view_mask); assert(view_count > 1 && view_count <= MAX_VIEWS_FOR_PRIMITIVE_REPLICATION); anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr) { @@ -2409,7 +2212,7 @@ emit_3dstate_primitive_replication(struct anv_graphics_pipeline *pipeline, pr.ReplicationCount = view_count - 1; int i = 0; - u_foreach_bit(view_index, view_mask) { + u_foreach_bit(view_index, rp->view_mask) { pr.RTAIOffset[i] = view_index; i++; } @@ -2549,53 +2352,23 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline) void genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const VkPipelineRenderingCreateInfo *rendering_info, - const VkRenderingSelfDependencyInfoMESA *rsd_info) + const struct vk_graphics_pipeline_state *state) { - /* If rasterization is not enabled, various CreateInfo structs must be - * ignored. - */ - const bool raster_enabled = - !pCreateInfo->pRasterizationState->rasterizerDiscardEnable || - (pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE); - - const VkPipelineViewportStateCreateInfo *vp_info = - raster_enabled ? pCreateInfo->pViewportState : NULL; - - const VkPipelineMultisampleStateCreateInfo *ms_info = - raster_enabled ? pCreateInfo->pMultisampleState : NULL; - - const VkPipelineDepthStencilStateCreateInfo *ds_info = - raster_enabled ? pCreateInfo->pDepthStencilState : NULL; - - const VkPipelineColorBlendStateCreateInfo *cb_info = - raster_enabled ? pCreateInfo->pColorBlendState : NULL; - - const VkPipelineRasterizationLineStateCreateInfoEXT *line_info = - vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, - PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT); - enum intel_urb_deref_block_size urb_deref_block_size; emit_urb_setup(pipeline, &urb_deref_block_size); - assert(pCreateInfo->pRasterizationState); - emit_rs_state(pipeline, pCreateInfo->pInputAssemblyState, - pCreateInfo->pRasterizationState, - ms_info, line_info, rendering_info, + assert(state->rs != NULL); + emit_rs_state(pipeline, state->ia, state->rs, state->ms, state->rp, urb_deref_block_size); - emit_ms_state(pipeline, ms_info); - emit_ds_state(pipeline, ds_info, rendering_info); - emit_cb_state(pipeline, cb_info, ms_info); - compute_kill_pixel(pipeline, ms_info, rsd_info); + emit_ms_state(pipeline, state->ms); + emit_ds_state(pipeline, state->ds, state->rp); + emit_cb_state(pipeline, state->cb, state->ms); + compute_kill_pixel(pipeline, state->ms, state->rp); - emit_3dstate_clip(pipeline, - pCreateInfo->pInputAssemblyState, - vp_info, - pCreateInfo->pRasterizationState); + emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs); #if GFX_VER == 12 - emit_3dstate_primitive_replication(pipeline, rendering_info); + emit_3dstate_primitive_replication(pipeline, state->rp); #endif #if 0 @@ -2618,16 +2391,15 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, #endif if (anv_pipeline_is_primitive(pipeline)) { - assert(pCreateInfo->pVertexInputState); - emit_vertex_input(pipeline, pCreateInfo->pVertexInputState); + emit_vertex_input(pipeline, state->vi); emit_3dstate_vs(pipeline); - emit_3dstate_hs_te_ds(pipeline, pCreateInfo->pTessellationState); + emit_3dstate_hs_te_ds(pipeline, state->ts); emit_3dstate_gs(pipeline); emit_3dstate_vf_statistics(pipeline); - emit_3dstate_streamout(pipeline, pCreateInfo->pRasterizationState); + emit_3dstate_streamout(pipeline, state->rs); #if GFX_VERx10 >= 125 const struct anv_device *device = pipeline->base.device; @@ -2652,13 +2424,11 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, } emit_3dstate_sbe(pipeline); - emit_3dstate_wm(pipeline, - pCreateInfo->pInputAssemblyState, - pCreateInfo->pRasterizationState, - cb_info, ms_info, line_info, rsd_info); - emit_3dstate_ps(pipeline, cb_info, ms_info); + emit_3dstate_wm(pipeline, state->ia, state->rs, + state->ms, state->cb, state->rp); + emit_3dstate_ps(pipeline, state->ms, state->cb); #if GFX_VER >= 8 - emit_3dstate_ps_extra(pipeline, pCreateInfo->pRasterizationState, rsd_info); + emit_3dstate_ps_extra(pipeline, state->rs, state->rp); #endif }