radv: disable viewport depth clamping only when necessary
When the application uses depth values outside of the [0.0,1.0] range with VK_EXT_depth_range_unrestricted, or when explicitly disabled. Otherwise, the driver can clamp to [0.0,1.0] internally for optimal performance. From the Vulkan spec "in 28.10.1. Depth Clamping and Range Adjustment": "If depth clamping is not enabled and zf is not in the range [0, 1] and either VK_EXT_depth_range_unrestricted is not enabled, or the depth attachment has a fixed-point format, then zf is undefined following this step." Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16349>
This commit is contained in:

committed by
Marge Bot

parent
bec3c83e19
commit
203afc9351
@@ -1426,7 +1426,7 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
static void
|
static void
|
||||||
radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
|
radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
|
||||||
{
|
{
|
||||||
bool negative_one_to_one = cmd_buffer->state.graphics_pipeline->negative_one_to_one;
|
const struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline;
|
||||||
const struct radv_viewport_state *viewport = &cmd_buffer->state.dynamic.viewport;
|
const struct radv_viewport_state *viewport = &cmd_buffer->state.dynamic.viewport;
|
||||||
int i;
|
int i;
|
||||||
const unsigned count = viewport->count;
|
const unsigned count = viewport->count;
|
||||||
@@ -1441,7 +1441,7 @@ radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
radeon_emit(cmd_buffer->cs, fui(viewport->xform[i].translate[1]));
|
radeon_emit(cmd_buffer->cs, fui(viewport->xform[i].translate[1]));
|
||||||
|
|
||||||
double scale_z, translate_z;
|
double scale_z, translate_z;
|
||||||
if (negative_one_to_one) {
|
if (pipeline->negative_one_to_one) {
|
||||||
scale_z = viewport->xform[i].scale[2] * 0.5f;
|
scale_z = viewport->xform[i].scale[2] * 0.5f;
|
||||||
translate_z = (viewport->xform[i].translate[2] + viewport->viewports[i].maxDepth) * 0.5f;
|
translate_z = (viewport->xform[i].translate[2] + viewport->viewports[i].maxDepth) * 0.5f;
|
||||||
} else {
|
} else {
|
||||||
@@ -1455,8 +1455,16 @@ radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
|
|
||||||
radeon_set_context_reg_seq(cmd_buffer->cs, R_0282D0_PA_SC_VPORT_ZMIN_0, count * 2);
|
radeon_set_context_reg_seq(cmd_buffer->cs, R_0282D0_PA_SC_VPORT_ZMIN_0, count * 2);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
float zmin = MIN2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
|
float zmin, zmax;
|
||||||
float zmax = MAX2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
|
|
||||||
|
if (pipeline->depth_clamp_mode == RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE) {
|
||||||
|
zmin = 0.0f;
|
||||||
|
zmax = 1.0f;
|
||||||
|
} else {
|
||||||
|
zmin = MIN2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
|
||||||
|
zmax = MAX2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
|
||||||
|
}
|
||||||
|
|
||||||
radeon_emit(cmd_buffer->cs, fui(zmin));
|
radeon_emit(cmd_buffer->cs, fui(zmin));
|
||||||
radeon_emit(cmd_buffer->cs, fui(zmax));
|
radeon_emit(cmd_buffer->cs, fui(zmax));
|
||||||
}
|
}
|
||||||
|
@@ -2145,7 +2145,7 @@ static void
|
|||||||
radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
|
radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
|
||||||
const struct radv_graphics_pipeline_info *info)
|
const struct radv_graphics_pipeline_info *info)
|
||||||
{
|
{
|
||||||
const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
|
const struct radv_device *device = pipeline->base.device;
|
||||||
|
|
||||||
pipeline->pa_su_sc_mode_cntl =
|
pipeline->pa_su_sc_mode_cntl =
|
||||||
S_028814_FACE(info->rs.front_face) |
|
S_028814_FACE(info->rs.front_face) |
|
||||||
@@ -2159,7 +2159,7 @@ radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
S_028814_POLY_OFFSET_PARA_ENABLE(info->rs.depth_bias_enable) |
|
S_028814_POLY_OFFSET_PARA_ENABLE(info->rs.depth_bias_enable) |
|
||||||
S_028814_PROVOKING_VTX_LAST(info->rs.provoking_vtx_last);
|
S_028814_PROVOKING_VTX_LAST(info->rs.provoking_vtx_last);
|
||||||
|
|
||||||
if (pdevice->rad_info.gfx_level >= GFX10) {
|
if (device->physical_device->rad_info.gfx_level >= GFX10) {
|
||||||
/* It should also be set if PERPENDICULAR_ENDCAP_ENA is set. */
|
/* It should also be set if PERPENDICULAR_ENDCAP_ENA is set. */
|
||||||
pipeline->pa_su_sc_mode_cntl |=
|
pipeline->pa_su_sc_mode_cntl |=
|
||||||
S_028814_KEEP_TOGETHER_ENABLE(info->rs.polygon_mode != V_028814_X_DRAW_TRIANGLES);
|
S_028814_KEEP_TOGETHER_ENABLE(info->rs.polygon_mode != V_028814_X_DRAW_TRIANGLES);
|
||||||
@@ -2174,6 +2174,20 @@ radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
|
|
||||||
pipeline->uses_conservative_overestimate =
|
pipeline->uses_conservative_overestimate =
|
||||||
info->rs.conservative_mode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
|
info->rs.conservative_mode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
|
||||||
|
|
||||||
|
pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_VIEWPORT;
|
||||||
|
if (!info->rs.depth_clamp_enable) {
|
||||||
|
/* For optimal performance, depth clamping should always be enabled except if the
|
||||||
|
* application disables clamping explicitly or uses depth values outside of the [0.0, 1.0]
|
||||||
|
* range.
|
||||||
|
*/
|
||||||
|
if (info->rs.depth_clip_disable ||
|
||||||
|
device->vk.enabled_extensions.EXT_depth_range_unrestricted) {
|
||||||
|
pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_DISABLED;
|
||||||
|
} else {
|
||||||
|
pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct radv_depth_stencil_state
|
static struct radv_depth_stencil_state
|
||||||
@@ -2181,7 +2195,6 @@ radv_pipeline_init_depth_stencil_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
const struct radv_graphics_pipeline_info *info)
|
const struct radv_graphics_pipeline_info *info)
|
||||||
{
|
{
|
||||||
const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
|
const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
|
||||||
struct radv_shader *ps = pipeline->base.shaders[MESA_SHADER_FRAGMENT];
|
|
||||||
struct radv_depth_stencil_state ds_state = {0};
|
struct radv_depth_stencil_state ds_state = {0};
|
||||||
uint32_t db_depth_control = 0;
|
uint32_t db_depth_control = 0;
|
||||||
|
|
||||||
@@ -2210,19 +2223,8 @@ radv_pipeline_init_depth_stencil_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
ds_state.db_render_override |= S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
|
ds_state.db_render_override |= S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
|
||||||
S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
|
S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
|
||||||
|
|
||||||
if (!info->rs.depth_clamp_enable && ps->info.ps.writes_z) {
|
if (pipeline->depth_clamp_mode == RADV_DEPTH_CLAMP_MODE_DISABLED)
|
||||||
/* From VK_EXT_depth_range_unrestricted spec:
|
|
||||||
*
|
|
||||||
* "The behavior described in Primitive Clipping still applies.
|
|
||||||
* If depth clamping is disabled the depth values are still
|
|
||||||
* clipped to 0 ≤ zc ≤ wc before the viewport transform. If
|
|
||||||
* depth clamping is enabled the above equation is ignored and
|
|
||||||
* the depth values are instead clamped to the VkViewport
|
|
||||||
* minDepth and maxDepth values, which in the case of this
|
|
||||||
* extension can be outside of the 0.0 to 1.0 range."
|
|
||||||
*/
|
|
||||||
ds_state.db_render_override |= S_02800C_DISABLE_VIEWPORT_CLAMP(1);
|
ds_state.db_render_override |= S_02800C_DISABLE_VIEWPORT_CLAMP(1);
|
||||||
}
|
|
||||||
|
|
||||||
if (pdevice->rad_info.gfx_level >= GFX11) {
|
if (pdevice->rad_info.gfx_level >= GFX11) {
|
||||||
unsigned max_allowed_tiles_in_wave = 0;
|
unsigned max_allowed_tiles_in_wave = 0;
|
||||||
|
@@ -2078,6 +2078,12 @@ struct radv_graphics_pipeline_info {
|
|||||||
uint8_t ds_att_samples;
|
uint8_t ds_att_samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum radv_depth_clamp_mode {
|
||||||
|
RADV_DEPTH_CLAMP_MODE_VIEWPORT = 0, /* Clamp to the viewport min/max depth bounds */
|
||||||
|
RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE = 1, /* Clamp between 0.0f and 1.0f */
|
||||||
|
RADV_DEPTH_CLAMP_MODE_DISABLED = 2, /* Disable depth clamping */
|
||||||
|
};
|
||||||
|
|
||||||
struct radv_pipeline {
|
struct radv_pipeline {
|
||||||
struct vk_object_base base;
|
struct vk_object_base base;
|
||||||
enum radv_pipeline_type type;
|
enum radv_pipeline_type type;
|
||||||
@@ -2153,6 +2159,7 @@ struct radv_graphics_pipeline {
|
|||||||
bool uses_dynamic_stride;
|
bool uses_dynamic_stride;
|
||||||
bool uses_conservative_overestimate;
|
bool uses_conservative_overestimate;
|
||||||
bool negative_one_to_one;
|
bool negative_one_to_one;
|
||||||
|
enum radv_depth_clamp_mode depth_clamp_mode;
|
||||||
bool use_per_attribute_vb_descs;
|
bool use_per_attribute_vb_descs;
|
||||||
bool can_use_simple_input;
|
bool can_use_simple_input;
|
||||||
bool uses_user_sample_locations;
|
bool uses_user_sample_locations;
|
||||||
|
Reference in New Issue
Block a user