Skip to content

Commit 9880b45

Browse files
ZZKQcomspencer-lunarg
authored andcommitted
layers: Add VK_QCOM_tile_shading render pass VUIDs and tests
1 parent f76342a commit 9880b45

20 files changed

Lines changed: 1883 additions & 36 deletions

layers/chassis/dispatch_object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (c) 2015-2026 LunarG, Inc.
66
* Copyright (c) 2015-2026 Google Inc.
77
* Copyright (c) 2023-2024 RasterGrid Kft.
8+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
89
* Modifications Copyright (C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
910
*
1011
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -119,6 +120,7 @@ struct DeviceExtensionProperties {
119120
VkPhysicalDevicePerformanceCountersByRegionPropertiesARM renderpass_counter_by_region_props;
120121
VkPhysicalDeviceRayTracingInvocationReorderPropertiesEXT ray_tracing_invocation_reorder_props;
121122
VkPhysicalDeviceShaderLongVectorPropertiesEXT shader_long_vector_props;
123+
VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props;
122124
};
123125

124126
// This object holds all static state for the device (device properties, enabled extensions/features, etc.)

layers/chassis/dispatch_object_manual.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2015-2026 Valve Corporation
55
* Copyright (c) 2015-2026 LunarG, Inc.
66
* Copyright (C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
7+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
78
*
89
* Licensed under the Apache License, Version 2.0 (the "License");
910
* you may not use this file except in compliance with the License.
@@ -495,6 +496,8 @@ StatelessDeviceData::StatelessDeviceData(DispatchInstance* instance, VkPhysicalD
495496
&phys_dev_ext_props.renderpass_counter_by_region_props);
496497
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_ext_shader_long_vector,
497498
&phys_dev_ext_props.shader_long_vector_props);
499+
instance->GetPhysicalDeviceExtProperties(physical_device, extensions.vk_qcom_tile_shading,
500+
&phys_dev_ext_props.tile_shading_props);
498501

499502
// None of these "check if supported" features are possible without first having gpdp2 first
500503
if (IsExtEnabled(extensions.vk_khr_get_physical_device_properties2)) {

layers/core_checks/cc_cmd_buffer.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,6 +2067,47 @@ bool CoreChecks::ValidateCmdExecuteCommandsDynamicRenderingInherited(const vvl::
20672067
return skip;
20682068
}
20692069

2070+
bool CoreChecks::PreCallValidateCmdBeginPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
2071+
const VkPerTileBeginInfoQCOM* pPerTileBeginInfo,
2072+
const ErrorObject& error_obj) const {
2073+
bool skip = false;
2074+
const auto cb_state = GetRead<vvl::CommandBuffer>(commandBuffer);
2075+
const auto rp_state = cb_state->active_render_pass;
2076+
2077+
if (rp_state && !rp_state->has_tile_shading_enabled) {
2078+
const LogObjectList objlist(cb_state->Handle(), rp_state->Handle());
2079+
skip |= LogError("VUID-vkCmdBeginPerTileExecutionQCOM-None-10664", objlist, error_obj.location,
2080+
"current render pass doesn't have tile shading enabled.");
2081+
}
2082+
2083+
return skip;
2084+
}
2085+
2086+
bool CoreChecks::PreCallValidateCmdEndPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
2087+
const VkPerTileEndInfoQCOM* pPerTileEndInfo,
2088+
const ErrorObject& error_obj) const {
2089+
bool skip = false;
2090+
const auto cb_state = GetRead<vvl::CommandBuffer>(commandBuffer);
2091+
const auto rp_state = cb_state->active_render_pass;
2092+
2093+
if (rp_state) {
2094+
if (!cb_state->per_tile_execution_model_enabled) {
2095+
const LogObjectList objlist(cb_state->Handle(), rp_state->Handle());
2096+
skip |= LogError("VUID-vkCmdEndPerTileExecutionQCOM-None-10666", objlist, error_obj.location,
2097+
"the command buffer doesn't have the per-tile execution model enabled "
2098+
"in the current render pass.");
2099+
}
2100+
2101+
if (!rp_state->has_tile_shading_enabled) {
2102+
const LogObjectList objlist(cb_state->Handle(), rp_state->Handle());
2103+
skip |= LogError("VUID-vkCmdEndPerTileExecutionQCOM-None-10667", objlist, error_obj.location,
2104+
"current render pass doesn't have tile shading enabled.");
2105+
}
2106+
}
2107+
2108+
return skip;
2109+
}
2110+
20702111
bool CoreChecks::PreCallValidateCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo,
20712112
const ErrorObject& error_obj) const {
20722113
auto cb_state = GetRead<vvl::CommandBuffer>(commandBuffer);

layers/core_checks/cc_render_pass.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) 2015-2026 Valve Corporation
33
* Copyright (c) 2015-2026 LunarG, Inc.
44
* Copyright (C) 2015-2026 Google Inc.
5+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
56
* Modifications Copyright (C) 2020-2022 Advanced Micro Devices, Inc. All rights reserved.
67
*
78
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -654,6 +655,21 @@ bool CoreChecks::ValidateCmdBeginRenderPass(VkCommandBuffer commandBuffer, const
654655
pRenderPassBegin->renderArea, rp_begin_loc);
655656
}
656657

