@@ -311,17 +311,82 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
311311 }
312312 }
313313 }
314+ if (!ok && _.HasCapability (spv::Capability::TileShadingQCOM)) {
315+ ok =
316+ execution_modes &&
317+ execution_modes->count (spv::ExecutionMode::TileShadingRateQCOM);
318+ }
314319 if (!ok) {
315320 return _.diag (SPV_ERROR_INVALID_DATA, inst)
316321 << _.VkErrorID (6426 )
317322 << " In the Vulkan environment, GLCompute execution model "
318- " entry points require either the LocalSize or "
319- " LocalSizeId execution mode or an object decorated with "
320- " WorkgroupSize must be specified." ;
323+ " entry points require either the "
324+ << (_.HasCapability (spv::Capability::TileShadingQCOM)
325+ ? " TileShadingRateQCOM, "
326+ : " " )
327+ << " LocalSize or LocalSizeId execution mode or an object "
328+ " decorated with WorkgroupSize must be specified." ;
329+ }
330+ }
331+
332+ if (_.HasCapability (spv::Capability::TileShadingQCOM)) {
333+ if (execution_modes) {
334+ if (execution_modes->count (
335+ spv::ExecutionMode::TileShadingRateQCOM) &&
336+ (execution_modes->count (spv::ExecutionMode::LocalSize) ||
337+ execution_modes->count (spv::ExecutionMode::LocalSizeId))) {
338+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
339+ << " If the TileShadingRateQCOM execution mode is used, "
340+ << " LocalSize and LocalSizeId must not be specified." ;
341+ }
342+ if (execution_modes->count (
343+ spv::ExecutionMode::NonCoherentTileAttachmentReadQCOM)) {
344+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
345+ << " The NonCoherentTileAttachmentQCOM execution mode must "
346+ " not be used in any stage other than fragment." ;
347+ }
348+ }
349+ } else {
350+ if (execution_modes &&
351+ execution_modes->count (spv::ExecutionMode::TileShadingRateQCOM)) {
352+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
353+ << " If the TileShadingRateQCOM execution mode is used, the "
354+ " TileShadingQCOM capability must be enabled." ;
321355 }
322356 }
323357 break ;
324358 default :
359+ if (execution_modes &&
360+ execution_modes->count (spv::ExecutionMode::TileShadingRateQCOM)) {
361+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
362+ << " The TileShadingRateQCOM execution mode must not be used "
363+ " in any stage other than compute." ;
364+ }
365+ if (execution_model != spv::ExecutionModel::Fragment) {
366+ if (execution_modes &&
367+ execution_modes->count (
368+ spv::ExecutionMode::NonCoherentTileAttachmentReadQCOM)) {
369+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
370+ << " The NonCoherentTileAttachmentQCOM execution mode must "
371+ " not be used in any stage other than fragment." ;
372+ }
373+ if (_.HasCapability (spv::Capability::TileShadingQCOM)) {
374+ return _.diag (SPV_ERROR_INVALID_CAPABILITY, inst)
375+ << " The TileShadingQCOM capability must not be enabled in "
376+ " any stage other than compute or fragment." ;
377+ }
378+ } else {
379+ if (execution_modes &&
380+ execution_modes->count (
381+ spv::ExecutionMode::NonCoherentTileAttachmentReadQCOM)) {
382+ if (!_.HasCapability (spv::Capability::TileShadingQCOM)) {
383+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
384+ << " If the NonCoherentTileAttachmentReadQCOM execution "
385+ " mode is used, the TileShadingQCOM capability must be "
386+ " enabled." ;
387+ }
388+ }
389+ }
325390 break ;
326391 }
327392 }
@@ -758,6 +823,14 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
758823 << " In the Vulkan environment, the PixelCenterInteger execution "
759824 " mode must not be used." ;
760825 }
826+ if (mode == spv::ExecutionMode::TileShadingRateQCOM) {
827+ const auto rateX = inst->GetOperandAs <int >(2 );
828+ const auto rateY = inst->GetOperandAs <int >(3 );
829+ if ((rateX & (rateX - 1 )) != 0 || (rateY & (rateY - 1 )) != 0 )
830+ return _.diag (SPV_ERROR_INVALID_DATA, inst)
831+ << " The TileShadingRateQCOM execution mode's x and y values "
832+ " must be powers of 2." ;
833+ }
761834 }
762835
763836 return SPV_SUCCESS;
@@ -927,7 +1000,7 @@ spv_result_t ValidateDuplicateExecutionModes(ValidationState_t& _) {
9271000 std::set<PerOperandKey> seen_per_operand;
9281001
9291002 const auto lookupMode = [](spv::ExecutionMode mode) -> std::string {
930- const spvtools::OperandDesc* desc = nullptr ;
1003+ spvtools::OperandDesc* desc = nullptr ;
9311004 if (spvtools::LookupOperand (SPV_OPERAND_TYPE_EXECUTION_MODE,
9321005 static_cast <uint32_t >(mode),
9331006 &desc) == SPV_SUCCESS) {
0 commit comments