v3dv: implement VK_EXT_depth_clip_control
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18387>
This commit is contained in:

committed by
Marge Bot

parent
c6a9897b76
commit
bcc37775f1
@@ -545,7 +545,7 @@ Khronos extensions that are not part of any Vulkan version:
|
|||||||
VK_EXT_custom_border_color DONE (anv, lvp, panvk, radv, tu, v3dv, vn)
|
VK_EXT_custom_border_color DONE (anv, lvp, panvk, radv, tu, v3dv, vn)
|
||||||
VK_EXT_debug_marker DONE (radv)
|
VK_EXT_debug_marker DONE (radv)
|
||||||
VK_EXT_depth_clip_enable DONE (anv, lvp, radv, tu, vn)
|
VK_EXT_depth_clip_enable DONE (anv, lvp, radv, tu, vn)
|
||||||
VK_EXT_depth_clip_control DONE (anv, lvp, radv, tu)
|
VK_EXT_depth_clip_control DONE (anv, lvp, radv, tu, v3dv)
|
||||||
VK_EXT_depth_range_unrestricted DONE (radv, lvp)
|
VK_EXT_depth_range_unrestricted DONE (radv, lvp)
|
||||||
VK_EXT_discard_rectangles DONE (radv)
|
VK_EXT_discard_rectangles DONE (radv)
|
||||||
VK_EXT_display_control DONE (anv, radv, tu)
|
VK_EXT_display_control DONE (anv, radv, tu)
|
||||||
|
@@ -2112,6 +2112,33 @@ v3dv_viewport_compute_xform(const VkViewport *viewport,
|
|||||||
scale[2] = min_abs_scale * (scale[2] < 0 ? -1.0f : 1.0f);
|
scale[2] = min_abs_scale * (scale[2] < 0 ? -1.0f : 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Considers the pipeline's negative_one_to_one state and applies it to the
|
||||||
|
* current viewport transform if needed to produce the resulting Z translate
|
||||||
|
* and scale parameters.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer_state *state,
|
||||||
|
uint32_t vp_idx,
|
||||||
|
float *translate_z, float *scale_z)
|
||||||
|
{
|
||||||
|
const struct v3dv_viewport_state *vp_state = &state->dynamic.viewport;
|
||||||
|
|
||||||
|
float t = vp_state->translate[vp_idx][2];
|
||||||
|
float s = vp_state->scale[vp_idx][2];
|
||||||
|
|
||||||
|
assert(state->gfx.pipeline);
|
||||||
|
if (state->gfx.pipeline->negative_one_to_one) {
|
||||||
|
t = (t + vp_state->viewports[vp_idx].maxDepth) * 0.5f;
|
||||||
|
s *= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (translate_z)
|
||||||
|
*translate_z = t;
|
||||||
|
|
||||||
|
if (scale_z)
|
||||||
|
*scale_z = s;
|
||||||
|
}
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
|
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
|
||||||
uint32_t firstViewport,
|
uint32_t firstViewport,
|
||||||
|
@@ -169,6 +169,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
|
|||||||
.EXT_border_color_swizzle = true,
|
.EXT_border_color_swizzle = true,
|
||||||
.EXT_color_write_enable = true,
|
.EXT_color_write_enable = true,
|
||||||
.EXT_custom_border_color = true,
|
.EXT_custom_border_color = true,
|
||||||
|
.EXT_depth_clip_control = true,
|
||||||
.EXT_inline_uniform_block = true,
|
.EXT_inline_uniform_block = true,
|
||||||
.EXT_external_memory_dma_buf = true,
|
.EXT_external_memory_dma_buf = true,
|
||||||
.EXT_host_query_reset = true,
|
.EXT_host_query_reset = true,
|
||||||
@@ -1314,6 +1315,13 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT: {
|
||||||
|
VkPhysicalDeviceDepthClipControlFeaturesEXT *features =
|
||||||
|
(VkPhysicalDeviceDepthClipControlFeaturesEXT *)ext;
|
||||||
|
features->depthClipControl = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
v3dv_debug_ignored_stype(ext->sType);
|
v3dv_debug_ignored_stype(ext->sType);
|
||||||
break;
|
break;
|
||||||
|
@@ -2977,6 +2977,14 @@ pipeline_init(struct v3dv_pipeline *pipeline,
|
|||||||
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
|
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
if (vp_info) {
|
||||||
|
const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_control =
|
||||||
|
vk_find_struct_const(vp_info->pNext,
|
||||||
|
PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT);
|
||||||
|
if (depth_clip_control)
|
||||||
|
pipeline->negative_one_to_one = depth_clip_control->negativeOneToOne;
|
||||||
|
}
|
||||||
|
|
||||||
pipeline_init_dynamic_state(pipeline,
|
pipeline_init_dynamic_state(pipeline,
|
||||||
pCreateInfo->pDynamicState,
|
pCreateInfo->pDynamicState,
|
||||||
vp_info, ds_info, cb_info, rs_info, cw_info);
|
vp_info, ds_info, cb_info, rs_info, cw_info);
|
||||||
|
@@ -1432,6 +1432,11 @@ struct v3dv_cmd_buffer_state {
|
|||||||
} query;
|
} query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer_state *state,
|
||||||
|
uint32_t vp_idx,
|
||||||
|
float *translate_z, float *scale_z);
|
||||||
|
|
||||||
/* The following struct represents the info from a descriptor that we store on
|
/* The following struct represents the info from a descriptor that we store on
|
||||||
* the host memory. They are mostly links to other existing vulkan objects,
|
* the host memory. They are mostly links to other existing vulkan objects,
|
||||||
* like the image_view in order to access to swizzle info, or the buffer used
|
* like the image_view in order to access to swizzle info, or the buffer used
|
||||||
@@ -2077,6 +2082,7 @@ struct v3dv_pipeline {
|
|||||||
uint32_t sample_mask;
|
uint32_t sample_mask;
|
||||||
|
|
||||||
bool primitive_restart;
|
bool primitive_restart;
|
||||||
|
bool negative_one_to_one;
|
||||||
|
|
||||||
/* Accessed by binding. So vb[binding]->stride is the stride of the vertex
|
/* Accessed by binding. So vb[binding]->stride is the stride of the vertex
|
||||||
* array with such binding
|
* array with such binding
|
||||||
|
@@ -527,13 +527,21 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
|
|||||||
cl_aligned_f(&uniforms, dynamic->viewport.scale[0][1] * 256.0f);
|
cl_aligned_f(&uniforms, dynamic->viewport.scale[0][1] * 256.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QUNIFORM_VIEWPORT_Z_OFFSET:
|
case QUNIFORM_VIEWPORT_Z_OFFSET: {
|
||||||
cl_aligned_f(&uniforms, dynamic->viewport.translate[0][2]);
|
float translate_z;
|
||||||
|
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
|
||||||
|
&translate_z, NULL);
|
||||||
|
cl_aligned_f(&uniforms, translate_z);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QUNIFORM_VIEWPORT_Z_SCALE:
|
case QUNIFORM_VIEWPORT_Z_SCALE: {
|
||||||
cl_aligned_f(&uniforms, dynamic->viewport.scale[0][2]);
|
float scale_z;
|
||||||
|
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
|
||||||
|
NULL, &scale_z);
|
||||||
|
cl_aligned_f(&uniforms, scale_z);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QUNIFORM_SSBO_OFFSET:
|
case QUNIFORM_SSBO_OFFSET:
|
||||||
case QUNIFORM_UBO_ADDR:
|
case QUNIFORM_UBO_ADDR:
|
||||||
|
@@ -1008,6 +1008,9 @@ void
|
|||||||
v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
|
v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
{
|
{
|
||||||
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
||||||
|
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||||
|
assert(pipeline);
|
||||||
|
|
||||||
/* FIXME: right now we only support one viewport. viewporst[0] would work
|
/* FIXME: right now we only support one viewport. viewporst[0] would work
|
||||||
* now, would need to change if we allow multiple viewports
|
* now, would need to change if we allow multiple viewports
|
||||||
*/
|
*/
|
||||||
@@ -1030,14 +1033,21 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
|
|||||||
clip.viewport_half_height_in_1_256th_of_pixel = vpscale[1] * 256.0f;
|
clip.viewport_half_height_in_1_256th_of_pixel = vpscale[1] * 256.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float translate_z, scale_z;
|
||||||
|
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
|
||||||
|
&translate_z, &scale_z);
|
||||||
|
|
||||||
cl_emit(&job->bcl, CLIPPER_Z_SCALE_AND_OFFSET, clip) {
|
cl_emit(&job->bcl, CLIPPER_Z_SCALE_AND_OFFSET, clip) {
|
||||||
clip.viewport_z_offset_zc_to_zs = vptranslate[2];
|
clip.viewport_z_offset_zc_to_zs = translate_z;
|
||||||
clip.viewport_z_scale_zc_to_zs = vpscale[2];
|
clip.viewport_z_scale_zc_to_zs = scale_z;
|
||||||
}
|
}
|
||||||
cl_emit(&job->bcl, CLIPPER_Z_MIN_MAX_CLIPPING_PLANES, clip) {
|
cl_emit(&job->bcl, CLIPPER_Z_MIN_MAX_CLIPPING_PLANES, clip) {
|
||||||
/* Vulkan's Z NDC is [0..1], unlile OpenGL which is [-1, 1] */
|
/* Vulkan's default Z NDC is [0..1]. If 'negative_one_to_one' is enabled,
|
||||||
float z1 = vptranslate[2];
|
* we are using OpenGL's [-1, 1] instead.
|
||||||
float z2 = vptranslate[2] + vpscale[2];
|
*/
|
||||||
|
float z1 = pipeline->negative_one_to_one ? translate_z - scale_z :
|
||||||
|
translate_z;
|
||||||
|
float z2 = translate_z + scale_z;
|
||||||
clip.minimum_zw = MIN2(z1, z2);
|
clip.minimum_zw = MIN2(z1, z2);
|
||||||
clip.maximum_zw = MAX2(z1, z2);
|
clip.maximum_zw = MAX2(z1, z2);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user