658+
if ((cb_state.begin_info_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) != 0) {
659+
if (const auto* rp_tile_shading_ci =
660+
vku::FindStructInPNextChain<VkRenderPassTileShadingCreateInfoQCOM>(rp_state->create_info.pNext)) {
661+
if ((rp_tile_shading_ci->flags & VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM) != 0) {
662+
const LogObjectList objlist(commandBuffer, pRenderPassBegin->renderPass);
663+
skip |= LogError("VUID-vkCmdBeginRenderPass2-flags-10652", objlist,
664+
rp_begin_loc.dot(Field::renderPass),
665+
"has been created with VkTileShadingRenderPassFlagsQCOM (%s), but commandBuffer "
666+
"is being recorded with VkCommandBufferUsageFlags (%s).",
667+
string_VkTileShadingRenderPassFlagsQCOM(rp_tile_shading_ci->flags).c_str(),
668+
string_VkCommandBufferUsageFlags(cb_state.begin_info_flags).c_str());
669+
}
670+
}
671+
}
672+
657673
return skip;
658674
}
659675

@@ -775,6 +791,12 @@ bool CoreChecks::ValidateCmdEndRenderPass(const vvl::CommandBuffer& cb_state, co
775791
FormatHandle(query.pool).c_str(), query.subpass);
776792
}
777793

794+
if (cb_state.per_tile_execution_model_enabled) {
795+
const LogObjectList objlist(cb_state.Handle(), rp_state.Handle());
796+
skip |= LogError("VUID-vkCmdEndRenderPass-None-10653", objlist, error_obj.location,
797+
"per-tile execution model is still enabled in this command buffer.");
798+
}
799+
778800
return skip;
779801
}
780802

@@ -3923,6 +3945,11 @@ bool CoreChecks::PreCallValidateCmdBeginRendering(VkCommandBuffer commandBuffer,
39233945
commandBuffer, *counters_begin_info, objlist, 1u, layer_or_view_count, pRenderingInfo->renderArea, rendering_info_loc);
39243946
}
39253947

3948+
if (const auto* rp_tile_shading_ci =
3949+
vku::FindStructInPNextChain<VkRenderPassTileShadingCreateInfoQCOM>(pRenderingInfo->pNext)) {
3950+
skip |= ValidateBeginRenderingTileShadingCreateInfo(*cb_state, *pRenderingInfo, *rp_tile_shading_ci, rendering_info_loc);
3951+
}
3952+
39263953
return skip;
39273954
}
39283955

@@ -4540,6 +4567,55 @@ bool CoreChecks::ValidateBeginRenderingDepthAndStencilAttachment(VkCommandBuffer
45404567
return skip;
45414568
}
45424569

4570+
bool CoreChecks::ValidateBeginRenderingTileShadingCreateInfo(const vvl::CommandBuffer& cb_state, const VkRenderingInfo& rendering_info,
4571+
const VkRenderPassTileShadingCreateInfoQCOM& rp_tile_shading_ci,
4572+
const Location& rendering_info_loc) const {
4573+
bool skip = false;
4574+
const bool has_rp_enable_bit = (rp_tile_shading_ci.flags & VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM) != 0;
4575+
const bool has_rp_per_tile_exec_bit = (rp_tile_shading_ci.flags & VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM) != 0;
4576+
const auto* fragment_density_map_info =
4577+
vku::FindStructInPNextChain<VkRenderingFragmentDensityMapAttachmentInfoEXT>(rendering_info.pNext);
4578+
4579+
if (fragment_density_map_info && fragment_density_map_info->imageView != VK_NULL_HANDLE && has_rp_enable_bit) {
4580+
const LogObjectList objlist(cb_state.Handle(), fragment_density_map_info->imageView);
4581+
skip |= LogError("VUID-VkRenderingInfo-imageView-10643", objlist,
4582+
rendering_info_loc.pNext(Struct::VkRenderingFragmentDensityMapAttachmentInfoEXT, Field::imageView),
4583+
"is not VK_NULL_HANDLE, but VkRenderPassTileShadingCreateInfoQCOM::flags (%s) includes "
4584+
"VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM bit.",
4585+
string_VkTileShadingRenderPassFlagsQCOM(rp_tile_shading_ci.flags).c_str());
4586+
}
4587+
4588+
for (uint32_t index = 0; index < rendering_info.colorAttachmentCount; ++index) {
4589+
if (rendering_info.pColorAttachments[index].resolveMode == VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_BIT_ANDROID &&
4590+
has_rp_enable_bit) {
4591+
const LogObjectList objlist(cb_state.Handle(), rendering_info.pColorAttachments[index].resolveImageView);
4592+
skip |= LogError("VUID-VkRenderingInfo-resolveMode-10644", objlist,
4593+
rendering_info_loc.dot(Field::pColorAttachments, index).dot(Field::resolveMode),
4594+
"is VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_BIT_ANDROID, but "
4595+
"VkRenderPassTileShadingCreateInfoQCOM::flags (%s) includes VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM bit",
4596+
string_VkTileShadingRenderPassFlagsQCOM(rp_tile_shading_ci.flags).c_str());
4597+
}
4598+
}
4599+
4600+
if (has_rp_enable_bit && (cb_state.begin_info_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) != 0) {
4601+
skip |= LogError("VUID-vkCmdBeginRendering-flags-10641", cb_state.Handle(),
4602+
rendering_info_loc.pNext(Struct::VkRenderPassTileShadingCreateInfoQCOM, Field::flags),
4603+
"(%s) includes VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM bit, but commandBuffer "
4604+
"is being recorded with VkCommandBufferUsageFlags (%s).",
4605+
string_VkTileShadingRenderPassFlagsQCOM(rp_tile_shading_ci.flags).c_str(),
4606+
string_VkCommandBufferUsageFlags(cb_state.begin_info_flags).c_str());
4607+
}
4608+
4609+
if (has_rp_per_tile_exec_bit) {
4610+
skip |= LogError("VUID-vkCmdBeginRendering-flags-10642", cb_state.Handle(),
4611+
rendering_info_loc.pNext(Struct::VkRenderPassTileShadingCreateInfoQCOM, Field::flags),
4612+
"(%s) includes VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM bit.",
4613+
string_VkTileShadingRenderPassFlagsQCOM(rp_tile_shading_ci.flags).c_str());
4614+
}
4615+
4616+
return skip;
4617+
}
4618+
45434619
// Flags validation error if the associated call is made inside a render pass. The apiName routine should ONLY be called outside a
45444620
// render pass.
45454621
bool CoreChecks::InsideRenderPass(const vvl::CommandBuffer& cb_state, const Location& loc, const char* vuid) const {
@@ -4629,6 +4705,10 @@ bool CoreChecks::ValidateCmdEndRendering(const vvl::CommandBuffer& cb_state, con
46294705
LogError(vuid, objlist, error_obj.location, "query %" PRIu32 " from %s was began in the render pass, but never ended.",
46304706
query.slot, FormatHandle(query.pool).c_str());
46314707
}
4708+
if (cb_state.per_tile_execution_model_enabled) {
4709+
skip |= LogError("VUID-vkCmdEndRendering-None-10645", cb_state.Handle(), error_obj.location,
4710+
"per-tile execution model is still enabled in this command buffer.");
4711+
}
46324712

46334713
return skip;
46344714
}

