anv: Convert to using vk_graphics_pipeline_state
This attempts to be a pretty minimal refactor. We just switch all the state emit code to use the new graphics pipeline state object. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17564>
This commit is contained in:
parent
44cbb7d9c8
commit
b656957c56
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue