From 68b02ff200cc9cd37afb48efc57825bfdee60fda Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 30 Sep 2022 12:42:27 +0200 Subject: [PATCH] tu: Implement extendedDynamicState3DepthClipNegativeOneToOne Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 29 +++++++++++++++++++++++++- src/freedreno/vulkan/tu_device.c | 2 +- src/freedreno/vulkan/tu_pipeline.c | 31 ++++++++++++++++++++++++++-- src/freedreno/vulkan/tu_pipeline.h | 5 +++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 878e6e5d442..15fdaac07bb 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2635,11 +2635,24 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, tu6_update_msaa_samples(cmd, pipeline->output.samples); if ((pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_VIEWPORT)) && + !(pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_VIEWPORT_RANGE)) && (pipeline->viewport.z_negative_one_to_one != cmd->state.z_negative_one_to_one)) { cmd->state.z_negative_one_to_one = pipeline->viewport.z_negative_one_to_one; cmd->state.dirty |= TU_CMD_DIRTY_VIEWPORTS; } + if (pipeline->viewport.set_dynamic_vp_to_static) { + memcpy(cmd->state.viewport, pipeline->viewport.viewports, + pipeline->viewport.num_viewports * + sizeof(pipeline->viewport.viewports[0])); + + /* Any viewports set dynamically are invalidated when the pipeline is + * bound, so we don't need to take the max here. + */ + cmd->state.max_viewport = pipeline->viewport.num_viewports; + cmd->state.dirty |= TU_CMD_DIRTY_VIEWPORTS; + } + if (!(pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_VIEWPORT))) cmd->state.dirty &= ~TU_CMD_DIRTY_VIEWPORTS; @@ -3228,6 +3241,20 @@ tu_CmdSetAlphaToOneEnableEXT(VkCommandBuffer commandBuffer, cmd->state.dirty |= TU_CMD_DIRTY_BLEND; } +VKAPI_ATTR void VKAPI_CALL +tu_CmdSetDepthClipNegativeOneToOneEXT(VkCommandBuffer commandBuffer, + VkBool32 negativeOneToOne) +{ + TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + + cmd->state.gras_cl_cntl = + (cmd->state.gras_cl_cntl & ~A6XX_GRAS_CL_CNTL_ZERO_GB_SCALE_Z) | + COND(!negativeOneToOne, A6XX_GRAS_CL_CNTL_ZERO_GB_SCALE_Z); + cmd->state.z_negative_one_to_one = negativeOneToOne; + + cmd->state.dirty |= TU_CMD_DIRTY_RAST | TU_CMD_DIRTY_VIEWPORTS; +} + static void tu_flush_for_access(struct tu_cache_state *cache, enum tu_cmd_access_mask src_mask, @@ -4675,7 +4702,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, if (dirty & TU_CMD_DIRTY_VIEWPORTS) { struct tu_cs cs = tu_cmd_dynamic_state(cmd, VK_DYNAMIC_STATE_VIEWPORT, 8 + 10 * cmd->state.max_viewport); tu6_emit_viewport(&cs, cmd->state.viewport, cmd->state.max_viewport, - pipeline->viewport.z_negative_one_to_one); + cmd->state.z_negative_one_to_one); } if (dirty & TU_CMD_DIRTY_BLEND) { diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 92c6f73a4c5..dcb25dac48f 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -770,7 +770,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, features->extendedDynamicState3RasterizationSamples = true; features->extendedDynamicState3AlphaToCoverageEnable = true; features->extendedDynamicState3AlphaToOneEnable = true; - features->extendedDynamicState3DepthClipNegativeOneToOne = false; + features->extendedDynamicState3DepthClipNegativeOneToOne = true; features->extendedDynamicState3RasterizationStream = false; features->extendedDynamicState3ConservativeRasterizationMode = false; features->extendedDynamicState3ExtraPrimitiveOverestimationSize = false; diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 706258de49b..5a301adb608 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -3598,6 +3598,7 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, return; bool dynamic_depth_clip = false, dynamic_depth_clamp = false; + bool dynamic_viewport = false, dynamic_viewport_range = false; for (uint32_t i = 0; i < dynamic_info->dynamicStateCount; i++) { VkDynamicState state = dynamic_info->pDynamicStates[i]; @@ -3606,6 +3607,8 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, if (state == VK_DYNAMIC_STATE_LINE_WIDTH) pipeline->rast.gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK; pipeline->dynamic_state_mask |= BIT(state); + if (state == VK_DYNAMIC_STATE_VIEWPORT) + dynamic_viewport = true; break; case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_SAMPLE_LOCATIONS); @@ -3627,6 +3630,7 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, break; case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: pipeline->dynamic_state_mask |= BIT(VK_DYNAMIC_STATE_VIEWPORT); + dynamic_viewport = true; break; case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: pipeline->dynamic_state_mask |= BIT(VK_DYNAMIC_STATE_SCISSOR); @@ -3759,6 +3763,15 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, pipeline->blend.rb_blend_cntl_mask &= ~A6XX_RB_BLEND_CNTL_ALPHA_TO_ONE; break; + case VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT: + pipeline->dynamic_state_mask |= + BIT(VK_DYNAMIC_STATE_VIEWPORT) | + BIT(TU_DYNAMIC_STATE_RAST) | + BIT(TU_DYNAMIC_STATE_VIEWPORT_RANGE); + pipeline->rast.gras_cl_cntl_mask &= + ~A6XX_GRAS_CL_CNTL_ZERO_GB_SCALE_Z; + dynamic_viewport_range = true; + break; default: assert(!"unsupported dynamic state"); break; @@ -3767,6 +3780,14 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, pipeline->rast.override_depth_clip = dynamic_depth_clamp && !dynamic_depth_clip; + + /* If the viewport range is dynamic, the viewport may need to be adjusted + * dynamically so we can't emit it up-front, but we need to copy the state + * viewport state to the dynamic state as if we had called CmdSetViewport() + * when binding the pipeline. + */ + pipeline->viewport.set_dynamic_vp_to_static = + dynamic_viewport_range && !dynamic_viewport; } static void @@ -3820,7 +3841,8 @@ tu_pipeline_builder_parse_libraries(struct tu_pipeline_builder *builder, BIT(TU_DYNAMIC_STATE_RASTERIZER_DISCARD) | BIT(TU_DYNAMIC_STATE_PATCH_CONTROL_POINTS) | BIT(TU_DYNAMIC_STATE_POLYGON_MODE) | - BIT(TU_DYNAMIC_STATE_TESS_DOMAIN_ORIGIN); + BIT(TU_DYNAMIC_STATE_TESS_DOMAIN_ORIGIN) | + BIT(TU_DYNAMIC_STATE_VIEWPORT_RANGE); } if (library->state & @@ -4152,8 +4174,13 @@ tu_pipeline_builder_parse_viewport(struct tu_pipeline_builder *builder, struct tu_cs cs; - if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_VIEWPORT, 8 + 10 * vp_info->viewportCount)) + if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_VIEWPORT, 8 + 10 * vp_info->viewportCount)) { tu6_emit_viewport(&cs, vp_info->pViewports, vp_info->viewportCount, pipeline->viewport.z_negative_one_to_one); + } else if (pipeline->viewport.set_dynamic_vp_to_static) { + memcpy(pipeline->viewport.viewports, vp_info->pViewports, + vp_info->viewportCount * sizeof(*vp_info->pViewports)); + pipeline->viewport.num_viewports = vp_info->viewportCount; + } if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_SCISSOR, 1 + 2 * vp_info->scissorCount)) tu6_emit_scissor(&cs, vp_info->pScissors, vp_info->scissorCount); diff --git a/src/freedreno/vulkan/tu_pipeline.h b/src/freedreno/vulkan/tu_pipeline.h index 74283d6a0db..83e91563cbd 100644 --- a/src/freedreno/vulkan/tu_pipeline.h +++ b/src/freedreno/vulkan/tu_pipeline.h @@ -39,6 +39,8 @@ enum tu_dynamic_state TU_DYNAMIC_STATE_TESS_DOMAIN_ORIGIN, TU_DYNAMIC_STATE_MSAA_SAMPLES, TU_DYNAMIC_STATE_ALPHA_TO_COVERAGE, + TU_DYNAMIC_STATE_DEPTH_CLIP_RANGE, + TU_DYNAMIC_STATE_VIEWPORT_RANGE, /* re-use the line width enum as it uses GRAS_SU_CNTL: */ TU_DYNAMIC_STATE_RAST = VK_DYNAMIC_STATE_LINE_WIDTH, }; @@ -243,6 +245,9 @@ struct tu_pipeline struct tu_lrz_pipeline lrz; struct { + VkViewport viewports[MAX_VIEWPORTS]; + unsigned num_viewports; + bool set_dynamic_vp_to_static; bool z_negative_one_to_one; } viewport;