VK_EXT_custom_border_color DONE (anv, lvp, panvk, radv, tu, v3dv, vn)
VK_EXT_debug_marker DONE (radv)
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_discard_rectangles DONE (radv)
VK_EXT_display_control DONE (anv, radv, tu)
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
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
uint32_t firstViewport,
.EXT_border_color_swizzle = true,
.EXT_color_write_enable = true,
.EXT_custom_border_color = true,
+ .EXT_depth_clip_control = true,
.EXT_inline_uniform_block = true,
.EXT_external_memory_dma_buf = true,
.EXT_host_query_reset = true,
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT: {
+ VkPhysicalDeviceDepthClipControlFeaturesEXT *features =
+ (VkPhysicalDeviceDepthClipControlFeaturesEXT *)ext;
+ features->depthClipControl = true;
+ break;
+ }
+
default:
v3dv_debug_ignored_stype(ext->sType);
break;
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
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,
pCreateInfo->pDynamicState,
vp_info, ds_info, cb_info, rs_info, cw_info);
} 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 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
uint32_t sample_mask;
bool primitive_restart;
+ bool negative_one_to_one;
/* Accessed by binding. So vb[binding]->stride is the stride of the vertex
* array with such binding
cl_aligned_f(&uniforms, dynamic->viewport.scale[0][1] * 256.0f);
break;
- case QUNIFORM_VIEWPORT_Z_OFFSET:
- cl_aligned_f(&uniforms, dynamic->viewport.translate[0][2]);
+ case QUNIFORM_VIEWPORT_Z_OFFSET: {
+ 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;
+ }
- case QUNIFORM_VIEWPORT_Z_SCALE:
- cl_aligned_f(&uniforms, dynamic->viewport.scale[0][2]);
+ case QUNIFORM_VIEWPORT_Z_SCALE: {
+ 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;
+ }
case QUNIFORM_SSBO_OFFSET:
case QUNIFORM_UBO_ADDR:
v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
{
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
* now, would need to change if we allow multiple viewports
*/
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) {
- clip.viewport_z_offset_zc_to_zs = vptranslate[2];
- clip.viewport_z_scale_zc_to_zs = vpscale[2];
+ clip.viewport_z_offset_zc_to_zs = translate_z;
+ clip.viewport_z_scale_zc_to_zs = scale_z;
}
cl_emit(&job->bcl, CLIPPER_Z_MIN_MAX_CLIPPING_PLANES, clip) {
- /* Vulkan's Z NDC is [0..1], unlile OpenGL which is [-1, 1] */
- float z1 = vptranslate[2];
- float z2 = vptranslate[2] + vpscale[2];
+ /* Vulkan's default Z NDC is [0..1]. If 'negative_one_to_one' is enabled,
+ * we are using OpenGL's [-1, 1] instead.
+ */
+ 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.maximum_zw = MAX2(z1, z2);
}