VK_EXT_custom_border_color DONE (anv, lvp, radv, tu, v3dv)
VK_EXT_debug_marker DONE (radv)
VK_EXT_depth_clip_enable DONE (anv, lvp, radv, tu)
- VK_EXT_depth_clip_control DONE (lvp)
+ VK_EXT_depth_clip_control DONE (lvp, tu)
VK_EXT_depth_range_unrestricted DONE (radv)
VK_EXT_discard_rectangles DONE (radv)
VK_EXT_display_control DONE (anv, tu)
}
}
+ if ((pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_VIEWPORT)) &&
+ (pipeline->z_negative_one_to_one != cmd->state.z_negative_one_to_one)) {
+ cmd->state.z_negative_one_to_one = pipeline->z_negative_one_to_one;
+ cmd->state.dirty |= TU_CMD_DIRTY_VIEWPORTS;
+ }
+
/* the vertex_buffers draw state always contains all the currently
* bound vertex buffers. update its size to only emit the vbs which
* are actually used by the pipeline
const VkViewport *pViewports)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
- struct tu_cs cs;
memcpy(&cmd->state.viewport[firstViewport], pViewports, viewportCount * sizeof(*pViewports));
cmd->state.max_viewport = MAX2(cmd->state.max_viewport, firstViewport + viewportCount);
- 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);
+ /* With VK_EXT_depth_clip_control we have to take into account
+ * negativeOneToOne property of the pipeline, so the viewport calculations
+ * are deferred until it is known.
+ */
+ cmd->state.dirty |= TU_CMD_DIRTY_VIEWPORTS;
}
VKAPI_ATTR void VKAPI_CALL
tu6_emit_consts(cmd, pipeline, descriptors_state, MESA_SHADER_FRAGMENT);
}
+ if (cmd->state.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->z_negative_one_to_one);
+ }
+
/* for the first draw in a renderpass, re-emit all the draw states
*
* and if a draw-state disabling path (CmdClearAttachments 3D fallback) was
.EXT_4444_formats = true,
.EXT_conditional_rendering = true,
.EXT_custom_border_color = true,
+ .EXT_depth_clip_control = true,
.EXT_depth_clip_enable = true,
.EXT_descriptor_indexing = true,
.EXT_extended_dynamic_state = true,
features->rasterizationOrderStencilAttachmentAccess = true;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT: {
+ VkPhysicalDeviceDepthClipControlFeaturesEXT *features =
+ (VkPhysicalDeviceDepthClipControlFeaturesEXT *)ext;
+ features->depthClipControl = true;
+ break;
+ }
default:
break;
*
* - Loader interface v4 differs from v3 in:
* - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().
- *
+ *
* - Loader interface v5 differs from v4 in:
- * - The ICD must support Vulkan API version 1.1 and must not return
+ * - The ICD must support Vulkan API version 1.1 and must not return
* VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a
* Vulkan Loader with interface v4 or smaller is being used and the
* application provides an API version that is greater than 1.0.
}
void
-tu6_emit_viewport(struct tu_cs *cs, const VkViewport *viewports, uint32_t num_viewport)
+tu6_emit_viewport(struct tu_cs *cs, const VkViewport *viewports, uint32_t num_viewport,
+ bool z_negative_one_to_one)
{
VkExtent2D guardband = {511, 511};
float scales[3];
scales[0] = viewport->width / 2.0f;
scales[1] = viewport->height / 2.0f;
- scales[2] = viewport->maxDepth - viewport->minDepth;
+ if (z_negative_one_to_one) {
+ scales[2] = 0.5 * (viewport->maxDepth - viewport->minDepth);
+ } else {
+ scales[2] = viewport->maxDepth - viewport->minDepth;
+ }
+
offsets[0] = viewport->x + scales[0];
offsets[1] = viewport->y + scales[1];
- offsets[2] = viewport->minDepth;
+ if (z_negative_one_to_one) {
+ offsets[2] = 0.5 * (viewport->minDepth + viewport->maxDepth);
+ } else {
+ offsets[2] = viewport->minDepth;
+ }
+
for (uint32_t j = 0; j < 3; j++) {
tu_cs_emit(cs, fui(offsets[j]));
tu_cs_emit(cs, fui(scales[j]));
const VkPipelineViewportStateCreateInfo *vp_info =
builder->create_info->pViewportState;
+ const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_info =
+ vk_find_struct_const(vp_info->pNext, PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT);
+ pipeline->z_negative_one_to_one = depth_clip_info ? depth_clip_info->negativeOneToOne : false;
struct tu_cs cs;
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);
+ tu6_emit_viewport(&cs, vp_info->pViewports, vp_info->viewportCount, pipeline->z_negative_one_to_one);
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);
.zfar_clip_disable = depth_clip_disable,
/* TODO should this be depth_clip_disable instead? */
.unk5 = rast_info->depthClampEnable,
- .zero_gb_scale_z = 1,
+ .zero_gb_scale_z = pipeline->z_negative_one_to_one ? 0 : 1,
.vp_clip_code_ignore = 1));
tu_cs_emit_regs(&cs,
TU_CMD_DIRTY_LRZ = BIT(8),
TU_CMD_DIRTY_VS_PARAMS = BIT(9),
TU_CMD_DIRTY_RASTERIZER_DISCARD = BIT(10),
+ TU_CMD_DIRTY_VIEWPORTS = BIT(11),
/* all draw states were disabled and need to be re-enabled: */
- TU_CMD_DIRTY_DRAW_STATE = BIT(11)
+ TU_CMD_DIRTY_DRAW_STATE = BIT(12)
};
/* There are only three cache domains we have to care about: the CCU, or
bool predication_active;
bool disable_gmem;
enum a5xx_line_mode line_mode;
+ bool z_negative_one_to_one;
uint32_t drawcall_count;
bool raster_order_attachment_access;
bool subpass_feedback_loop_ds;
+ bool z_negative_one_to_one;
+
/* Base drawcall cost for sysmem vs gmem autotuner */
uint8_t drawcall_base_cost;
};
void
-tu6_emit_viewport(struct tu_cs *cs, const VkViewport *viewport, uint32_t num_viewport);
+tu6_emit_viewport(struct tu_cs *cs, const VkViewport *viewport, uint32_t num_viewport,
+ bool z_negative_one_to_one);
void
tu6_emit_scissor(struct tu_cs *cs, const VkRect2D *scs, uint32_t scissor_count);