diff --git a/docs/features.txt b/docs/features.txt index 9c5c3c3f4e7..b3c58d01f55 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -593,7 +593,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_debug_utils DONE (anv, dzn, hasvk, hk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) VK_EXT_depth_bias_control DONE (anv, hk, nvk, panvk, radv, vn) VK_EXT_depth_clamp_control DONE (anv, hasvk, nvk, radv, vn) - VK_EXT_depth_clip_control DONE (anv, hasvk, hk, lvp, nvk, radv, tu, v3dv, vn) + VK_EXT_depth_clip_control DONE (anv, hasvk, hk, lvp, nvk, panvk, radv, tu, v3dv, vn) VK_EXT_depth_clip_enable DONE (anv, hasvk, hk, lvp, nvk, panvk, radv, tu, v3dv/vc7+, vn) VK_EXT_depth_range_unrestricted DONE (anv/gen20+, nvk, radv, lvp, vn) VK_EXT_descriptor_buffer DONE (anv, lvp, nvk, radv, tu) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index af233c01d39..ff62acc1b39 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -43,3 +43,4 @@ MSAA with 8 and 16 sample counts on panfrost cl_khr_spirv_queries VK_EXT_depth_clamp_zero_one on panvk VK_KHR_depth_clamp_zero_one on panvk +VK_EXT_depth_clip_control on panvk diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c index 31ec277760f..e94b378881e 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c @@ -695,6 +695,7 @@ prepare_vp(struct panvk_cmd_buffer *cmdbuf) } if (dyn_gfx_state_dirty(cmdbuf, VP_VIEWPORTS) || + dyn_gfx_state_dirty(cmdbuf, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLIP_ENABLE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLAMP_ENABLE)) { struct mali_viewport_packed mali_viewport; @@ -721,7 +722,8 @@ prepare_vp(struct panvk_cmd_buffer *cmdbuf) cfg.max_y = CLAMP(maxy, 0, UINT16_MAX); float z_min, z_max; - panvk_depth_range(&cmdbuf->state.gfx, &z_min, &z_max); + panvk_depth_range(&cmdbuf->state.gfx, + &cmdbuf->vk.dynamic_graphics_state.vp, &z_min, &z_max); cfg.min_depth = CLAMP(z_min, 0.0f, 1.0f); cfg.max_depth = CLAMP(z_max, 0.0f, 1.0f); } @@ -782,10 +784,12 @@ prepare_vp(struct panvk_cmd_buffer *cmdbuf) } if (dyn_gfx_state_dirty(cmdbuf, VP_VIEWPORTS) || + dyn_gfx_state_dirty(cmdbuf, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLIP_ENABLE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLAMP_ENABLE)) { float z_min, z_max; - panvk_depth_range(&cmdbuf->state.gfx, &z_min, &z_max); + panvk_depth_range(&cmdbuf->state.gfx, + &cmdbuf->vk.dynamic_graphics_state.vp, &z_min, &z_max); cs_move32_to(b, cs_sr_reg32(b, IDVS, LOW_DEPTH_CLAMP), fui(z_min)); cs_move32_to(b, cs_sr_reg32(b, IDVS, HIGH_DEPTH_CLAMP), fui(z_max)); } diff --git a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c index 37926049bf6..7cad6baa54e 100644 --- a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c @@ -676,7 +676,8 @@ panvk_emit_viewport(struct panvk_cmd_buffer *cmdbuf, const VkViewport *viewport = &vp->viewports[0]; const VkRect2D *scissor = &vp->scissors[0]; float minz, maxz; - panvk_depth_range(&cmdbuf->state.gfx, &minz, &maxz); + panvk_depth_range(&cmdbuf->state.gfx, &cmdbuf->vk.dynamic_graphics_state.vp, + &minz, &maxz); /* The spec says "width must be greater than 0.0" */ assert(viewport->width >= 0); @@ -722,6 +723,7 @@ panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf, * As a result, we define an empty one. */ if (!cmdbuf->state.gfx.vpd || dyn_gfx_state_dirty(cmdbuf, VP_VIEWPORTS) || + dyn_gfx_state_dirty(cmdbuf, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) || dyn_gfx_state_dirty(cmdbuf, VP_SCISSORS) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLIP_ENABLE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLAMP_ENABLE)) { diff --git a/src/panfrost/vulkan/panvk_cmd_draw.h b/src/panfrost/vulkan/panvk_cmd_draw.h index 4c2ee11521e..69de753e957 100644 --- a/src/panfrost/vulkan/panvk_cmd_draw.h +++ b/src/panfrost/vulkan/panvk_cmd_draw.h @@ -228,10 +228,13 @@ struct panvk_device_draw_context { static inline void panvk_depth_range(const struct panvk_cmd_graphics_state *state, + const struct vk_viewport_state *vp, float *z_min, float *z_max) { - float a = state->sysvals.viewport.offset.z; - float b = a + state->sysvals.viewport.scale.z; + float a = vp->depth_clip_negative_one_to_one ? + state->sysvals.viewport.offset.z - state->sysvals.viewport.scale.z : + state->sysvals.viewport.offset.z; + float b = state->sysvals.viewport.offset.z + state->sysvals.viewport.scale.z; *z_min = MIN2(a, b); *z_max = MAX2(a, b); } diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index 6e7f714e9d6..1f632132a9a 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -288,6 +288,7 @@ get_device_extensions(const struct panvk_physical_device *device, .EXT_depth_bias_control = true, .EXT_depth_clamp_zero_one = true, .EXT_depth_clip_enable = true, + .EXT_depth_clip_control = true, #ifdef VK_USE_PLATFORM_DISPLAY_KHR .EXT_display_control = true, #endif @@ -545,6 +546,9 @@ get_features(const struct panvk_instance *instance, .floatRepresentation = false, .depthBiasExact = true, + /* VK_EXT_depth_clip_control */ + .depthClipControl = true, + /* VK_EXT_depth_clip_enable */ .depthClipEnable = true, diff --git a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c index d9ada2ee788..e22558e1593 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c @@ -726,11 +726,14 @@ panvk_per_arch(cmd_prepare_draw_sysvals)(struct panvk_cmd_buffer *cmdbuf, } if (dyn_gfx_state_dirty(cmdbuf, VP_VIEWPORTS) || + dyn_gfx_state_dirty(cmdbuf, VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLIP_ENABLE) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_CLAMP_ENABLE)) { const struct vk_rasterization_state *rs = &cmdbuf->vk.dynamic_graphics_state.rs; - VkViewport *viewport = &cmdbuf->vk.dynamic_graphics_state.vp.viewports[0]; + const struct vk_viewport_state *vp = + &cmdbuf->vk.dynamic_graphics_state.vp; + const VkViewport *viewport = &vp->viewports[0]; /* Doing the viewport transform in the vertex shader and then depth * clipping with the viewport depth range gets a similar result to @@ -764,13 +767,16 @@ panvk_per_arch(cmd_prepare_draw_sysvals)(struct panvk_cmd_buffer *cmdbuf, * * px = width * py = height - * pz = maxDepth - minDepth + * pz = maxDepth - minDepth if negativeOneToOne is false + * pz = (maxDepth - minDepth) / 2 if negativeOneToOne is true */ set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.scale.x, 0.5f * viewport->width); set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.scale.y, 0.5f * viewport->height); - set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.scale.z, z_max - z_min); + set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.scale.z, + vp->depth_clip_negative_one_to_one ? + 0.5f * (z_max - z_min) : z_max - z_min); /* Upload the viewport offset. Defined as (ox, oy, oz) at the start of * section 24.5 ("Controlling the Viewport") of the Vulkan spec. At the @@ -778,13 +784,17 @@ panvk_per_arch(cmd_prepare_draw_sysvals)(struct panvk_cmd_buffer *cmdbuf, * * ox = x + width/2 * oy = y + height/2 - * oz = minDepth + * oz = minDepth if negativeOneToOne is false + * oz = (maxDepth + minDepth) / 2 if negativeOneToOne is true */ set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.offset.x, (0.5f * viewport->width) + viewport->x); set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.offset.y, (0.5f * viewport->height) + viewport->y); - set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.offset.z, z_min); + set_gfx_sysval(cmdbuf, dirty_sysvals, viewport.offset.z, + vp->depth_clip_negative_one_to_one ? + 0.5f * (z_min + z_max) : z_min); + } if (dyn_gfx_state_dirty(cmdbuf, INPUT_ATTACHMENT_MAP))