layers/core_checks/core_validation.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2015-2026 LunarG, Inc.
44
* Copyright (C) 2015-2026 Google Inc.
55
* Copyright (C) 2025 Arm Limited.
6+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
67
* Modifications Copyright (C) 2020-2025 Advanced Micro Devices, Inc. All rights reserved.
78
* Modifications Copyright (C) 2022-2025 RasterGrid Kft.
89
*
@@ -1727,6 +1728,9 @@ class CoreChecks : public vvl::DeviceProxy {
17271728
const Location& rendering_info_loc) const;
17281729
bool ValidateBeginRenderingDepthAndStencilAttachment(VkCommandBuffer commandBuffer, const VkRenderingInfo& rendering_info,
17291730
const Location& rendering_info_loc) const;
1731+
bool ValidateBeginRenderingTileShadingCreateInfo(const vvl::CommandBuffer& cb_state, const VkRenderingInfo& rendering_info,
1732+
const VkRenderPassTileShadingCreateInfoQCOM& rp_tile_shading_ci,
1733+
const Location& rendering_info_loc) const;
17301734
bool PreCallValidateCmdBeginRenderingKHR(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo,
17311735
const ErrorObject& error_obj) const override;
17321736
bool PreCallValidateCmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo,
@@ -2126,6 +2130,13 @@ class CoreChecks : public vvl::DeviceProxy {
21262130
const VkRenderPassFragmentDensityMapOffsetEndInfoEXT& fdm_offset_end_info,
21272131
const Location& end_info_loc) const;
21282132

2133+
bool PreCallValidateCmdBeginPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
2134+
const VkPerTileBeginInfoQCOM* pPerTileBeginInfo,
2135+
const ErrorObject& error_obj) const override;
2136+
bool PreCallValidateCmdEndPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
2137+
const VkPerTileEndInfoQCOM* pPerTileEndInfo,
2138+
const ErrorObject& error_obj) const override;
2139+
21292140
class ViewportScissorInheritanceTracker;
21302141
bool PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
21312142
const VkCommandBuffer* pCommandBuffers, const ErrorObject& error_obj) const override;

layers/state_tracker/cmd_buffer_state.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2015-2026 LunarG, Inc.
44
* Copyright (C) 2015-2026 Google Inc.
55
* Copyright (c) 2025 Arm Limited.
6+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
67
* Modifications Copyright (C) 2020,2025-2026 Advanced Micro Devices, Inc. All rights reserved.
78
* Modifications Copyright (C) 2022 RasterGrid Kft.
89
*
@@ -323,6 +324,7 @@ void CommandBuffer::ResetCBState() {
323324

324325
has_render_pass_instance = false;
325326
resumes_render_pass_instance = false;
327+
per_tile_execution_model_enabled = false;
326328
last_suspend_state = SuspendState::Empty;
327329
first_action_or_sync_command = Func::Empty;
328330
first_rendering_info = {};
@@ -895,6 +897,7 @@ void CommandBuffer::RecordEndRenderPass(const VkSubpassEndInfo* subpass_end_info
895897
SetActiveSubpass(0);
896898
active_framebuffer = VK_NULL_HANDLE;
897899
sample_locations_begin_info = {};
900+
per_tile_execution_model_enabled = false;
898901
}
899902

900903
static void InitDefaultRenderingAttachments(CommandBuffer::RenderingAttachment& attachments, uint32_t count) {
@@ -1061,6 +1064,7 @@ void CommandBuffer::RecordEndRendering(const VkRenderingEndInfoEXT* pRenderingEn
10611064
RecordCommand(loc);
10621065
active_render_pass = nullptr;
10631066
active_color_attachments_index.clear();
1067+
per_tile_execution_model_enabled = false;
10641068
}
10651069

10661070
void CommandBuffer::RecordBeginCustomResolve(const Location& loc) {

layers/state_tracker/cmd_buffer_state.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2015-2026 LunarG, Inc.
44
* Copyright (C) 2015-2026 Google Inc.
55
* Copyright (C) 2025 Arm Limited.
6+
* Copyright (C) 2026 Qualcomm Technologies, Inc.
67
* Modifications Copyright (C) 2020,2025-2026 Advanced Micro Devices, Inc. All rights reserved.
78
* Modifications Copyright (C) 2022 RasterGrid Kft.
89
*
@@ -434,6 +435,9 @@ class CommandBuffer : public RefcountedStateObject, public SubStateManager<Comma
434435
// True if the *first* render pass instance specifies VK_RENDERING_RESUMING_BIT
435436
bool resumes_render_pass_instance;
436437

438+
// Track VK_QCOM_tile_shading (vkCmdBeginPerTileExecutionQCOM and vkCmdEndPerTileExecutionQCOM)
439+
bool per_tile_execution_model_enabled;
440+
437441
// During recording, this tracks the current suspension state of the command buffer.
438442
// When recording ends, this is the suspension state at the end of the command buffer.
439443
// Render pass instances without RESUMING/SUSPENDING do not modify the suspension state.

0 commit comments

Comments
 (0)